Use extraFiles2 everywhere

This commit is contained in:
Jeroen Engels 2024-04-17 00:52:29 +02:00
parent 757ebb6b5e
commit f505932b0c
9 changed files with 127 additions and 89 deletions

View File

@ -313,22 +313,20 @@ readme (Internal.Project project) =
{-| Add extra files to the project. These are files that `elm-review` doesn't load by default
but can be visited by rules if they're explicily requested.
-}
addExtraFiles : List { path : String, content : String } -> Project -> Project
addExtraFiles files (Internal.Project project) =
-- TODO Make this function take a Dict String String instead
addExtraFiles : Dict String String -> Project -> Project
addExtraFiles newFiles (Internal.Project project) =
let
extraFiles_ : List ( { path : String, content : String }, ContentHash )
extraFiles_ =
List.foldl (\file acc -> ( file, ContentHash.hash file.content ) :: acc) project.extraFiles files
extraFilesContentHashes : Dict String ContentHash
extraFilesContentHashes =
List.foldl (\file acc -> Dict.insert file.path (ContentHash.hash file.content) acc) project.extraFilesContentHashes files
Dict.foldl
(\path content acc -> Dict.insert path (ContentHash.hash content) acc)
project.extraFilesContentHashes
newFiles
in
Internal.Project
{ project
| extraFiles = extraFiles_
, extraFiles2 = List.foldl (\file acc -> Dict.insert file.path file.content acc) project.extraFiles2 files
| extraFiles = [] -- TODO Remove
, extraFiles2 = Dict.union newFiles project.extraFiles2
, extraFilesContentHashes = extraFilesContentHashes
, extraFilesContentHash = ContentHash.combine extraFilesContentHashes
}

View File

