From d3125ed913d5dccb0ccf3e646048b6d07d2bf7f7 Mon Sep 17 00:00:00 2001 From: Smaug123 Date: Tue, 30 Jan 2024 18:33:40 +0000 Subject: [PATCH 1/3] Error when unmatched analyzers --- src/FSharp.Analyzers.Cli/Program.fs | 106 +++++++++++++++++++--------- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index 3c1c4f5..872d72a 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -1,4 +1,5 @@ open System +open System.Collections.Generic open System.IO open System.Runtime.Loader open System.Runtime.InteropServices @@ -456,6 +457,32 @@ let getProperties (results: ParseResults) = | _ -> () ] +/// Returns a "does this string match any of these globs" function, +/// and also an IReadOnlyList you can use to determine whether across all invocations of the function, +/// any given glob was ever matched. +/// Note that the returned function will always scan over every element of the input list, so that it +/// can report the "did anything match this glob" correctly. +let createFilter (globs: string list) : (string -> bool) * IReadOnlyList = + let globs = globs |> List.map Glob + + let unmatchedAnalyzerPatterns = ResizeArray() + + globs |> Seq.map (fun glob -> glob, true) |> unmatchedAnalyzerPatterns.AddRange + + let anyMatches (s: string) = + let mutable result = false + + globs + |> List.iteri (fun index glob -> + if glob.IsMatch s then + unmatchedAnalyzerPatterns.[index] <- (glob, false) + result <- true + ) + + result + + anyMatches, unmatchedAnalyzerPatterns :> _ + [] let main argv = let toolsPath = Init.init (DirectoryInfo Environment.CurrentDirectory) None @@ -555,24 +582,24 @@ let main argv = logger.LogInformation("Loading analyzers from {0}", (String.concat ", " analyzersPaths)) - let exclInclAnalyzers = + let exclInclAnalyzers, unmatchedAnalyzerPatterns = let excludeAnalyzers = results.GetResult(<@ Exclude_Analyzers @>, []) let includeAnalyzers = results.GetResult(<@ Include_Analyzers @>, []) match excludeAnalyzers, includeAnalyzers with | e, [] -> - fun (s: string) -> e |> List.map Glob |> List.exists (fun g -> g.IsMatch s) - |> ExcludeFilter + let result, list = createFilter e + ExcludeFilter result, list | [], i -> - fun (s: string) -> i |> List.map Glob |> List.exists (fun g -> g.IsMatch s) - |> IncludeFilter + let result, list = createFilter i + IncludeFilter result, list | _e, i -> logger.LogWarning( "--exclude-analyzers and --include-analyzers are mutually exclusive, ignoring --exclude-analyzers" ) - fun (s: string) -> i |> List.map Glob |> List.exists (fun g -> g.IsMatch s) - |> IncludeFilter + let result, list = createFilter i + IncludeFilter result, list AssemblyLoadContext.Default.add_Resolving (fun _ctx assemblyName -> if assemblyName.Name <> "FSharp.Core" then @@ -634,36 +661,51 @@ let main argv = |> List.concat |> Some - match results with - | None -> -1 - | Some results -> - let results, hasError = - match Result.allOkOrError results with - | Ok results -> results, false - | Error(results, _errors) -> results, true + let results = + match results with + | None -> exit -1 + | Some results -> results + + let results, hasError = + match Result.allOkOrError results with + | Ok results -> results, false + | Error(results, _errors) -> results, true - let results = results |> List.concat + let results = results |> List.concat - printMessages results + printMessages results - report |> Option.iter (writeReport results codeRoot) + report |> Option.iter (writeReport results codeRoot) - let check = - results - |> List.exists (fun analyzerMessage -> - let message = analyzerMessage.Message + let check = + results + |> List.exists (fun analyzerMessage -> + let message = analyzerMessage.Message - message.Severity = Severity.Error - ) + message.Severity = Severity.Error + ) - if failedAssemblies > 0 then - logger.LogError( - "Because we failed to load some assemblies to obtain analyzers from them, exiting (failure count: {FailedAssemblyLoadCount})", - failedAssemblies - ) + if failedAssemblies > 0 then + logger.LogError( + "Because we failed to load some assemblies to obtain analyzers from them, exiting (failure count: {FailedAssemblyLoadCount})", + failedAssemblies + ) + + exit -3 + + let unmatchedAnalyzerPatterns = + unmatchedAnalyzerPatterns + |> Seq.choose (fun (glob, isUnmatched) -> if isUnmatched then Some glob else None) + |> Seq.toList + + if not (List.isEmpty unmatchedAnalyzerPatterns) then + logger.LogError( + "The following glob(s) were specified to include or exclude specific analyzers, but they did not match any discovered analyzers. Have you got them right? {UnmatchedAnalyzerGlobs}", + unmatchedAnalyzerPatterns |> Seq.map _.Pattern |> String.concat ", " + ) - exit -3 + exit -5 - if check then -2 - elif hasError then -4 - else 0 + if check then -2 + elif hasError then -4 + else 0 From 1dc939029655be7b7b2c84aaf479ff769ac1c85f Mon Sep 17 00:00:00 2001 From: Smaug123 Date: Tue, 30 Jan 2024 18:44:30 +0000 Subject: [PATCH 2/3] Provide error message in more cases --- src/FSharp.Analyzers.Cli/Program.fs | 44 ++++++++++++------- .../Properties/launchSettings.json | 2 +- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index 872d72a..ac3d0fa 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -661,6 +661,25 @@ let main argv = |> List.concat |> Some + let unmatchedAnalyzerPatterns = + unmatchedAnalyzerPatterns + |> Seq.choose (fun (glob, isUnmatched) -> if isUnmatched then Some glob else None) + |> Seq.toList + + // Before we process the results, unconditionally warn if the inclusion or exclusion globs didn't look right. + // Then, *after* we've printed the results (which may be useful even if they're partial!), we'll fail if they + // didn't look right. + let anyUnmatchedAnalyzers = + if not (List.isEmpty unmatchedAnalyzerPatterns) then + logger.LogError( + "The following glob(s) were specified to include or exclude specific analyzers, but they did not match any discovered analyzers. Have you got them right? {UnmatchedAnalyzerGlobs}", + unmatchedAnalyzerPatterns |> Seq.map _.Pattern |> String.concat ", " + ) + + true + else + false + let results = match results with | None -> exit -1 @@ -693,19 +712,12 @@ let main argv = exit -3 - let unmatchedAnalyzerPatterns = - unmatchedAnalyzerPatterns - |> Seq.choose (fun (glob, isUnmatched) -> if isUnmatched then Some glob else None) - |> Seq.toList - - if not (List.isEmpty unmatchedAnalyzerPatterns) then - logger.LogError( - "The following glob(s) were specified to include or exclude specific analyzers, but they did not match any discovered analyzers. Have you got them right? {UnmatchedAnalyzerGlobs}", - unmatchedAnalyzerPatterns |> Seq.map _.Pattern |> String.concat ", " - ) - - exit -5 - - if check then -2 - elif hasError then -4 - else 0 + if anyUnmatchedAnalyzers then + logger.LogError("Aborting because there were unmatched analyzer globs (see earlier log).") + -5 + elif check then + -2 + elif hasError then + -4 + else + 0 diff --git a/src/FSharp.Analyzers.Cli/Properties/launchSettings.json b/src/FSharp.Analyzers.Cli/Properties/launchSettings.json index 3a967a7..0ba4bc2 100644 --- a/src/FSharp.Analyzers.Cli/Properties/launchSettings.json +++ b/src/FSharp.Analyzers.Cli/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ReadMeSample": { "commandName": "Project", - "commandLineArgs": "--project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbosity d" + "commandLineArgs": "--include-analyzers OptionAnailyzer --project /Users/patrick/Documents/GitHub/FSharp.Analyzers.SDK/samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path /Users/patrick/Documents/GitHub/FSharp.Analyzers.SDK/samples/OptionAnalyzer/bin/Release --verbosity d" } } } From 44efef611bc712f969bc623e145c8e494812346c Mon Sep 17 00:00:00 2001 From: Smaug123 Date: Tue, 30 Jan 2024 19:39:37 +0000 Subject: [PATCH 3/3] Revert launchsettings --- src/FSharp.Analyzers.Cli/Properties/launchSettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharp.Analyzers.Cli/Properties/launchSettings.json b/src/FSharp.Analyzers.Cli/Properties/launchSettings.json index 0ba4bc2..3a967a7 100644 --- a/src/FSharp.Analyzers.Cli/Properties/launchSettings.json +++ b/src/FSharp.Analyzers.Cli/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ReadMeSample": { "commandName": "Project", - "commandLineArgs": "--include-analyzers OptionAnailyzer --project /Users/patrick/Documents/GitHub/FSharp.Analyzers.SDK/samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path /Users/patrick/Documents/GitHub/FSharp.Analyzers.SDK/samples/OptionAnalyzer/bin/Release --verbosity d" + "commandLineArgs": "--project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbosity d" } } }