Skip to content

Commit

Permalink
PSRule banner can be configured in output #708 (#709)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite committed May 9, 2021
1 parent 6b64034 commit fc09406
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -331,6 +331,7 @@ The following conceptual topics exist in the `PSRule` module:
- [Logging.RuleFail](docs/concepts/PSRule/en-US/about_PSRule_Options.md#loggingrulefail)
- [Logging.RulePass](docs/concepts/PSRule/en-US/about_PSRule_Options.md#loggingrulepass)
- [Output.As](docs/concepts/PSRule/en-US/about_PSRule_Options.md#outputas)
- [Output.Banner](docs/concepts/PSRule/en-US/about_PSRule_Options.md#outputbanner)
- [Output.Culture](docs/concepts/PSRule/en-US/about_PSRule_Options.md#outputculture)
- [Output.Encoding](docs/concepts/PSRule/en-US/about_PSRule_Options.md#outputencoding)
- [Output.Format](docs/concepts/PSRule/en-US/about_PSRule_Options.md#outputformat)
Expand Down
5 changes: 5 additions & 0 deletions docs/CHANGELOG-v1.md
Expand Up @@ -10,6 +10,11 @@ See [upgrade notes][upgrade-notes] for helpful information when upgrading from p

## Unreleased

What's changed since v1.3.0:

- General improvements:
- PSRule banner can be configured in output when using `Assert-PSRule`. [#708](https://github.com/microsoft/PSRule/issues/708)

## v1.3.0

What's changed since v1.2.0:
Expand Down
65 changes: 65 additions & 0 deletions docs/concepts/PSRule/en-US/about_PSRule_Options.md
Expand Up @@ -27,6 +27,7 @@ The following workspace options are available for use:
- [Logging.RuleFail](#loggingrulefail)
- [Logging.RulePass](#loggingrulepass)
- [Output.As](#outputas)
- [Output.Banner](#outputbanner)
- [Output.Culture](#outputculture)
- [Output.Encoding](#outputencoding)
- [Output.Format](#outputformat)
Expand Down Expand Up @@ -1305,6 +1306,68 @@ variables:
value: Summary
```

### Output.Banner

The information displayed for PSRule banner.
This option is only applicable when using `Assert-PSRule` cmdlet.

The following information can be shown or hidden by configuring this option.

- `Title` (1) - Shows the PSRule title ASCII text.
- `Source` (2) - Shows rules module versions used in this run.
- `SupportLinks` (4) - Shows supporting links for PSRule and rules modules.

Additionally the following rollup options exist:

- `Default` - Shows `Title`, `Source`, and `SupportLinks`.
This is the default option.
- `Minimal` - Shows `Source`.

This option can be configured using one of the named values described above.
Alternatively, this value can be configured by specifying a bit mask as an integer.
For example `6` would show `Source`, and `SupportLinks`.

This option can be specified using:

```powershell
# PowerShell: Using the OutputBanner parameter
$option = New-PSRuleOption -OutputBanner Minimal;
```

```powershell
# PowerShell: Using the Output.Banner hashtable key
$option = New-PSRuleOption -Option @{ 'Output.Banner' = 'Minimal' };
```

```powershell
# PowerShell: Using the OutputBanner parameter to set YAML
Set-PSRuleOption -OutputBanner Minimal;
```

```yaml
# YAML: Using the output/banner property
output:
banner: OutputBanner
```

```bash
# Bash: Using environment variable
export PSRULE_OUTPUT_BANNER=Minimal
```

```yaml
# GitHub Actions: Using environment variable
env:
PSRULE_OUTPUT_BANNER: Minimal
```

```yaml
# Azure Pipelines: Using environment variable
variables:
- name: PSRULE_OUTPUT_BANNER
value: Minimal
```

### Output.Culture

Specified the name of one or more cultures to use for generating output.
Expand Down Expand Up @@ -1907,6 +1970,7 @@ logging:

output:
as: Summary
banner: Minimal
culture:
- en-US
encoding: UTF8
Expand Down Expand Up @@ -1993,6 +2057,7 @@ logging:

output:
as: Detail
banner: Default
culture: [ ]
encoding: Default
format: None
Expand Down
22 changes: 22 additions & 0 deletions schemas/PSRule-options.schema.json
Expand Up @@ -312,6 +312,28 @@
],
"default": "Detail"
},
"banner": {
"title": "Banner format",
"description": "The information displayed for Assert-PSRule banner. The default is Default which includes Title, Source, and SupportLinks.",
"markdownDescription": "The information displayed for Assert-PSRule banner. The default is `Default` which includes `Title`, `Source`, and `SupportLinks`. [See help](https://microsoft.github.io/PSRule/concepts/PSRule/en-US/about_PSRule_Options.html#outputbanner)",
"oneOf": [
{
"type": "string",
"enum": [
"None",
"Title",
"Source",
"SupportLinks",
"Default",
"Minimal"
]
},
{
"type": "integer"
}
],
"default": "Default"
},
"culture": {
"type": "array",
"title": "Culture",
Expand Down
40 changes: 40 additions & 0 deletions src/PSRule/Configuration/BannerFormat.cs
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;

namespace PSRule.Configuration
{
/// <summary>
/// The information displayed for Assert-PSRule banner.
/// </summary>
[Flags]
[JsonConverter(typeof(StringEnumConverter))]
public enum BannerFormat
{
/// <summary>
/// No banner is shown.
/// </summary>
None = 0,

/// <summary>
/// The PSRule title ASCII text is shown.
/// </summary>
Title = 1,

/// <summary>
/// The rules module versions used in this run are shown.
/// </summary>
Source = 2,

/// <summary>
/// Supporting links for PSRule and rules modules are shown.
/// </summary>
SupportLinks = 4,

Default = Title | Source | SupportLinks,
Minimal = Source
}
}
28 changes: 28 additions & 0 deletions src/PSRule/Configuration/OutputOption.cs
Expand Up @@ -18,10 +18,12 @@ public sealed class OutputOption : IEquatable<OutputOption>
private const OutputFormat DEFAULT_FORMAT = OutputFormat.None;
private const RuleOutcome DEFAULT_OUTCOME = RuleOutcome.Processed;
private const OutputStyle DEFAULT_STYLE = OutputStyle.Client;
private const BannerFormat DEFAULT_BANNER = BannerFormat.Default;

internal static readonly OutputOption Default = new OutputOption
{
As = DEFAULT_AS,
Banner = DEFAULT_BANNER,
Encoding = DEFAULT_ENCODING,
Format = DEFAULT_FORMAT,
Outcome = DEFAULT_OUTCOME,
Expand All @@ -31,6 +33,7 @@ public sealed class OutputOption : IEquatable<OutputOption>
public OutputOption()
{
As = null;
Banner = null;
Culture = null;
Encoding = null;
Format = null;
Expand All @@ -44,6 +47,7 @@ public OutputOption(OutputOption option)
return;

As = option.As;
Banner = option.Banner;
Culture = option.Culture;
Encoding = option.Encoding;
Format = option.Format;
Expand All @@ -61,6 +65,7 @@ public bool Equals(OutputOption other)
{
return other != null &&
As == other.As &&
Banner == other.Banner &&
Culture == other.Culture &&
Encoding == other.Encoding &&
Format == other.Format &&
Expand All @@ -75,6 +80,7 @@ public override int GetHashCode()
{
int hash = 17;
hash = hash * 23 + (As.HasValue ? As.Value.GetHashCode() : 0);
hash = hash * 23 + (Banner.HasValue ? Banner.Value.GetHashCode() : 0);
hash = hash * 23 + (Culture != null ? Culture.GetHashCode() : 0);
hash = hash * 23 + (Encoding.HasValue ? Encoding.Value.GetHashCode() : 0);
hash = hash * 23 + (Format.HasValue ? Format.Value.GetHashCode() : 0);
Expand All @@ -90,6 +96,7 @@ internal static OutputOption Combine(OutputOption o1, OutputOption o2)
var result = new OutputOption(o1)
{
As = o1.As ?? o2.As,
Banner = o1.Banner ?? o2.Banner,
Culture = o1.Culture ?? o2.Culture,
Encoding = o1.Encoding ?? o2.Encoding,
Format = o1.Format ?? o2.Format,
Expand All @@ -106,6 +113,15 @@ internal static OutputOption Combine(OutputOption o1, OutputOption o2)
[DefaultValue(null)]
public ResultFormat? As { get; set; }

/// <summary>
/// The information displayed for Assert-PSRule banner.
/// </summary>
[DefaultValue(null)]
public BannerFormat? Banner { get; set; }

/// <summary>
/// One or more cultures to use for generating output.
/// </summary>
[DefaultValue(null)]
public string[] Culture { get; set; }

Expand All @@ -121,6 +137,9 @@ internal static OutputOption Combine(OutputOption o1, OutputOption o2)
[DefaultValue(null)]
public OutputFormat? Format { get; set; }

/// <summary>
/// The outcome of rule results to return.
/// </summary>
[DefaultValue(null)]
public RuleOutcome? Outcome { get; set; }

Expand All @@ -130,6 +149,9 @@ internal static OutputOption Combine(OutputOption o1, OutputOption o2)
[DefaultValue(null)]
public string Path { get; set; }

/// <summary>
/// The style that results will be presented in.
/// </summary>
[DefaultValue(null)]
public OutputStyle? Style { get; set; }

Expand All @@ -138,6 +160,9 @@ internal void Load(EnvironmentHelper env)
if (env.TryEnum("PSRULE_OUTPUT_AS", out ResultFormat value))
As = value;

if (env.TryEnum("PSRULE_OUTPUT_BANNER", out BannerFormat banner))
Banner = banner;

if (env.TryStringArray("PSRULE_OUTPUT_CULTURE", out string[] culture))
Culture = culture;

Expand All @@ -162,6 +187,9 @@ internal void Load(Dictionary<string, object> index)
if (index.TryPopEnum("Output.As", out ResultFormat value))
As = value;

if (index.TryPopEnum("Output.Banner", out BannerFormat banner))
Banner = banner;

if (index.TryPopStringArray("Output.Culture", out string[] culture))
Culture = culture;

Expand Down
20 changes: 20 additions & 0 deletions src/PSRule/PSRule.psm1
Expand Up @@ -1108,6 +1108,11 @@ function New-PSRuleOption {
[ValidateSet('Detail', 'Summary')]
[PSRule.Configuration.ResultFormat]$OutputAs = 'Detail',

# Sets the Output.Banner option
[Parameter(Mandatory = $False)]
[ValidateSet('Default', 'Minimal', 'None', 'Title', 'Source', 'SupportLinks')]
[PSRule.Configuration.BannerFormat]$OutputBanner = 'Default',

# Sets the Output.Culture option
[Parameter(Mandatory = $False)]
[String[]]$OutputCulture,
Expand Down Expand Up @@ -1323,6 +1328,11 @@ function Set-PSRuleOption {
[ValidateSet('Detail', 'Summary')]
[PSRule.Configuration.ResultFormat]$OutputAs = 'Detail',

# Sets the Output.Banner option
[Parameter(Mandatory = $False)]
[ValidateSet('Default', 'Minimal', 'None', 'Title', 'Source', 'SupportLinks')]
[PSRule.Configuration.BannerFormat]$OutputBanner = 'Default',

# Sets the Output.Culture option
[Parameter(Mandatory = $False)]
[String[]]$OutputCulture,
Expand Down Expand Up @@ -1948,6 +1958,11 @@ function SetOptions {
[ValidateSet('Detail', 'Summary')]
[PSRule.Configuration.ResultFormat]$OutputAs = 'Detail',

# Sets the Output.Banner option
[Parameter(Mandatory = $False)]
[ValidateSet('Default', 'Minimal', 'None', 'Title', 'Source', 'SupportLinks')]
[PSRule.Configuration.BannerFormat]$OutputBanner = 'Default',

# Sets the Output.Culture option
[Parameter(Mandatory = $False)]
[String[]]$OutputCulture,
Expand Down Expand Up @@ -2080,6 +2095,11 @@ function SetOptions {
$Option.Output.As = $OutputAs;
}

# Sets option Output.As
if ($PSBoundParameters.ContainsKey('OutputBanner')) {
$Option.Output.Banner = $OutputBanner;
}

# Sets option Output.Culture
if ($PSBoundParameters.ContainsKey('OutputCulture')) {
$Option.Output.Culture = $OutputCulture;
Expand Down
13 changes: 11 additions & 2 deletions src/PSRule/Pipeline/AssertPipeline.cs
Expand Up @@ -93,7 +93,7 @@ protected AssertFormatterBase(Source[] source, IPipelineWriter writer, PSRuleOpt
Option = option;
Banner();
Source(source);
Help(source);
SupportLinks(source);
}

public void Error(ErrorRecord errorRecord)
Expand Down Expand Up @@ -185,6 +185,9 @@ protected virtual void Warning(string message)

protected void Banner()
{
if (!Option.Output.Banner.GetValueOrDefault(BannerFormat.Default).HasFlag(BannerFormat.Title))
return;

WriteLine(FormatterStrings.Banner.Replace("\\n", Environment.NewLine));
LineBreak();
}
Expand All @@ -203,6 +206,9 @@ protected void StartObject(InvokeResult result, out RuleRecord[] records, Consol

private void Source(Source[] source)
{
if (!Option.Output.Banner.GetValueOrDefault(BannerFormat.Default).HasFlag(BannerFormat.Source))
return;

var version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
WriteLineFormat(FormatterStrings.PSRuleVersion, version);
var list = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
Expand All @@ -217,8 +223,11 @@ private void Source(Source[] source)
LineBreak();
}

private void Help(Source[] source)
private void SupportLinks(Source[] source)
{
if (!Option.Output.Banner.GetValueOrDefault(BannerFormat.Default).HasFlag(BannerFormat.SupportLinks))
return;

WriteLine(OUTPUT_SEPARATOR_BAR);
WriteLine(FormatterStrings.HelpDocs);
WriteLine(FormatterStrings.HelpContribute);
Expand Down
1 change: 1 addition & 0 deletions src/PSRule/Pipeline/PipelineBuilder.cs
Expand Up @@ -168,6 +168,7 @@ public virtual IPipelineBuilder Configure(PSRuleOption option)
Option.Input.Format = Option.Input.Format ?? InputOption.Default.Format;
Option.Output = new OutputOption(option.Output);
Option.Output.Outcome = Option.Output.Outcome ?? OutputOption.Default.Outcome;
Option.Output.Banner = Option.Output.Banner ?? OutputOption.Default.Banner;
return this;
}

Expand Down

0 comments on commit fc09406

Please sign in to comment.