@ -1,5 +1,6 @@
module Review.Project.Valid exposing
( ValidProject
( ExtraFileData
, ValidProject
, addElmJson
, addExtraFile
, addParsedModule
@ -12,6 +13,7 @@ module Review.Project.Valid exposing
, elmJsonHash
, extraFiles
, extraFilesHash
, extraFilesWithoutKeys
, getModuleByPath
, moduleGraph
, moduleZipper
@ -323,9 +325,22 @@ readmeHash (ValidProject project) =
Maybe.map Tuple.second project.readme
extraFiles : ValidProject -> List { path : String, content : String }
extraFiles (ValidProject project) =
List.map Tuple.first project.extraFiles
type alias ExtraFileData fileKey =
{ withFileKeys : Dict String { fileKey : fileKey, content : String }
, withoutFileKeys : Dict String String
}
extraFiles : ({ path : String, content : String } -> fileKey) -> ValidProject -> ExtraFileData fileKey
extraFiles toFileKey (ValidProject project) =
{ withFileKeys = Dict.map (\path content -> { fileKey = toFileKey { path = path, content = content }, content = content }) project.extraFiles2
, withoutFileKeys = project.extraFiles2
}
extraFilesWithoutKeys : ValidProject -> Dict String String
extraFilesWithoutKeys (ValidProject project) =
project.extraFiles2
extraFilesHash : ValidProject -> List ContentHash

View File

@ -409,7 +409,7 @@ type alias ModuleRuleSchemaData moduleContext =
, elmJsonVisitor : Maybe (Maybe Elm.Project.Project -> moduleContext -> moduleContext)
, extraFileRequest : ExtraFileRequest
, readmeVisitor : Maybe (Maybe String -> moduleContext -> moduleContext)
, extraFilesVisitor : Maybe (List { path : String, content : String } -> moduleContext -> moduleContext)
, extraFilesVisitor : Maybe (ExtraFileData -> moduleContext -> moduleContext)
, dependenciesVisitor : Maybe (Dict String Review.Project.Dependency.Dependency -> moduleContext -> moduleContext)
, directDependenciesVisitor : Maybe (Dict String Review.Project.Dependency.Dependency -> moduleContext -> moduleContext)
}
@ -1189,11 +1189,13 @@ compactProjectDataVisitors getData maybeVisitor =
Just (\rawData moduleContext -> ( [], visitor (getData rawData) moduleContext ))
compactExtraFilesVisitor : Maybe (List { path : String, content : String } -> moduleContext -> moduleContext) -> Maybe (List { fileKey : ExtraFileKey, path : String, content : String } -> moduleContext -> ( List nothing, moduleContext ))
compactExtraFilesVisitor :
Maybe (ExtraFileData -> moduleContext -> moduleContext)
-> Maybe (ExtraFileData -> moduleContext -> ( List nothing, moduleContext ))
compactExtraFilesVisitor maybeExtraFilesVisitor =
case maybeExtraFilesVisitor of
Just extraFilesVisitor ->
Just (\files moduleContext -> ( [], extraFilesVisitor (List.map (\{ path, content } -> { path = path, content = content }) files) moduleContext ))
Just (\files moduleContext -> ( [], extraFilesVisitor files moduleContext ))
Nothing ->
Nothing
@ -1223,7 +1225,7 @@ type alias ProjectRuleSchemaData projectContext moduleContext =
, initialProjectContext : projectContext
, elmJsonVisitor : Maybe (Maybe { elmJsonKey : ElmJsonKey, project : Elm.Project.Project } -> projectContext -> ( List (Error {}), projectContext ))
, readmeVisitor : Maybe (Maybe { readmeKey : ReadmeKey, content : String } -> projectContext -> ( List (Error {}), projectContext ))
, extraFilesVisitor : Maybe (List { fileKey : ExtraFileKey, path : String, content : String } -> projectContext -> ( List (Error {}), projectContext ))
, extraFilesVisitor : Maybe (ExtraFileData -> projectContext -> ( List (Error {}), projectContext ))
, extraFileRequest : ExtraFileRequest
, directDependenciesVisitor : Maybe (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
, dependenciesVisitor : Maybe (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
@ -2017,7 +2019,7 @@ and reports errors when the classes given as argument are unknown.
-}
withExtraFilesProjectVisitor :
(List { fileKey : ExtraFileKey, path : String, content : String } -> projectContext -> ( List (Error { useErrorForModule : () }), projectContext ))
(Dict String { fileKey : ExtraFileKey, content : String } -> projectContext -> ( List (Error { useErrorForModule : () }), projectContext ))
-> List FilePattern
-> ProjectRuleSchema schemaState projectContext moduleContext
-> ProjectRuleSchema { schemaState | hasAtLeastOneVisitor : () } projectContext moduleContext
@ -2025,9 +2027,9 @@ withExtraFilesProjectVisitor baseVisitor filePatterns (ProjectRuleSchema schema)
case FilePattern.compact filePatterns of
Ok filePatternSummary ->
let
visitor : List { fileKey : ExtraFileKey, path : String, content : String } -> projectContext -> ( List (Error {}), projectContext )
visitor : ExtraFileData -> projectContext -> ( List (Error {}), projectContext )
visitor files context =
baseVisitor (List.filter (\file -> FilePattern.match filePatternSummary file.path) files) context
baseVisitor (Dict.filter (\path _ -> FilePattern.match filePatternSummary path) files.withFileKeys) context
|> Tuple.mapFirst removeErrorPhantomTypes
in
ProjectRuleSchema
@ -2571,7 +2573,7 @@ withElmJsonModuleVisitor visitor (ModuleRuleSchema schema) =
{-| REPLACEME
-}
withExtraFilesModuleVisitor :
(List { path : String, content : String } -> moduleContext -> moduleContext)
(Dict String String -> moduleContext -> moduleContext)
-> List FilePattern
-> ModuleRuleSchema { schemaState | canCollectProjectData : () } moduleContext
-> ModuleRuleSchema { schemaState | canCollectProjectData : () } moduleContext
@ -2579,9 +2581,9 @@ withExtraFilesModuleVisitor baseVisitor filePatterns (ModuleRuleSchema schema) =
case FilePattern.compact filePatterns of
Ok filePatternSummary ->
let
visitor : List { path : String, content : String } -> moduleContext -> moduleContext
visitor : ExtraFileData -> moduleContext -> moduleContext
visitor files context =
baseVisitor (List.filter (\file -> FilePattern.match filePatternSummary file.path) files) context
baseVisitor (Dict.filter (\path _ -> FilePattern.match filePatternSummary path) files.withoutFileKeys) context
in
ModuleRuleSchema
{ schema
@ -4025,6 +4027,10 @@ type ExtraFileKey
}
type alias ExtraFileData =
ValidProject.ExtraFileData ExtraFileKey
{-| REPLACEME
-}
errorForExtraFile : ExtraFileKey -> { message : String, details : List String } -> Range -> Error scope
@ -4726,9 +4732,9 @@ computeStepsForProject reviewOptions { project, ruleProjectVisitors, fixedErrors
ExtraFiles ->
let
extraFiles : List { path : String, content : String }
extraFiles : ExtraFileData
extraFiles =
ValidProject.extraFiles project
ValidProject.extraFiles ExtraFileKey project
in
computeStepsForProject
reviewOptions
@ -4901,7 +4907,7 @@ computeExtraFiles :
ReviewOptionsData
-> ValidProject
-> FixedErrors
-> List { path : String, content : String }
-> ExtraFileData
-> List RuleProjectVisitor
-> List RuleProjectVisitor
-> { project : ValidProject, ruleProjectVisitors : List RuleProjectVisitor, step : Step, fixedErrors : FixedErrors }
@ -4919,7 +4925,7 @@ computeExtraFiles reviewOptions project fixedErrors extraFiles remainingRules ac
Just visitor ->
let
( errors, RuleProjectVisitor updatedRule ) =
visitor project (List.map (\file -> { fileKey = ExtraFileKey file, path = file.path, content = file.content }) extraFiles)
visitor project extraFiles
in
case standardFindFix reviewOptions project fixedErrors updatedRule.setErrorsForExtraFiles errors of
FoundFixStandard { newProject, newRule, newFixedErrors, step } ->
@ -5688,12 +5694,12 @@ findFixHelp project fixablePredicate errors accErrors maybeModuleZipper =
}
Review.Error.ExtraFile ->
case ListExtra.find (\file -> file.path == headError.filePath) (ValidProject.extraFiles project) of
case Dict.get headError.filePath (ValidProject.extraFilesWithoutKeys project) of
Nothing ->
findFixHelp project fixablePredicate restOfErrors (err :: accErrors) maybeModuleZipper
Just file ->
case InternalFix.fixExtraFile fixes file.content of
Just content ->
case InternalFix.fixExtraFile fixes content of
Err fixProblem ->
findFixHelp project fixablePredicate restOfErrors (Error (Review.Error.markFixesAsProblem fixProblem headError) :: accErrors) maybeModuleZipper
@ -5904,7 +5910,7 @@ The hidden state is `{ cache : ProjectRuleCache projectContext, ruleData : Chang
type alias RuleProjectVisitorOperations =
{ elmJsonVisitor : Maybe (ValidProject -> Maybe { elmJsonKey : ElmJsonKey, project : Elm.Project.Project } -> ( List (Error {}), RuleProjectVisitor ))
, readmeVisitor : Maybe (ValidProject -> Maybe { readmeKey : ReadmeKey, content : String } -> ( List (Error {}), RuleProjectVisitor ))
, extraFilesVisitor : Maybe (ValidProject -> List { fileKey : ExtraFileKey, path : String, content : String } -> ( List (Error {}), RuleProjectVisitor ))
, extraFilesVisitor : Maybe (ValidProject -> ExtraFileData -> ( List (Error {}), RuleProjectVisitor ))
, dependenciesVisitor : Maybe (ValidProject -> { all : Dict String Review.Project.Dependency.Dependency, direct : Dict String Review.Project.Dependency.Dependency } -> ( List (Error {}), RuleProjectVisitor ))
, createModuleVisitorFromProjectVisitor : Maybe (ValidProject -> String -> ContentHash -> Graph.Adjacency () -> Maybe (AvailableData -> RuleModuleVisitor))
, finalProjectEvaluation : Maybe (() -> ( List (Error {}), RuleProjectVisitor ))
@ -6039,7 +6045,7 @@ createExtraFilesVisitor :
->
Maybe
(ValidProject
-> List { fileKey : ExtraFileKey, content : String, path : String }
-> ExtraFileData
-> ( List (Error {}), RuleProjectVisitor )
)
createExtraFilesVisitor schema ({ cache } as hidden) raise raiseCache =

View File

@ -182,11 +182,11 @@ cssFiles globs =
}
cssFilesVisitor : List { fileKey : Rule.ExtraFileKey, path : String, content : String } -> ProjectContext -> ( List (Rule.Error scope), ProjectContext )
cssFilesVisitor : Dict String { fileKey : Rule.ExtraFileKey, content : String } -> ProjectContext -> ( List (Rule.Error scope), ProjectContext )
cssFilesVisitor files context =
let
( errors, knownClasses ) =
List.foldl parseCssFile ( [], context.knownClasses ) files
Dict.foldl parseCssFile ( [], context.knownClasses ) files
in
( errors, { knownClasses = knownClasses } )
@ -544,8 +544,8 @@ unknownClassesHelp knownClasses row column classes errors =
---
parseCssFile : { fileKey : Rule.ExtraFileKey, path : String, content : String } -> ( List (Rule.Error externalFile), Set String ) -> ( List (Rule.Error externalFile), Set String )
parseCssFile file ( errors, knownClasses ) =
parseCssFile : String -> { fileKey : Rule.ExtraFileKey, content : String } -> ( List (Rule.Error externalFile), Set String ) -> ( List (Rule.Error externalFile), Set String )
parseCssFile path file ( errors, knownClasses ) =
case Parser.run cssParser file.content of
Ok cssClasses ->
( errors, Set.union cssClasses knownClasses )

View File

@ -2,6 +2,7 @@ module Css.NoUnknownCssClassesTest exposing (all)
import Css.ClassFunction as ClassFunction exposing (CssArgument, fromLiteral)
import Css.NoUnknownCssClasses exposing (addKnownClasses, cssFiles, rule, withCssUsingFunctions)
import Dict
import Elm.Syntax.Expression exposing (Expression)
import Elm.Syntax.Node exposing (Node)
import Review.FilePattern as FilePattern exposing (FilePattern)
@ -376,8 +377,9 @@ classFromAttrFunction { firstArgument } =
projectWithCssClasses : Project
projectWithCssClasses =
Project.addExtraFiles
[ { path = "some-file.css"
, content = """-- First line
(Dict.fromList
[ ( "some-file.css"
, """-- First line
.known {
color: blue;
}
@ -388,16 +390,18 @@ projectWithCssClasses =
color: green;
}
"""
}
]
)
]
)
Review.Test.Dependencies.projectWithElmCore
projectWithUnparsableCssClasses : Project
projectWithUnparsableCssClasses =
Project.addExtraFiles
[ { path = "some-file.css"
, content = """-- First line
(Dict.fromList
[ ( "some-file.css"
, """-- First line
.known {
color: blue;
}
@ -405,6 +409,7 @@ projectWithUnparsableCssClasses =
color: red;
-- missing closing curly brace
"""
}
]
)
]
)
Review.Test.Dependencies.projectWithElmCore

View File

@ -42,6 +42,7 @@ elm-review --template jfmengels/elm-review/example --rules Docs.NoMissingChangel
-}
import Dict exposing (Dict)
import Elm.Project exposing (Project)
import Elm.Syntax.Range exposing (Range)
import Elm.Version
@ -56,7 +57,7 @@ rule : Configuration -> Rule
rule (Configuration { changelogPath }) =
Rule.newProjectRuleSchema "Docs.NoMissingChangelogEntry" initialProjectContext
|> Rule.withElmJsonProjectVisitor elmJsonVisitor
|> Rule.withExtraFilesProjectVisitor (extraFilesVisitor changelogPath) [ FilePattern.include (Maybe.withDefault defaultPath changelogPath) ]
|> Rule.withExtraFilesProjectVisitor (extraFilesVisitor changelogPath) [ FilePattern.include (getChangelogPath changelogPath) ]
|> Rule.providesFixesForProjectRule
|> Rule.fromProjectRuleSchema
@ -70,9 +71,9 @@ defaults =
Configuration { changelogPath = Nothing }
defaultPath : String
defaultPath =
"CHANGELOG.md"
getChangelogPath : Maybe String -> String
getChangelogPath changelogPath =
Maybe.withDefault "CHANGELOG.md" changelogPath
withPathToChangelog : String -> Configuration -> Configuration
@ -112,9 +113,14 @@ elmJsonVisitor maybeElmJsonData context =
( [], context )
extraFilesVisitor : Maybe String -> List { fileKey : Rule.ExtraFileKey, path : String, content : String } -> ProjectContext -> ( List (Rule.Error { useErrorForModule : () }), ProjectContext )
extraFilesVisitor changelogPath files context =
case List.head files of
extraFilesVisitor : Maybe String -> Dict String { fileKey : Rule.ExtraFileKey, content : String } -> ProjectContext -> ( List (Rule.Error { useErrorForModule : () }), ProjectContext )
extraFilesVisitor maybeChangelogPath files context =
let
changelogPath : String
changelogPath =
getChangelogPath maybeChangelogPath
in
case Dict.get changelogPath files of
Just { fileKey, content } ->
case context.elmJsonVersion of
Nothing ->
@ -142,7 +148,7 @@ extraFilesVisitor changelogPath files context =
( [], context )
Just _ ->
case changelogPath of
case maybeChangelogPath of
Nothing ->
( [ Rule.globalError
{ message = "Could not find the CHANGELOG.md file"

View File

@ -1,5 +1,6 @@
module Docs.NoMissingChangelogEntryTest exposing (all)
import Dict
import Docs.NoMissingChangelogEntry exposing (defaults, rule, withPathToChangelog)
import Elm.Project
import Json.Decode as Decode
@ -17,8 +18,9 @@ all =
project : Project
project =
Project.addExtraFiles
[ { path = "CHANGELOG.md"
, content = """
(Dict.fromList
[ ( "CHANGELOG.md"
, """
# Changelog
## [Unreleased]
Stuff
@ -27,8 +29,9 @@ More stuff happened
## 2.12.0
Stuff happened
"""
}
]
)
]
)
(package "2.13.0")
in
"module A exposing (..)\na = 1"
@ -40,8 +43,9 @@ Stuff happened
project : Project
project =
Project.addExtraFiles
[ { path = "CHANGELOG.md"
, content = """# Changelog
(Dict.fromList
[ ( "CHANGELOG.md"
, """# Changelog
## [Unreleased]
Stuff
## 1.13.0
@ -49,8 +53,9 @@ More stuff happened
## 1.12.0
Stuff happened
"""
}
]
)
]
)
(package "2.13.0")
in
"""module A exposing (..)
@ -84,15 +89,17 @@ Stuff happened
project : Project
project =
Project.addExtraFiles
[ { path = "CHANGELOG.md"
, content = """# Changelog
(Dict.fromList
[ ( "CHANGELOG.md"
, """# Changelog
## 1.13.0
More stuff happened
## 1.12.0
Stuff happened
"""
}
]
)
]
)
(package "2.13.0")
in
"""module A exposing (..)
@ -149,10 +156,12 @@ a = 1
project : Project
project =
Project.addExtraFiles
[ { path = "CHANGELOG.md"
, content = "# something"
}
]
(Dict.fromList
[ ( "CHANGELOG.md"
, "# something"
)
]
)
application
in
"""module A exposing (..)
@ -177,10 +186,7 @@ a = 1
project : Project
project =
Project.addExtraFiles
[ { path = "CHANGELOG.md"
, content = ""
}
]
(Dict.fromList [ ( "CHANGELOG.md", "" ) ])
(package "1.0.0")
in
"""module A exposing (..)

View File

@ -1,5 +1,6 @@
module Review.Rule.VisitorsOrderTest exposing (all)
import Dict
import Elm.Syntax.Declaration exposing (Declaration)
import Elm.Syntax.Expression as Expression exposing (Expression)
import Elm.Syntax.Import exposing (Import)
@ -33,8 +34,8 @@ all =
|> Rule.withElmJsonModuleVisitor (\_ context -> context ++ "\n1.2 - withElmJsonModuleVisitor")
|> Rule.withReadmeModuleVisitor (\_ context -> context ++ "\n2.1 - withReadmeModuleVisitor")
|> Rule.withReadmeModuleVisitor (\_ context -> context ++ "\n2.2 - withReadmeModuleVisitor")
|> Rule.withExtraFilesModuleVisitor (\files context -> context ++ "\n3.1 - withExtraFilesModuleVisitor " ++ (List.map .path files |> String.join ", ")) [ FilePattern.include "first.txt" ]
|> Rule.withExtraFilesModuleVisitor (\files context -> context ++ "\n3.2 - withExtraFilesModuleVisitor " ++ (List.map .path files |> String.join ", ")) [ FilePattern.include "last.txt" ]
|> Rule.withExtraFilesModuleVisitor (\files context -> context ++ "\n3.1 - withExtraFilesModuleVisitor " ++ (Dict.keys files |> String.join ", ")) [ FilePattern.include "first.txt" ]
|> Rule.withExtraFilesModuleVisitor (\files context -> context ++ "\n3.2 - withExtraFilesModuleVisitor " ++ (Dict.keys files |> String.join ", ")) [ FilePattern.include "last.txt" ]
|> Rule.withDirectDependenciesModuleVisitor (\_ context -> context ++ "\n4.1 - withDirectDependenciesModuleVisitor")
|> Rule.withDirectDependenciesModuleVisitor (\_ context -> context ++ "\n4.2 - withDirectDependenciesModuleVisitor")
|> Rule.withDependenciesModuleVisitor (\_ context -> context ++ "\n4.3 - withDependenciesModuleVisitor")
@ -71,7 +72,7 @@ all =
project : Project
project =
Project.new
|> Project.addExtraFiles [ { path = "first.txt", content = "" }, { path = "last.txt", content = "" } ]
|> Project.addExtraFiles (Dict.fromList [ ( "first.txt", "" ), ( "last.txt", "" ) ])
in
"""module A exposing (..)
import B

View File

@ -1,5 +1,6 @@
module Review.Rule.WithExtraFilesVisitorTest exposing (all)
import Dict exposing (Dict)
import Review.FilePattern as FilePattern exposing (FilePattern)
import Review.Project as Project exposing (Project)
import Review.Rule as Rule exposing (Error, Rule)
@ -16,7 +17,7 @@ all =
project : Project
project =
createProject
[ { path = "foo/some-file.css", content = "#thing { color: red; }" }
[ ( "foo/some-file.css", "#thing { color: red; }" )
]
rule : Rule
@ -38,9 +39,9 @@ a = 1
project : Project
project =
createProject
[ { path = "foo/some-file.css", content = "#thing { color: red; }" }
, { path = "foo/some-other-file.css", content = "#thing { color: red; }" }
, { path = "bar/some-file.css", content = "#thing { color: red; }" }
[ ( "foo/some-file.css", "#thing { color: red; }" )
, ( "foo/some-other-file.css", "#thing { color: red; }" )
, ( "bar/some-file.css", "#thing { color: red; }" )
]
rule : Rule
@ -62,9 +63,9 @@ a = 1
project : Project
project =
createProject
[ { path = "a.txt", content = "A" }
, { path = "b.txt", content = "B" }
, { path = "c.txt", content = "C" }
[ ( "a.txt", "A" )
, ( "b.txt", "B" )
, ( "c.txt", "C" )
]
rule : Rule
@ -117,14 +118,14 @@ createRule modifier =
|> Rule.fromModuleRuleSchema
extraFilesModuleVisitor : List { path : String, content : String } -> Context -> Context
extraFilesModuleVisitor : Dict String String -> Context -> Context
extraFilesModuleVisitor files context =
List.map .path files ++ context
Dict.keys files ++ context
reportsFileNames : String -> List { path : String, content : String } -> Context -> Context
reportsFileNames : String -> Dict String String -> Context -> Context
reportsFileNames prefix files context =
List.map (\file -> "Visitor " ++ prefix ++ " saw file " ++ file.path) files ++ context
List.map (\path -> "Visitor " ++ prefix ++ " saw file " ++ path) (Dict.keys files) ++ context
finalEvaluation : Context -> List (Error scope)
@ -136,6 +137,6 @@ finalEvaluation context =
]
createProject : List { path : String, content : String } -> Project
createProject : List ( String, String ) -> Project
createProject extraFiles =
Project.addExtraFiles extraFiles Project.new
Project.addExtraFiles (Dict.fromList extraFiles) Project.new