mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-25 18:51:41 +03:00
Display the import cycle when one occurs
This commit is contained in:
parent
e2a3c23585
commit
6b409c8547
@ -252,6 +252,7 @@ reason or seemingly inappropriately.
|
|||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
import Ansi
|
||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
import Elm.Docs
|
import Elm.Docs
|
||||||
import Elm.Project
|
import Elm.Project
|
||||||
@ -531,21 +532,32 @@ checkForDuplicateModules project =
|
|||||||
getModulesSortedByImport : Project -> Result (List Review.Error.ReviewError) (List (Graph.NodeContext ModuleName ()))
|
getModulesSortedByImport : Project -> Result (List Review.Error.ReviewError) (List (Graph.NodeContext ModuleName ()))
|
||||||
getModulesSortedByImport project =
|
getModulesSortedByImport project =
|
||||||
let
|
let
|
||||||
sortedModules : Result (Graph.Edge ()) (List (Graph.NodeContext ModuleName ()))
|
moduleGraph : Graph (List String) ()
|
||||||
sortedModules =
|
moduleGraph =
|
||||||
project
|
project
|
||||||
|> Review.Project.Internal.moduleGraph
|
|> Review.Project.Internal.moduleGraph
|
||||||
|
|
||||||
|
sortedModules : Result (Graph.Edge ()) (List (Graph.NodeContext ModuleName ()))
|
||||||
|
sortedModules =
|
||||||
|
moduleGraph
|
||||||
|> Graph.checkAcyclic
|
|> Graph.checkAcyclic
|
||||||
|> Result.map Graph.topologicalSort
|
|> Result.map Graph.topologicalSort
|
||||||
in
|
in
|
||||||
Result.mapError
|
Result.mapError
|
||||||
(\_ ->
|
(\edge ->
|
||||||
|
let
|
||||||
|
cycle : List ModuleName
|
||||||
|
cycle =
|
||||||
|
findCycle moduleGraph edge
|
||||||
|
|> List.reverse
|
||||||
|
in
|
||||||
[ Review.Error.ReviewError
|
[ Review.Error.ReviewError
|
||||||
{ filePath = "GLOBAL ERROR"
|
{ filePath = "GLOBAL ERROR"
|
||||||
, ruleName = "Incorrect project"
|
, ruleName = "Incorrect project"
|
||||||
, message = "Import cycle discovered"
|
, message = "Import cycle discovered"
|
||||||
, details =
|
, details =
|
||||||
[ "I detected an import cycle in your project. This prevents me from working correctly, and results in a error for the Elm compiler anyway. Please resolve it using the compiler's suggestions, then try running `elm-review` again."
|
[ "I detected an import cycle in your project. This prevents me from working correctly, and results in a error for the Elm compiler anyway. Please resolve it using the compiler's suggestions, then try running `elm-review` again."
|
||||||
|
, printCycle cycle
|
||||||
]
|
]
|
||||||
, range = { start = { row = 0, column = 0 }, end = { row = 0, column = 0 } }
|
, range = { start = { row = 0, column = 0 }, end = { row = 0, column = 0 } }
|
||||||
, fixes = Nothing
|
, fixes = Nothing
|
||||||
@ -556,6 +568,52 @@ getModulesSortedByImport project =
|
|||||||
sortedModules
|
sortedModules
|
||||||
|
|
||||||
|
|
||||||
|
findCycle : Graph n e -> Graph.Edge e -> List n
|
||||||
|
findCycle graph edge =
|
||||||
|
let
|
||||||
|
startingNode : Graph.NodeId
|
||||||
|
startingNode =
|
||||||
|
edge.from
|
||||||
|
|
||||||
|
targetNode : Graph.NodeId
|
||||||
|
targetNode =
|
||||||
|
edge.to
|
||||||
|
|
||||||
|
reachedTarget : List { a | node : { b | id : Graph.NodeId } } -> Bool
|
||||||
|
reachedTarget path =
|
||||||
|
Maybe.map (.node >> .id) (List.head path) == Just targetNode
|
||||||
|
|
||||||
|
visitorDiscoverCycle : List { a | node : { id : Graph.NodeId, label : n } } -> b -> List n -> List n
|
||||||
|
visitorDiscoverCycle path _ acc =
|
||||||
|
if List.isEmpty acc then
|
||||||
|
-- we haven't found the cycle yet
|
||||||
|
if reachedTarget path then
|
||||||
|
List.map (.node >> .label) path
|
||||||
|
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
|
||||||
|
else
|
||||||
|
-- we already found the cycle
|
||||||
|
acc
|
||||||
|
in
|
||||||
|
Graph.guidedBfs Graph.alongIncomingEdges visitorDiscoverCycle [ startingNode ] [] graph
|
||||||
|
|> Tuple.first
|
||||||
|
|
||||||
|
|
||||||
|
printCycle : List ModuleName -> String
|
||||||
|
printCycle moduleNames =
|
||||||
|
moduleNames
|
||||||
|
|> List.map (String.join "." >> Ansi.yellow)
|
||||||
|
|> String.join "\n │ ↓\n │ "
|
||||||
|
|> wrapInCycle
|
||||||
|
|
||||||
|
|
||||||
|
wrapInCycle : String -> String
|
||||||
|
wrapInCycle string =
|
||||||
|
" ┌─────┐\n │ " ++ string ++ "\n └─────┘"
|
||||||
|
|
||||||
|
|
||||||
extractResultValue : Result a a -> a
|
extractResultValue : Result a a -> a
|
||||||
extractResultValue result =
|
extractResultValue result =
|
||||||
case result of
|
case result of
|
||||||
|
Loading…
Reference in New Issue
Block a user