diff --git a/src/pkgchk-cli/Commands.fs b/src/pkgchk-cli/Commands.fs new file mode 100644 index 00000000..9e584a4a --- /dev/null +++ b/src/pkgchk-cli/Commands.fs @@ -0,0 +1,73 @@ +namespace pkgchk + +module Commands = + + let private runProc logging proc = + try + proc |> Io.run logging + finally + proc.Dispose() + + let console = Spectre.Console.AnsiConsole.MarkupLine + + let trace traceLogging = + if traceLogging then Console.grey >> console else ignore + + let getErrors procResults = + procResults + |> Seq.map (function + | Choice2Of2 x -> x + | _ -> "") + |> Seq.filter String.isNotEmpty + |> Seq.distinct + + let returnError error = + error |> Console.error |> console + ReturnCodes.sysError + + let renderTables (values: seq) = + values |> Seq.iter Spectre.Console.AnsiConsole.Write + + let liftHits procResults = + procResults + |> Seq.collect (function + | Choice1Of2 xs -> xs + | _ -> []) + |> List.ofSeq + + let sortHits (hits: seq) = + hits + |> Seq.sortBy (fun h -> + ((match h.kind with + | ScaHitKind.Vulnerability -> 0 + | ScaHitKind.Dependency -> 1 + | ScaHitKind.VulnerabilityTransitive -> 2 + | ScaHitKind.Deprecated -> 3 + | ScaHitKind.DependencyTransitive -> 4), + h.packageId)) + + let getHits x = x |> liftHits |> sortHits |> List.ofSeq + + let restore (settings: PackageCommandSettings) logging = + if settings.NoRestore then + Choice1Of2 false + else + let runRestoreProcParse run proc = + proc + |> run + |> (function + | Choice2Of2 error -> Choice2Of2 error + | _ -> Choice1Of2 true) + + settings.ProjectPath + |> Sca.restoreArgs + |> Io.createProcess + |> runRestoreProcParse (runProc logging) + + let scan trace = + Sca.scanArgs + >> Array.map (fun (args, parser) -> (Io.createProcess args, parser)) + >> Array.map (fun (proc, parser) -> + match proc |> (runProc trace) with + | Choice1Of2 json -> parser json + | Choice2Of2 x -> Choice2Of2 x) diff --git a/src/pkgchk-cli/PackageCommandSettings.fs b/src/pkgchk-cli/PackageCommandSettings.fs new file mode 100644 index 00000000..61711f22 --- /dev/null +++ b/src/pkgchk-cli/PackageCommandSettings.fs @@ -0,0 +1,30 @@ +namespace pkgchk + +open System +open System.ComponentModel +open System.Diagnostics.CodeAnalysis +open Spectre.Console.Cli + +[] +type PackageCommandSettings() = + inherit CommandSettings() + + [] + [] + [] + member val ProjectPath = "" with get, set + + [] + [] + [] + member val TraceLogging = false with get, set + + [] + [] + [] + member val NoRestore = false with get, set + + [] + [] + [] + member val NoBanner = false with get, set diff --git a/src/pkgchk-cli/PackageListCommand.fs b/src/pkgchk-cli/PackageListCommand.fs index 385aa239..15a5e0f8 100644 --- a/src/pkgchk-cli/PackageListCommand.fs +++ b/src/pkgchk-cli/PackageListCommand.fs @@ -6,124 +6,37 @@ open Spectre.Console.Cli [] type PackageListCommandSettings() = - inherit CommandSettings() - - [] - [] - [] - member val ProjectPath = "" with get, set + inherit PackageCommandSettings() [] [] [] member val IncludeTransitives = true with get, set - [] - [] - [] - member val TraceLogging = false with get, set - - [] - [] - [] - member val NoRestore = false with get, set - - [] - [] - [] - member val NoBanner = false with get, set - [] type PackageListCommand(nuget: Tk.Nuget.INugetClient) = inherit Command() - let console = Spectre.Console.AnsiConsole.MarkupLine - - let trace traceLogging = - if traceLogging then Console.grey >> console else ignore - - let returnError error = - error |> Console.error |> console - ReturnCodes.sysError - - let runProc logging proc = - try - proc |> Io.run logging - finally - proc.Dispose() - - let runRestore (settings: PackageListCommandSettings) logging = - if settings.NoRestore then - Choice1Of2 false - else - let runRestoreProcParse run proc = - proc - |> run - |> (function - | Choice2Of2 error -> Choice2Of2 error - | _ -> Choice1Of2 true) - - settings.ProjectPath - |> Sca.restoreArgs - |> Io.createProcess - |> runRestoreProcParse (runProc logging) - - let getErrors procResults = - procResults - |> Seq.map (function - | Choice2Of2 x -> x - | _ -> "") - |> Seq.filter String.isNotEmpty - |> Seq.distinct - - let renderTables (values: seq) = - values |> Seq.iter Spectre.Console.AnsiConsole.Write - - let liftHits procResults = - procResults - |> Seq.collect (function - | Choice1Of2 xs -> xs - | _ -> []) - |> List.ofSeq - - let sortHits (hits: seq) = - hits - |> Seq.sortBy (fun h -> - ((match h.kind with - | ScaHitKind.Vulnerability -> 0 - | ScaHitKind.Dependency -> 1 - | ScaHitKind.VulnerabilityTransitive -> 2 - | ScaHitKind.Deprecated -> 3 - | ScaHitKind.DependencyTransitive -> 4), - h.packageId)) - - let getHits = liftHits >> sortHits >> List.ofSeq - override _.Execute(context, settings) = - let trace = trace settings.TraceLogging + let trace = Commands.trace settings.TraceLogging if settings.NoBanner |> not then - nuget |> App.banner |> console + nuget |> App.banner |> Commands.console - match runRestore settings trace with - | Choice2Of2 error -> error |> returnError + match Commands.restore settings trace with + | Choice2Of2 error -> error |> Commands.returnError | _ -> let results = (settings.ProjectPath, false, settings.IncludeTransitives, false, true) - |> Sca.scanArgs - |> Array.map (fun (args, parser) -> (Io.createProcess args, parser)) - |> Array.map (fun (proc, parser) -> - match proc |> (runProc trace) with - | Choice1Of2 json -> parser json - | Choice2Of2 x -> Choice2Of2 x) + |> Commands.scan trace - let errors = getErrors results + let errors = Commands.getErrors results if Seq.isEmpty errors |> not then - errors |> String.joinLines |> returnError + errors |> String.joinLines |> Commands.returnError else trace "Analysing results..." - let hits = getHits results + let hits = Commands.getHits results let hitCounts = hits |> Sca.hitCountSummary |> List.ofSeq trace "Building display..." @@ -136,6 +49,6 @@ type PackageListCommand(nuget: Tk.Nuget.INugetClient) = hitCounts |> Console.hitSummaryTable } - renderTables renderables + Commands.renderTables renderables ReturnCodes.validationOk diff --git a/src/pkgchk-cli/PackageScanCommand.fs b/src/pkgchk-cli/PackageScanCommand.fs index 30395b15..8e75ab3e 100644 --- a/src/pkgchk-cli/PackageScanCommand.fs +++ b/src/pkgchk-cli/PackageScanCommand.fs @@ -7,12 +7,7 @@ open Spectre.Console.Cli [] type PackageScanCommandSettings() = - inherit CommandSettings() - - [] - [] - [] - member val ProjectPath = "" with get, set + inherit PackageCommandSettings() [] [] @@ -39,21 +34,6 @@ type PackageScanCommandSettings() = [] member val SeverityLevels: string array = [||] with get, set - [] - [] - [] - member val TraceLogging = false with get, set - - [] - [] - [] - member val NoRestore = false with get, set - - [] - [] - [] - member val NoBanner = false with get, set - [] [] [] @@ -93,68 +73,6 @@ type PackageScanCommandSettings() = type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = inherit Command() - let console = Spectre.Console.AnsiConsole.MarkupLine - - let trace traceLogging = - if traceLogging then Console.grey >> console else ignore - - let returnError error = - error |> Console.error |> console - ReturnCodes.sysError - - let runProc logging proc = - try - proc |> Io.run logging - finally - proc.Dispose() - - let runRestore (settings: PackageScanCommandSettings) logging = - if settings.NoRestore then - Choice1Of2 false - else - let runRestoreProcParse run proc = - proc - |> run - |> (function - | Choice2Of2 error -> Choice2Of2 error - | _ -> Choice1Of2 true) - - settings.ProjectPath - |> Sca.restoreArgs - |> Io.createProcess - |> runRestoreProcParse (runProc logging) - - let getErrors procResults = - procResults - |> Seq.map (function - | Choice2Of2 x -> x - | _ -> "") - |> Seq.filter String.isNotEmpty - |> Seq.distinct - - let renderTables (values: seq) = - values |> Seq.iter Spectre.Console.AnsiConsole.Write - - let liftHits procResults = - procResults - |> Seq.collect (function - | Choice1Of2 xs -> xs - | _ -> []) - |> List.ofSeq - - let sortHits (hits: seq) = - hits - |> Seq.sortBy (fun h -> - ((match h.kind with - | ScaHitKind.Vulnerability -> 0 - | ScaHitKind.Dependency -> 1 - | ScaHitKind.VulnerabilityTransitive -> 2 - | ScaHitKind.Deprecated -> 3 - | ScaHitKind.DependencyTransitive -> 4), - h.packageId)) - - let getHits = liftHits >> sortHits >> List.ofSeq - let rec genComment trace (settings: PackageScanCommandSettings, hits, errorHits, hitCounts, imageUri) attempt = let markdown = (hits, errorHits, hitCounts, settings.SeverityLevels, imageUri) @@ -210,17 +128,17 @@ type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = failwith "The PR ID must be an integer." override _.Execute(context, settings) = - let trace = trace settings.TraceLogging + let trace = Commands.trace settings.TraceLogging let settings = cleanSettings settings if settings.NoBanner |> not then - nuget |> App.banner |> console + nuget |> App.banner |> Commands.console validateSettings settings - match runRestore settings trace with - | Choice2Of2 error -> error |> returnError + match Commands.restore settings trace with + | Choice2Of2 error -> error |> Commands.returnError | _ -> let results = (settings.ProjectPath, @@ -228,20 +146,15 @@ type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = settings.IncludeTransitives, settings.IncludeDeprecations, false) - |> Sca.scanArgs - |> Array.map (fun (args, parser) -> (Io.createProcess args, parser)) - |> Array.map (fun (proc, parser) -> - match proc |> (runProc trace) with - | Choice1Of2 json -> parser json - | Choice2Of2 x -> Choice2Of2 x) + |> Commands.scan trace - let errors = getErrors results + let errors = Commands.getErrors results if Seq.isEmpty errors |> not then - errors |> String.joinLines |> returnError + errors |> String.joinLines |> Commands.returnError else trace "Analysing results..." - let hits = getHits results + let hits = Commands.getHits results let errorHits = hits |> Sca.hitsByLevels settings.SeverityLevels let hitCounts = errorHits |> Sca.hitCountSummary |> List.ofSeq @@ -259,7 +172,7 @@ type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = hitCounts |> Console.hitSummaryTable } - renderables |> renderTables + renderables |> Commands.renderTables let reportImg = match isSuccessScan errorHits with @@ -276,7 +189,7 @@ type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = $"{Environment.NewLine}Report file [link={reportFile}]{reportFile}[/] built." |> Console.italic - |> console + |> Commands.console if String.isNotEmpty settings.GithubToken @@ -294,7 +207,7 @@ type PackageScanCommand(nuget: Tk.Nuget.INugetClient) = if String.isNotEmpty settings.GithubPrId then trace $"Posting {comment.title} PR comment to Github repo {repo}..." let _ = (comment |> Github.setPrComment trace client repo prId).Result - $"{comment.title} report sent to Github." |> Console.italic |> console + $"{comment.title} report sent to Github." |> Console.italic |> Commands.console if String.isNotEmpty settings.GithubCommit then trace $"Posting {comment.title} build check to Github repo {repo}..." diff --git a/src/pkgchk-cli/pkgchk-cli.fsproj b/src/pkgchk-cli/pkgchk-cli.fsproj index fbbfa699..bb08a268 100644 --- a/src/pkgchk-cli/pkgchk-cli.fsproj +++ b/src/pkgchk-cli/pkgchk-cli.fsproj @@ -36,6 +36,8 @@ + +