mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-23 23:05:35 +03:00
Add data collection that we keep at every run
This commit is contained in:
parent
ca373f5a56
commit
58ad1b1a0c
@ -17,7 +17,7 @@ module Review.Rule exposing
|
||||
, ignoreErrorsForDirectories, ignoreErrorsForFiles
|
||||
, review, ruleName
|
||||
, Required, Forbidden
|
||||
, withModuleNameLookupTable
|
||||
, reviewWithPrecollectionOfData, withModuleNameLookupTable
|
||||
)
|
||||
|
||||
{-| This module contains functions that are used for writing rules.
|
||||
@ -244,7 +244,7 @@ reason or seemingly inappropriately.
|
||||
|
||||
# Running rules
|
||||
|
||||
@docs review, ruleName
|
||||
@docs review, reviewWithPrecollectionOfDat, ruleName
|
||||
|
||||
|
||||
# Internals
|
||||
@ -450,6 +450,134 @@ review rules project =
|
||||
( List.map parsingError modulesThatFailedToParse, rules )
|
||||
|
||||
|
||||
{-| Review a project and gives back the errors raised by the given rules.
|
||||
|
||||
Note that you won't need to use this function when writing a rule. You should
|
||||
only need it if you try to make `elm-review` run in a new environment.
|
||||
|
||||
import Review.Project as Project exposing (Project, ProjectModule)
|
||||
import Review.Rule as Rule exposing (Rule)
|
||||
|
||||
config : List Rule
|
||||
config =
|
||||
[ Some.Rule.rule
|
||||
, Some.Other.Rule.rule
|
||||
]
|
||||
|
||||
project : Project
|
||||
project =
|
||||
Project.new
|
||||
|> Project.addModule { path = "src/A.elm", source = "module A exposing (a)\na = 1" }
|
||||
|> Project.addModule { path = "src/B.elm", source = "module B exposing (b)\nb = 1" }
|
||||
|
||||
doReview =
|
||||
let
|
||||
( errors, rulesWithCachedValues ) =
|
||||
Rule.reviewWithPrecollectionOfData rules Nothing project
|
||||
in
|
||||
doSomethingWithTheseValues
|
||||
|
||||
The resulting `List Rule` is the same list of rules given as input, but with an
|
||||
updated internal cache to make it faster to re-run the rules on the same project.
|
||||
If you plan on re-reviewing with the same rules and project, for instance to
|
||||
review the project after a file has changed, you may want to store the rules in
|
||||
your `Model`.
|
||||
|
||||
The rules are functions, so doing so will make your model unable to be
|
||||
exported/imported with `elm/browser`'s debugger, and may cause a crash if you try
|
||||
to compare them or the model that holds them.
|
||||
|
||||
-}
|
||||
reviewWithPrecollectionOfData : List Rule -> Maybe ProjectData -> Project -> { errors : List ReviewError, rules : List Rule, projectData : Maybe ProjectData }
|
||||
reviewWithPrecollectionOfData rules maybeProjectData project =
|
||||
case Review.Project.modulesThatFailedToParse project of
|
||||
[] ->
|
||||
case Review.Project.modules project |> duplicateModuleNames Dict.empty of
|
||||
Just duplicate ->
|
||||
{ errors = [ duplicateModulesGlobalError duplicate ]
|
||||
, rules = rules
|
||||
, projectData = Nothing
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
let
|
||||
sortedModules : Result (Graph.Edge ()) (List (Graph.NodeContext ModuleName ()))
|
||||
sortedModules =
|
||||
project
|
||||
|> Review.Project.Internal.moduleGraph
|
||||
|> Graph.checkAcyclic
|
||||
|> Result.map Graph.topologicalSort
|
||||
in
|
||||
case sortedModules of
|
||||
Err _ ->
|
||||
{ errors =
|
||||
[ Review.Error.ReviewError
|
||||
{ filePath = "GLOBAL ERROR"
|
||||
, ruleName = "Incorrect project"
|
||||
, message = "Import cycle discovered"
|
||||
, 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."
|
||||
]
|
||||
, range = { start = { row = 0, column = 0 }, end = { row = 0, column = 0 } }
|
||||
, fixes = Nothing
|
||||
, target = Review.Error.Global
|
||||
}
|
||||
]
|
||||
, rules = rules
|
||||
, projectData = Nothing
|
||||
}
|
||||
|
||||
Ok nodeContexts ->
|
||||
let
|
||||
( scopeErrors, newScopeRule, extract ) =
|
||||
-- TODO Later use newScopeRule for to avoid recomputing it all over everytime
|
||||
runProjectVisitor
|
||||
"DUMMY"
|
||||
scopeRule
|
||||
Nothing
|
||||
Exceptions.init
|
||||
project
|
||||
nodeContexts
|
||||
|
||||
moduleNameLookupTables : Maybe (Dict ModuleName ModuleNameLookupTable)
|
||||
moduleNameLookupTables =
|
||||
Maybe.map (\(Extract moduleNameLookupTables_) -> moduleNameLookupTables_) extract
|
||||
|
||||
projectWithLookupTable : Project
|
||||
projectWithLookupTable =
|
||||
let
|
||||
(Project p) =
|
||||
project
|
||||
in
|
||||
Project { p | moduleNameLookupTables = moduleNameLookupTables }
|
||||
in
|
||||
if not (List.isEmpty scopeErrors) then
|
||||
{ errors = List.map errorToReviewError scopeErrors
|
||||
, rules = rules
|
||||
, projectData = Just ProjectData
|
||||
}
|
||||
|
||||
else
|
||||
let
|
||||
( errors, newRules ) =
|
||||
runRules rules projectWithLookupTable nodeContexts
|
||||
in
|
||||
{ errors = List.map errorToReviewError errors
|
||||
, rules = newRules
|
||||
, projectData = Just ProjectData
|
||||
}
|
||||
|
||||
modulesThatFailedToParse ->
|
||||
{ errors = List.map parsingError modulesThatFailedToParse
|
||||
, rules = rules
|
||||
, projectData = Nothing
|
||||
}
|
||||
|
||||
|
||||
type ProjectData
|
||||
= ProjectData
|
||||
|
||||
|
||||
duplicateModulesGlobalError : { moduleName : ModuleName, paths : List String } -> ReviewError
|
||||
duplicateModulesGlobalError duplicate =
|
||||
let
|
||||
|
@ -367,8 +367,8 @@ runOnModulesWithProjectData project rule sources =
|
||||
errors : List ReviewError
|
||||
errors =
|
||||
projectWithModules
|
||||
|> Rule.review [ rule ]
|
||||
|> Tuple.first
|
||||
|> Rule.reviewWithPrecollectionOfData [ rule ] Nothing
|
||||
|> .errors
|
||||
in
|
||||
case ListExtra.find (\err_ -> Rule.errorFilePath err_ == "GLOBAL ERROR") errors of
|
||||
Just globalError ->
|
||||
|
Loading…
Reference in New Issue
Block a user