Skip to content

Commit

Permalink
Merge pull request #196 from dawedawe/support_include_files
Browse files Browse the repository at this point in the history
Add a --include-files flag
  • Loading branch information
dawedawe authored Jan 5, 2024
2 parents 334ca3d + 92f49a2 commit 8e8fd19
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 42 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]

### Changed
* [Changed --exclude-analyzer to --exclude-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK/pull/196) (thanks @dawedawe!)
* [Changed --ignore-files to --exclude-files](https://github.com/ionide/FSharp.Analyzers.SDK/pull/196) (thanks @dawedawe!)

### Added
* [Add missing TAST walkers](https://github.com/ionide/FSharp.Analyzers.SDK/pull/185) (thanks @dawedawe!)
* [Add support for --include-analyzers to ignore all others](https://github.com/ionide/FSharp.Analyzers.SDK/pull/194) (thanks @dawedawe!)
* [Add support for --include-files to ignore all others](https://github.com/ionide/FSharp.Analyzers.SDK/pull/196) (thanks @dawedawe!)

## [0.22.0] - 2023-12-19

Expand Down
2 changes: 1 addition & 1 deletion docs/content/Getting Started Using.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ You can extend the value of `$(FSharpAnalyzersOtherFlags)` by setting it again i
<FSharpAnalyzersOtherFlags>--analyzers-path &quot;$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs&quot;</FSharpAnalyzersOtherFlags>
<FSharpAnalyzersOtherFlags>$(FSharpAnalyzersOtherFlags) --analyzers-path &quot;$(PkgIonide_Analyzers)/analyzers/dotnet/fs&quot;</FSharpAnalyzersOtherFlags>
<FSharpAnalyzersOtherFlags>$(FSharpAnalyzersOtherFlags) --configuration $(Configuration)</FSharpAnalyzersOtherFlags>
<FSharpAnalyzersOtherFlags>$(FSharpAnalyzersOtherFlags) --exclude-analyzer PartialAppAnalyzer</FSharpAnalyzersOtherFlags>
<FSharpAnalyzersOtherFlags>$(FSharpAnalyzersOtherFlags) --exclude-analyzers PartialAppAnalyzer</FSharpAnalyzersOtherFlags>
</PropertyGroup>
```

Expand Down
93 changes: 63 additions & 30 deletions src/FSharp.Analyzers.Cli/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ type Arguments =
| [<Unique>] Treat_As_Hint of string list
| [<Unique>] Treat_As_Warning of string list
| [<Unique>] Treat_As_Error of string list
| [<Unique>] Ignore_Files of string list
| [<Unique>] Exclude_Analyzer of string list
| [<Unique>] Include_Analyzer of string list
| [<Unique>] Exclude_Files of string list
| [<Unique>] Include_Files of string list
| [<Unique>] Exclude_Analyzers of string list
| [<Unique>] Include_Analyzers of string list
| [<Unique>] Report of string
| [<Unique>] FSC_Args of string
| [<Unique>] Code_Root of string
Expand All @@ -52,10 +53,12 @@ type Arguments =
"List of analyzer codes that should be treated as severity Warning by the tool. Regardless of the original severity."
| Treat_As_Error _ ->
"List of analyzer codes that should be treated as severity Error by the tool. Regardless of the original severity."
| Ignore_Files _ -> "Source files that shouldn't be processed."
| Exclude_Analyzer _ -> "The names of analyzers that should not be executed."
| Include_Analyzer _ ->
"The names of analyzers that should exclusively be executed while all others are ignored. Takes precedence over --exclude-analyzer."
| Exclude_Files _ -> "Source files that shouldn't be processed."
| Include_Files _ ->
"Source files that should be processed exclusively while all others are ignored. Takes precedence over --exclude-files."
| Exclude_Analyzers _ -> "The names of analyzers that should not be executed."
| Include_Analyzers _ ->
"The names of analyzers that should exclusively be executed while all others are ignored. Takes precedence over --exclude-analyzers."
| Report _ -> "Write the result messages to a (sarif) report file."
| Verbosity _ ->
"The verbosity level. The available verbosity levels are: n[ormal], d[etailed], diag[nostic]."
Expand Down Expand Up @@ -131,7 +134,7 @@ let loadProject toolsPath properties projPath =
let runProjectAux
(client: Client<CliAnalyzerAttribute, CliContext>)
(fsharpOptions: FSharpProjectOptions)
(ignoreFiles: Glob list)
(excludeIncludeFiles: Choice<Glob list, Glob list>)
(mappings: SeverityMappings)
=
async {
Expand All @@ -140,11 +143,19 @@ let runProjectAux
let! messagesPerAnalyzer =
fsharpOptions.SourceFiles
|> Array.filter (fun file ->
match ignoreFiles |> List.tryFind (fun g -> g.IsMatch file) with
| Some g ->
logger.LogInformation("Ignoring file {0} for pattern {1}", file, g.Pattern)
false
| None -> true
match excludeIncludeFiles with
| Choice1Of2 excludeFiles ->
match excludeFiles |> List.tryFind (fun g -> g.IsMatch file) with
| Some g ->
logger.LogInformation("Ignoring file {0} for pattern {1}", file, g.Pattern)
false
| None -> true
| Choice2Of2 includeFiles ->
match includeFiles |> List.tryFind (fun g -> g.IsMatch file) with
| Some g ->
logger.LogInformation("Including file {0} for pattern {1}", file, g.Pattern)
true
| None -> false
)
|> Array.choose (fun fileName ->
let fileContent = File.ReadAllText fileName
Expand Down Expand Up @@ -173,13 +184,13 @@ let runProject
toolsPath
properties
proj
(globs: Glob list)
(excludeIncludeFiles: Choice<Glob list, Glob list>)
(mappings: SeverityMappings)
=
async {
let path = Path.Combine(Environment.CurrentDirectory, proj) |> Path.GetFullPath
let! option = loadProject toolsPath properties path
return! runProjectAux client option globs mappings
return! runProjectAux client option excludeIncludeFiles mappings
}

let fsharpFiles = set [| ".fs"; ".fsi"; ".fsx" |]
Expand All @@ -190,7 +201,7 @@ let isFSharpFile (file: string) =
let runFscArgs
(client: Client<CliAnalyzerAttribute, CliContext>)
(fscArgs: string)
(globs: Glob list)
(excludeIncludeFiles: Choice<Glob list, Glob list>)
(mappings: SeverityMappings)
=
if String.IsNullOrWhiteSpace fscArgs then
Expand Down Expand Up @@ -229,7 +240,7 @@ let runFscArgs
Stamp = None
}

runProjectAux client projectOptions globs mappings
runProjectAux client projectOptions excludeIncludeFiles mappings

let printMessages (msgs: AnalyzerMessage list) =

Expand Down Expand Up @@ -507,9 +518,24 @@ let main argv =
let fscArgs = results.TryGetResult <@ FSC_Args @>
let report = results.TryGetResult <@ Report @>
let codeRoot = results.TryGetResult <@ Code_Root @>
let ignoreFiles = results.GetResult(<@ Ignore_Files @>, [])
logger.LogInformation("Ignore Files: [{0}]", (ignoreFiles |> String.concat ", "))
let ignoreFiles = ignoreFiles |> List.map Glob

let exclInclFiles =
let excludeFiles = results.GetResult(<@ Exclude_Files @>, [])
logger.LogInformation("Exclude Files: [{0}]", (excludeFiles |> String.concat ", "))
let excludeFiles = excludeFiles |> List.map Glob

let includeFiles = results.GetResult(<@ Include_Files @>, [])
logger.LogInformation("Include Files: [{0}]", (includeFiles |> String.concat ", "))
let includeFiles = includeFiles |> List.map Glob

match excludeFiles, includeFiles with
| e, [] -> Choice1Of2 e
| [], i -> Choice2Of2 i
| _e, i ->
logger.LogWarning("--exclude-files and --include-files are mutually exclusive, ignoring --exclude-files")

Choice2Of2 i

let properties = getProperties results

if Option.isSome fscArgs && not properties.IsEmpty then
Expand All @@ -534,19 +560,24 @@ let main argv =

logger.LogInformation("Loading analyzers from {0}", (String.concat ", " analyzersPaths))

let includeExclude =
let excludeAnalyzers = results.GetResult(<@ Exclude_Analyzer @>, [])
let includeAnalyzers = results.GetResult(<@ Include_Analyzer @>, [])
let exclInclAnalyzers =
let excludeAnalyzers = results.GetResult(<@ Exclude_Analyzers @>, [])
let includeAnalyzers = results.GetResult(<@ Include_Analyzers @>, [])

match excludeAnalyzers, includeAnalyzers with
| e, [] -> Exclude(Set.ofList e)
| [], i -> Include(Set.ofList i)
| i, _e ->
| e, [] ->
fun (s: string) -> e |> List.map Glob |> List.exists (fun g -> g.IsMatch s)
|> ExcludeFilter
| [], i ->
fun (s: string) -> i |> List.map Glob |> List.exists (fun g -> g.IsMatch s)
|> IncludeFilter
| _e, i ->
logger.LogWarning(
"--exclude-analyzers and --include-analyzers are mutually exclusive, ignoring --exclude-analyzers"
)

Include(Set.ofList i)
fun (s: string) -> i |> List.map Glob |> List.exists (fun g -> g.IsMatch s)
|> IncludeFilter

AssemblyLoadContext.Default.add_Resolving (fun _ctx assemblyName ->
if assemblyName.Name <> "FSharp.Core" then
Expand All @@ -568,7 +599,7 @@ let main argv =
let dlls, analyzers =
((0, 0), analyzersPaths)
||> List.fold (fun (accDlls, accAnalyzers) analyzersPath ->
let dlls, analyzers = client.LoadAnalyzers(analyzersPath, includeExclude)
let dlls, analyzers = client.LoadAnalyzers(analyzersPath, exclInclAnalyzers)
(accDlls + dlls), (accAnalyzers + analyzers)
)

Expand All @@ -586,7 +617,9 @@ let main argv =
| _ :: _, Some _ ->
logger.LogError("`--project` and `--fsc-args` cannot be combined.")
exit 1
| [], Some fscArgs -> runFscArgs client fscArgs ignoreFiles severityMapping |> Async.RunSynchronously
| [], Some fscArgs ->
runFscArgs client fscArgs exclInclFiles severityMapping
|> Async.RunSynchronously
| projects, None ->
for projPath in projects do
if not (File.Exists(projPath)) then
Expand All @@ -595,7 +628,7 @@ let main argv =

projects
|> List.map (fun projPath ->
runProject client toolsPath properties projPath ignoreFiles severityMapping
runProject client toolsPath properties projPath exclInclFiles severityMapping
)
|> Async.Sequential
|> Async.RunSynchronously
Expand Down
14 changes: 7 additions & 7 deletions src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.Client.fs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ module Client =
|> Seq.toList

type ExcludeInclude =
| Exclude of string Set
| Include of string Set
| ExcludeFilter of (string -> bool)
| IncludeFilter of (string -> bool)

type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TContext :> Context>(logger: ILogger) =
do TASTCollecting.logger <- logger
Expand All @@ -149,7 +149,7 @@ type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TC
let s = Path.GetFileName(a)

not (
s.EndsWith("fsharp.analyzers.sdk.dll", StringComparison.InvariantCultureIgnoreCase)
s.EndsWith("fsharp.analyzers.sdk.dll", StringComparison.OrdinalIgnoreCase)
|| regex.IsMatch(s)
)
)
Expand Down Expand Up @@ -200,8 +200,8 @@ type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TC
|> Seq.collect (Client.analyzersFromType<'TAttribute, 'TContext> path)
|> Seq.filter (fun registeredAnalyzer ->
match excludeInclude with
| Some(Exclude excluded) ->
let shouldExclude = excluded.Contains(registeredAnalyzer.Name)
| Some(ExcludeFilter excludeFilter) ->
let shouldExclude = excludeFilter registeredAnalyzer.Name

if shouldExclude then
logger.LogInformation(
Expand All @@ -211,8 +211,8 @@ type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TC
)

not shouldExclude
| Some(Include included) ->
let shouldInclude = included.Contains(registeredAnalyzer.Name)
| Some(IncludeFilter includeFilter) ->
let shouldInclude = includeFilter registeredAnalyzer.Name

if shouldInclude then
logger.LogInformation(
Expand Down
8 changes: 4 additions & 4 deletions src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.Client.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ type AnalysisResult =
}

type ExcludeInclude =
/// Analyzers in this set should be ignored.
| Exclude of string Set
/// Analyzers in this set should be used exclusively, while all others are ignored.
| Include of string Set
/// A predicate function to exclude Analyzers.
| ExcludeFilter of (string -> bool)
/// A predicate function to include Analyzers exclusively, while all others are ignored.
| IncludeFilter of (string -> bool)

type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TContext :> Context> =
new: logger: ILogger -> Client<'TAttribute, 'TContext>
Expand Down

0 comments on commit 8e8fd19

Please sign in to comment.