From 8b21437505f84a78185d211f54e1f3d8c588b13c Mon Sep 17 00:00:00 2001 From: Bernie White Date: Thu, 21 Dec 2023 00:48:11 +1000 Subject: [PATCH] Added outcome argument for CLI #1706 (#1707) --- docs/CHANGELOG-v3.md | 3 ++ docs/concepts/cli.md | 16 +++++++++++ src/PSRule.Tool/AnalyzerOptions.cs | 4 +++ src/PSRule.Tool/ClientBuilder.cs | 28 +++++++++++++++++-- src/PSRule.Tool/ClientHelper.cs | 6 ++-- .../Resources/CmdStrings.Designer.cs | 18 ++++++++++++ src/PSRule.Tool/Resources/CmdStrings.resx | 6 ++++ src/PSRule.Types/Data/SemanticVersion.cs | 2 -- src/PSRule/Configuration/PSRuleOption.cs | 1 - 9 files changed, 76 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG-v3.md b/docs/CHANGELOG-v3.md index f99609d4a6..0fe39a107b 100644 --- a/docs/CHANGELOG-v3.md +++ b/docs/CHANGELOG-v3.md @@ -29,6 +29,9 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers What's changed since pre-release v3.0.0-B0093: +- General improvements: + - Added `--outcome` argument for CLI to support filtering output by @bernieWhite. + [#1706](https://github.com/microsoft/PSRule/issues/1706) - Engineering: - Bump xunit to v2.6.3. [#1699](https://github.com/microsoft/PSRule/pull/1699) diff --git a/docs/concepts/cli.md b/docs/concepts/cli.md index f2873cafa9..8fbc31d2e1 100644 --- a/docs/concepts/cli.md +++ b/docs/concepts/cli.md @@ -8,6 +8,22 @@ Run rule analysis. +### `--outcome` + +Allows filtering of results by outcome. +The supported values are: + +- `Pass` - Results that passed. +- `Fail` - Results that did not pass. +- `Error` - Results that failed to be evaluted correctly due to an error. +- `Processed` - All results that were processed. + This aggregated outcome includes `Pass`, `Fail`, or `Error` results. +- `Problem` - Processed results that did not pass. + This aggregated outcome includes `Fail`, or `Error` results. + +To specify multiple values, specify the parameter multiple times. +For example: `--outcome Pass --Outcome Fail`. + ## `module add` Add one or more modules to the lock file. diff --git a/src/PSRule.Tool/AnalyzerOptions.cs b/src/PSRule.Tool/AnalyzerOptions.cs index 48dba28f6f..39a1303030 100644 --- a/src/PSRule.Tool/AnalyzerOptions.cs +++ b/src/PSRule.Tool/AnalyzerOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using PSRule.Rules; + namespace PSRule.Tool { internal sealed class AnalyzerOptions @@ -13,6 +15,8 @@ internal sealed class AnalyzerOptions public string Baseline { get; set; } + public RuleOutcome? Outcome { get; set; } + public string[] InputPath { get; set; } public bool Verbose { get; set; } diff --git a/src/PSRule.Tool/ClientBuilder.cs b/src/PSRule.Tool/ClientBuilder.cs index 5d54948929..13d2d44fe6 100644 --- a/src/PSRule.Tool/ClientBuilder.cs +++ b/src/PSRule.Tool/ClientBuilder.cs @@ -2,8 +2,8 @@ // Licensed under the MIT License. using System.CommandLine; -using System.CommandLine.Builder; using System.Reflection; +using PSRule.Rules; using PSRule.Tool.Resources; namespace PSRule.Tool @@ -25,6 +25,7 @@ internal sealed class ClientBuilder private readonly Option _InputPath; private readonly Option _Module; private readonly Option _Baseline; + private readonly Option _Outcome; private ClientBuilder(RootCommand cmd) { @@ -60,8 +61,15 @@ private ClientBuilder(RootCommand cmd) CmdStrings.Options_Module_Description ); _Baseline = new Option( - new string[] { "--baseline" } + new string[] { "--baseline" }, + CmdStrings.Analyze_Baseline_Description ); + _Outcome = new Option( + new string[] { "--outcome" }, + description: CmdStrings.Analyze_Outcome_Description + ).FromAmong("Pass", "Fail", "Error", "Processed", "Problem"); + _Outcome.Arity = ArgumentArity.ZeroOrMore; + _RestoreForce = new Option( new string[] { "--force" }, CmdStrings.Restore_Force_Description @@ -109,6 +117,7 @@ private void AddAnalyze() cmd.AddOption(_InputPath); cmd.AddOption(_Module); cmd.AddOption(_Baseline); + cmd.AddOption(_Outcome); cmd.SetHandler((invocation) => { var option = new AnalyzerOptions @@ -118,6 +127,7 @@ private void AddAnalyze() Module = invocation.ParseResult.GetValueForOption(_Module), Option = invocation.ParseResult.GetValueForOption(_Option), Baseline = invocation.ParseResult.GetValueForOption(_Baseline), + Outcome = ParseOutcome(invocation.ParseResult.GetValueForOption(_Outcome)), Verbose = invocation.ParseResult.GetValueForOption(_Verbose), Debug = invocation.ParseResult.GetValueForOption(_Debug), }; @@ -233,5 +243,19 @@ private void AddModule() cmd.AddOption(_Path); Command.AddCommand(cmd); } + + /// + /// Convert string arguments to flags of . + /// + private static RuleOutcome? ParseOutcome(string[] s) + { + var result = RuleOutcome.None; + for (var i = 0; s != null && i < s.Length; i++) + { + if (Enum.TryParse(s[i], ignoreCase: true, result: out RuleOutcome flag)) + result |= flag; + } + return result == RuleOutcome.None ? null : result; + } } } diff --git a/src/PSRule.Tool/ClientHelper.cs b/src/PSRule.Tool/ClientHelper.cs index e669afe7ef..f702be3ffb 100644 --- a/src/PSRule.Tool/ClientHelper.cs +++ b/src/PSRule.Tool/ClientHelper.cs @@ -2,11 +2,8 @@ // Licensed under the MIT License. using System.Collections; -using System.CommandLine; using System.CommandLine.Invocation; -using System.Diagnostics; using System.Management.Automation; -using Microsoft.CodeAnalysis.Sarif; using PSRule.Configuration; using PSRule.Data; using PSRule.Pipeline; @@ -59,6 +56,9 @@ public static int RunAnalyze(AnalyzerOptions operationOptions, ClientContext cli if (operationOptions.Path != null) option.Include.Path = operationOptions.Path; + if (operationOptions.Outcome != null && operationOptions.Outcome.Value != Rules.RuleOutcome.None) + option.Output.Outcome = operationOptions.Outcome; + // Build command var builder = CommandLineBuilder.Assert(operationOptions.Module, option, host, file); builder.Baseline(BaselineOption.FromString(operationOptions.Baseline)); diff --git a/src/PSRule.Tool/Resources/CmdStrings.Designer.cs b/src/PSRule.Tool/Resources/CmdStrings.Designer.cs index 27e34b315f..8638b85fda 100644 --- a/src/PSRule.Tool/Resources/CmdStrings.Designer.cs +++ b/src/PSRule.Tool/Resources/CmdStrings.Designer.cs @@ -60,6 +60,15 @@ internal class CmdStrings { } } + /// + /// Looks up a localized string similar to The specific baseline to use.. + /// + internal static string Analyze_Baseline_Description { + get { + return ResourceManager.GetString("Analyze_Baseline_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to Run rule analysis.. /// @@ -69,6 +78,15 @@ internal class CmdStrings { } } + /// + /// Looks up a localized string similar to Specifies the rule results to show in output. By default, Pass/ Fail/ Error results are shown.. + /// + internal static string Analyze_Outcome_Description { + get { + return ResourceManager.GetString("Analyze_Outcome_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to PSRule CLI. /// diff --git a/src/PSRule.Tool/Resources/CmdStrings.resx b/src/PSRule.Tool/Resources/CmdStrings.resx index ed7d8183c1..479984214d 100644 --- a/src/PSRule.Tool/Resources/CmdStrings.resx +++ b/src/PSRule.Tool/Resources/CmdStrings.resx @@ -117,9 +117,15 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + The specific baseline to use. + Run rule analysis. + + Specifies the rule results to show in output. By default, Pass/ Fail/ Error results are shown. + PSRule CLI diff --git a/src/PSRule.Types/Data/SemanticVersion.cs b/src/PSRule.Types/Data/SemanticVersion.cs index 260be5f93b..bf27056b5e 100644 --- a/src/PSRule.Types/Data/SemanticVersion.cs +++ b/src/PSRule.Types/Data/SemanticVersion.cs @@ -1,9 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System; using System.Diagnostics; -using YamlDotNet.Core.Tokens; namespace PSRule.Data { diff --git a/src/PSRule/Configuration/PSRuleOption.cs b/src/PSRule/Configuration/PSRuleOption.cs index b35ed22b84..434bd68873 100644 --- a/src/PSRule/Configuration/PSRuleOption.cs +++ b/src/PSRule/Configuration/PSRuleOption.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Diagnostics; -using System.Globalization; using System.Management.Automation; using Newtonsoft.Json; using PSRule.Converters.Yaml;