diff --git a/src/Cake.Cli/Hosts/BuildScriptHost.cs b/src/Cake.Cli/Hosts/BuildScriptHost.cs index 7dd7ee1bc9..bb5d7309fc 100644 --- a/src/Cake.Cli/Hosts/BuildScriptHost.cs +++ b/src/Cake.Cli/Hosts/BuildScriptHost.cs @@ -1,10 +1,13 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Threading.Tasks; +using Cake.Cli.Infrastructure; using Cake.Core; +using Cake.Core.Configuration; using Cake.Core.Diagnostics; using Cake.Core.Scripting; @@ -22,13 +25,15 @@ public sealed class BuildScriptHost : BuildScriptHost /// The execution strategy. /// The context. /// The report printer. + /// The Cake Configuration. /// The log. public BuildScriptHost( ICakeEngine engine, IExecutionStrategy executionStrategy, ICakeContext context, ICakeReportPrinter reportPrinter, - ICakeLog log) : base(engine, executionStrategy, context, reportPrinter, log) + ICakeConfiguration configuration, + ICakeLog log) : base(engine, executionStrategy, context, reportPrinter, configuration, log) { } } @@ -44,6 +49,7 @@ public class BuildScriptHost : ScriptHost private readonly ICakeLog _log; private readonly IExecutionStrategy _executionStrategy; private readonly TContext _context; + private readonly ICakeConfiguration _configuration; /// /// Initializes a new instance of the class. @@ -52,17 +58,20 @@ public class BuildScriptHost : ScriptHost /// The execution strategy. /// The context. /// The report printer. + /// The Cake Configuration. /// The log. public BuildScriptHost( ICakeEngine engine, IExecutionStrategy executionStrategy, TContext context, ICakeReportPrinter reportPrinter, + ICakeConfiguration configuration, ICakeLog log) : base(engine, context) { _executionStrategy = executionStrategy; _context = context; _reportPrinter = reportPrinter; + _configuration = configuration; _log = log; } @@ -88,7 +97,8 @@ private async Task internalRunTargetAsync() { var report = await Engine.RunTargetAsync(_context, _executionStrategy, Settings).ConfigureAwait(false); - if (report != null && !report.IsEmpty) + var noReportEnabled = _configuration.GetValue(Constants.Settings.NoReport) ?? bool.FalseString; + if (report != null && !report.IsEmpty && !noReportEnabled.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { _reportPrinter.Write(report); } diff --git a/src/Cake.Cli/Infrastructure/Constants.cs b/src/Cake.Cli/Infrastructure/Constants.cs new file mode 100644 index 0000000000..78511d9e8c --- /dev/null +++ b/src/Cake.Cli/Infrastructure/Constants.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Cake.Cli.Infrastructure +{ + /// + /// Constants used by the Cake CLI. + /// + internal static class Constants + { + /// + /// Configuration key names for CLI settings. + /// + public static class Settings + { + /// + /// Configuration key for disabling the build report. + /// + public const string NoReport = "Settings_NoReport"; + } + } +} diff --git a/src/Cake.Cli/Infrastructure/RemainingArgsParser.cs b/src/Cake.Cli/Infrastructure/RemainingArgsParser.cs index 6e77155a0f..58466b859f 100644 --- a/src/Cake.Cli/Infrastructure/RemainingArgsParser.cs +++ b/src/Cake.Cli/Infrastructure/RemainingArgsParser.cs @@ -3,6 +3,7 @@ using System.Linq; using Cake.Core; using Spectre.Console.Cli; +using static Cake.Cli.Infrastructure.Constants; namespace Cake.Cli.Infrastructure { @@ -22,35 +23,58 @@ public static CakeArguments ToCakeArguments( this IRemainingArguments remainingArguments, string[] targets = null, Action>> preProcessArgs = null) + => remainingArguments.ToCakeArguments( + noReport: false, + targets: targets, + preProcessArgs: preProcessArgs); + + /// + /// Parses Spectre.Console to . + /// + /// The remainingArguments. + /// No report argument supplied. + /// The optional targets, i.e. if specified by command. + /// The optional pre-process arguments. + /// . + public static CakeArguments ToCakeArguments( + this IRemainingArguments remainingArguments, + bool noReport, + string[] targets = null, + Action>> preProcessArgs = null) { var arguments = new Dictionary>(StringComparer.OrdinalIgnoreCase); // Keep the actual remaining arguments in the cake arguments foreach (var group in remainingArguments.Parsed) { - string key = group.Key.TrimStart('-'); - arguments[key] = new List(); - foreach (var argument in group) - { - arguments[key].Add(argument); - } + arguments.TryAdd( + group.Key.TrimStart('-'), + [.. group]); } // Fixes #3291, We have to add arguments manually which are defined within the DefaultCommandSettings type. Those are not considered "as remaining" because they could be parsed const string targetArgumentName = "target"; - if (!arguments.ContainsKey(targetArgumentName)) + if (!arguments.TryGetValue(targetArgumentName, out List value)) { - arguments[targetArgumentName] = new List(); + arguments[targetArgumentName] = value = + []; } if (targets != null) { foreach (var target in targets) { - arguments[targetArgumentName].Add(target); + value.Add(target); } } + if (noReport) + { + arguments.TryAdd( + Settings.NoReport, + [bool.TrueString]); + } + preProcessArgs?.Invoke(arguments); var argumentLookUp = arguments.SelectMany(a => a.Value, Tuple.Create).ToLookup(a => a.Item1.Key, a => a.Item2); diff --git a/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs b/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs index 92fd1ac0e2..4f90895b04 100644 --- a/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs +++ b/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs @@ -81,7 +81,7 @@ public override int Execute(CommandContext context, DefaultCommandSettings setti private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings) { - return remainingArguments.ToCakeArguments(settings.Targets); + return remainingArguments.ToCakeArguments(settings.NoReport, settings.Targets); } private void InstallTools(ServiceProvider provider) diff --git a/src/Cake.Frosting/Internal/Commands/DefaultCommandSettings.cs b/src/Cake.Frosting/Internal/Commands/DefaultCommandSettings.cs index 210b29e70f..54ff5f039a 100644 --- a/src/Cake.Frosting/Internal/Commands/DefaultCommandSettings.cs +++ b/src/Cake.Frosting/Internal/Commands/DefaultCommandSettings.cs @@ -51,5 +51,9 @@ internal sealed class DefaultCommandSettings : CommandSettings [CommandOption("--info")] [Description("Displays additional information about Cake.")] public bool Info { get; set; } + + [CommandOption("--no-report")] + [Description("Prevent the display of the summary report at the end of Cake Execution.")] + public bool NoReport { get; set; } } } diff --git a/src/Cake/Commands/DefaultCommand.cs b/src/Cake/Commands/DefaultCommand.cs index 4e0d9b6fcc..66e50db63a 100644 --- a/src/Cake/Commands/DefaultCommand.cs +++ b/src/Cake/Commands/DefaultCommand.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -144,14 +144,16 @@ private int PerformBootstrapping(CommandContext context, DefaultCommandSettings private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings) { return remainingArguments.ToCakeArguments( + settings.NoReport, preProcessArgs: arguments => { // Fixes #4157, We have to add arguments manually which are defined within the DefaultCommandSettings type. Those are not considered "as remaining" because they could be parsed const string recompileArgumentName = Infrastructure.Constants.Cache.InvalidateScriptCache; - if (settings.Recompile && !arguments.ContainsKey(recompileArgumentName)) + if (settings.Recompile) { - arguments[recompileArgumentName] = new List(); - arguments[recompileArgumentName].Add(true.ToString()); + arguments.TryAdd( + recompileArgumentName, + [true.ToString()]); } }); } diff --git a/src/Cake/Commands/DefaultCommandSettings.cs b/src/Cake/Commands/DefaultCommandSettings.cs index c2a12e2628..cdc111d48e 100644 --- a/src/Cake/Commands/DefaultCommandSettings.cs +++ b/src/Cake/Commands/DefaultCommandSettings.cs @@ -102,5 +102,12 @@ public sealed class DefaultCommandSettings : CommandSettings [CommandOption("--" + Infrastructure.Constants.Cache.InvalidateScriptCache)] [Description("Forces the script to be recompiled if caching is enabled.")] public bool Recompile { get; set; } + + /// + /// Gets or sets a value indicating whether to display report summary at the end of Cake execution. + /// + [CommandOption("--" + Infrastructure.Constants.CakeExecution.NoReport)] + [Description("Prevent the display of the summary report at the end of Cake Execution.")] + public bool NoReport { get; set; } } } diff --git a/src/Cake/Infrastructure/Constants.cs b/src/Cake/Infrastructure/Constants.cs index 7268826672..0741ac247d 100644 --- a/src/Cake/Infrastructure/Constants.cs +++ b/src/Cake/Infrastructure/Constants.cs @@ -10,6 +10,7 @@ public static class Settings { public const string EnableScriptCache = "Settings_EnableScriptCache"; public const string UseSpectreConsoleForConsoleOutput = "Settings_UseSpectreConsoleForConsoleOutput"; + public const string NoReport = "Settings_NoReport"; } public static class Paths @@ -21,5 +22,10 @@ public static class Cache { public const string InvalidateScriptCache = "invalidate-script-cache"; } + + public static class CakeExecution + { + public const string NoReport = "no-report"; + } } }