From 0da7e641f17a8f6459ed02ac4c6304829d244456 Mon Sep 17 00:00:00 2001
From: Frank Ray <52075808+FrankRay78@users.noreply.github.com>
Date: Tue, 24 Oct 2023 15:34:04 +0100
Subject: [PATCH] Within Cake.Commands.DefaultCommand.Execute(...), explicitly
create the CakeArguments from CommandContext.Remaining, adding in the
DefaultCommandSettings.Recompile flag, if necessary. Follows the same pattern
already established in Cake.Frosting.Internal.DefaultCommand
---
src/Cake.Cli/Cake.Cli.csproj | 4 +--
.../Internal/Commands/DefaultCommand.cs | 2 +-
.../Fixtures/BuildFeatureFixture.cs | 11 ++++--
src/Cake.Tests/Unit/ProgramTests.cs | 8 ++---
.../Utilities/TestContainerConfigurator.cs | 4 +--
src/Cake/Commands/DefaultCommand.cs | 35 +++++++++++++++++--
.../Bootstrapping/BootstrapFeature.cs | 4 +--
src/Cake/Features/Building/BuildFeature.cs | 6 ++--
src/Cake/Features/CakeFeature.cs | 6 ++--
.../Infrastructure/ContainerConfigurator.cs | 4 +--
.../Infrastructure/IContainerConfigurator.cs | 4 +--
11 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/src/Cake.Cli/Cake.Cli.csproj b/src/Cake.Cli/Cake.Cli.csproj
index 48b5859f13..64a6fd31e2 100644
--- a/src/Cake.Cli/Cake.Cli.csproj
+++ b/src/Cake.Cli/Cake.Cli.csproj
@@ -19,7 +19,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs b/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs
index cce55ad5de..6a172970a2 100644
--- a/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs
+++ b/src/Cake.Frosting/Internal/Commands/DefaultCommand.cs
@@ -82,6 +82,7 @@ public override int Execute(CommandContext context, DefaultCommandSettings setti
private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings)
{
var arguments = new Dictionary>(StringComparer.OrdinalIgnoreCase);
+
// Keep the actual remaining arguments in the cake arguments
foreach (var group in remainingArguments.Parsed)
{
@@ -98,7 +99,6 @@ private static CakeArguments CreateCakeArguments(IRemainingArguments remainingAr
{
arguments[targetArgumentName] = new List();
}
-
foreach (var target in settings.Targets)
{
arguments[targetArgumentName].Add(target);
diff --git a/src/Cake.Tests/Fixtures/BuildFeatureFixture.cs b/src/Cake.Tests/Fixtures/BuildFeatureFixture.cs
index 4c28658bc1..a17c879381 100644
--- a/src/Cake.Tests/Fixtures/BuildFeatureFixture.cs
+++ b/src/Cake.Tests/Fixtures/BuildFeatureFixture.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Text;
using Cake.Core;
using Cake.Core.Composition;
@@ -63,7 +65,10 @@ public BuildFeatureFixture(
public BuildFeatureFixtureResult Run(BuildFeatureSettings settings, IDictionary arguments = null)
{
- var remaining = new FakeRemainingArguments(arguments);
+ var parsed = (arguments ?? new Dictionary())
+ .ToLookup(x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase);
+
+ var remaining = new CakeArguments(parsed);
var exitCode = ((IBuildFeature)this).Run(remaining, settings);
return new BuildFeatureFixtureResult
@@ -88,7 +93,7 @@ private string GetDefaultScriptContent()
return builder.ToString();
}
- int IBuildFeature.Run(IRemainingArguments arguments, BuildFeatureSettings settings)
+ int IBuildFeature.Run(ICakeArguments arguments, BuildFeatureSettings settings)
{
var feature = new BuildFeature(FileSystem, Environment, Bootstrapper, ModuleSearcher, Log);
return feature.Run(arguments, settings);
diff --git a/src/Cake.Tests/Unit/ProgramTests.cs b/src/Cake.Tests/Unit/ProgramTests.cs
index 34ceaf2dc1..704bf94cd0 100644
--- a/src/Cake.Tests/Unit/ProgramTests.cs
+++ b/src/Cake.Tests/Unit/ProgramTests.cs
@@ -27,7 +27,7 @@ public async Task Should_Use_Default_Parameters_By_Default()
// Then
feature.Received(1).Run(
- Arg.Any(),
+ Arg.Any(),
Arg.Is(settings =>
settings.BuildHostKind == BuildHostKind.Build &&
settings.Debug == false &&
@@ -53,7 +53,7 @@ public async Task The_DryRun_Option_Should_Perform_A_Dry_Run_Of_Script(params st
// Then
feature.Received(1).Run(
- Arg.Any(),
+ Arg.Any(),
Arg.Is(settings =>
settings.BuildHostKind == BuildHostKind.DryRun));
}
@@ -73,7 +73,7 @@ public async Task The_Tree_Option_Should_Show_The_Script_Tree(params string[] ar
// Then
feature.Received(1).Run(
- Arg.Any(),
+ Arg.Any(),
Arg.Is(settings =>
settings.BuildHostKind == BuildHostKind.Tree));
}
@@ -93,7 +93,7 @@ public async Task The_Description_Option_Should_Show_Script_Descriptions(params
// Then
feature.Received(1).Run(
- Arg.Any(),
+ Arg.Any(),
Arg.Is(settings =>
settings.BuildHostKind == BuildHostKind.Description));
}
diff --git a/src/Cake.Tests/Utilities/TestContainerConfigurator.cs b/src/Cake.Tests/Utilities/TestContainerConfigurator.cs
index 9c4dcfd5ea..8e419295d0 100644
--- a/src/Cake.Tests/Utilities/TestContainerConfigurator.cs
+++ b/src/Cake.Tests/Utilities/TestContainerConfigurator.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
+using Cake.Core;
using Cake.Core.Composition;
using Cake.Core.Configuration;
using Cake.Infrastructure;
-using Spectre.Console.Cli;
namespace Cake.Tests.Fakes
{
@@ -21,7 +21,7 @@ public TestContainerConfigurator()
public void Configure(
ICakeContainerRegistrar registrar,
ICakeConfiguration configuration,
- IRemainingArguments arguments)
+ ICakeArguments arguments)
{
_decorated.Configure(registrar, configuration, arguments);
diff --git a/src/Cake/Commands/DefaultCommand.cs b/src/Cake/Commands/DefaultCommand.cs
index eafcfa72cf..9b860e4c38 100644
--- a/src/Cake/Commands/DefaultCommand.cs
+++ b/src/Cake/Commands/DefaultCommand.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Collections.Generic;
using System.Linq;
using Cake.Cli;
using Cake.Core;
@@ -69,8 +70,10 @@ public override int Execute(CommandContext context, DefaultCommandSettings setti
}
}
+ var arguments = CreateCakeArguments(context.Remaining, settings);
+
// Run the build feature.
- return _builder.Run(context.Remaining, new BuildFeatureSettings(host)
+ return _builder.Run(arguments, new BuildFeatureSettings(host)
{
Script = settings.Script,
Verbosity = settings.Verbosity,
@@ -110,11 +113,39 @@ private int PerformBootstrapping(CommandContext context, DefaultCommandSettings
return 0;
}
- return _bootstrapper.Run(context.Remaining, new BootstrapFeatureSettings
+ var arguments = CreateCakeArguments(context.Remaining, settings);
+
+ return _bootstrapper.Run(arguments, new BootstrapFeatureSettings
{
Script = settings.Script,
Verbosity = settings.Verbosity
});
}
+
+ private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings)
+ {
+ var arguments = new Dictionary>(StringComparer.OrdinalIgnoreCase);
+
+ // Keep the actual remaining arguments in the cake arguments
+ foreach (var group in remainingArguments.Parsed)
+ {
+ arguments[group.Key] = new List();
+ foreach (var argument in group)
+ {
+ arguments[group.Key].Add(argument);
+ }
+ }
+
+ // 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))
+ {
+ arguments[recompileArgumentName] = new List();
+ arguments[recompileArgumentName].Add(true.ToString());
+ }
+
+ var argumentLookUp = arguments.SelectMany(a => a.Value, Tuple.Create).ToLookup(a => a.Item1.Key, a => a.Item2);
+ return new CakeArguments(argumentLookUp);
+ }
}
}
diff --git a/src/Cake/Features/Bootstrapping/BootstrapFeature.cs b/src/Cake/Features/Bootstrapping/BootstrapFeature.cs
index c3f355b94c..4c1b666c7b 100644
--- a/src/Cake/Features/Bootstrapping/BootstrapFeature.cs
+++ b/src/Cake/Features/Bootstrapping/BootstrapFeature.cs
@@ -17,7 +17,7 @@ namespace Cake.Features.Bootstrapping
{
public interface IBootstrapFeature
{
- int Run(IRemainingArguments arguments, BootstrapFeatureSettings settings);
+ int Run(ICakeArguments arguments, BootstrapFeatureSettings settings);
}
public sealed class BootstrapFeature : Feature, IBootstrapFeature
@@ -32,7 +32,7 @@ public BootstrapFeature(
_environment = environment;
}
- public int Run(IRemainingArguments arguments, BootstrapFeatureSettings settings)
+ public int Run(ICakeArguments arguments, BootstrapFeatureSettings settings)
{
// Fix the script path.
settings.Script = settings.Script ?? new FilePath("build.cake");
diff --git a/src/Cake/Features/Building/BuildFeature.cs b/src/Cake/Features/Building/BuildFeature.cs
index 1dd9b82fc6..4a8fa4ec40 100644
--- a/src/Cake/Features/Building/BuildFeature.cs
+++ b/src/Cake/Features/Building/BuildFeature.cs
@@ -21,7 +21,7 @@ namespace Cake.Features.Building
{
public interface IBuildFeature
{
- int Run(IRemainingArguments arguments, BuildFeatureSettings settings);
+ int Run(ICakeArguments arguments, BuildFeatureSettings settings);
}
public sealed class BuildFeature : Feature, IBuildFeature
@@ -42,7 +42,7 @@ public BuildFeature(
_log = log;
}
- public int Run(IRemainingArguments arguments, BuildFeatureSettings settings)
+ public int Run(ICakeArguments arguments, BuildFeatureSettings settings)
{
using (new ScriptAssemblyResolver(_environment, _log))
{
@@ -50,7 +50,7 @@ public int Run(IRemainingArguments arguments, BuildFeatureSettings settings)
}
}
- private int RunCore(IRemainingArguments arguments, BuildFeatureSettings settings)
+ private int RunCore(ICakeArguments arguments, BuildFeatureSettings settings)
{
// Fix the script path.
settings.Script = settings.Script ?? new FilePath("build.cake");
diff --git a/src/Cake/Features/CakeFeature.cs b/src/Cake/Features/CakeFeature.cs
index c9eee80edd..3d47f8bc88 100644
--- a/src/Cake/Features/CakeFeature.cs
+++ b/src/Cake/Features/CakeFeature.cs
@@ -33,7 +33,7 @@ public Feature(
protected IContainer CreateScope(
ICakeConfiguration configuration,
- IRemainingArguments arguments,
+ ICakeArguments arguments,
Action action = null)
{
var registrar = new AutofacTypeRegistrar(new ContainerBuilder());
@@ -45,10 +45,10 @@ protected IContainer CreateScope(
}
protected ICakeConfiguration ReadConfiguration(
- IRemainingArguments remaining, DirectoryPath root)
+ ICakeArguments arguments, DirectoryPath root)
{
var provider = new CakeConfigurationProvider(_fileSystem, _environment);
- var args = remaining.Parsed.ToDictionary(x => x.Key, x => x.FirstOrDefault() ?? string.Empty);
+ var args = arguments.GetArguments().ToDictionary(x => x.Key, x => x.Value?.FirstOrDefault() ?? string.Empty);
return provider.CreateConfiguration(root, args);
}
diff --git a/src/Cake/Infrastructure/ContainerConfigurator.cs b/src/Cake/Infrastructure/ContainerConfigurator.cs
index e817a84cff..f2c4f59d4e 100644
--- a/src/Cake/Infrastructure/ContainerConfigurator.cs
+++ b/src/Cake/Infrastructure/ContainerConfigurator.cs
@@ -24,10 +24,10 @@ public sealed class ContainerConfigurator : IContainerConfigurator
public void Configure(
ICakeContainerRegistrar registrar,
ICakeConfiguration configuration,
- IRemainingArguments arguments)
+ ICakeArguments arguments)
{
// Arguments
- registrar.RegisterInstance(new CakeArguments(arguments.Parsed)).AsSelf().As();
+ registrar.RegisterInstance(arguments).AsSelf().As();
// Scripting
registrar.RegisterType().As().Singleton();
diff --git a/src/Cake/Infrastructure/IContainerConfigurator.cs b/src/Cake/Infrastructure/IContainerConfigurator.cs
index 3548c7bfec..41e5a07ef1 100644
--- a/src/Cake/Infrastructure/IContainerConfigurator.cs
+++ b/src/Cake/Infrastructure/IContainerConfigurator.cs
@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Cake.Core;
using Cake.Core.Composition;
using Cake.Core.Configuration;
-using Spectre.Console.Cli;
namespace Cake.Infrastructure
{
@@ -17,6 +17,6 @@ public interface IContainerConfigurator
void Configure(
ICakeContainerRegistrar registrar,
ICakeConfiguration configuration,
- IRemainingArguments arguments);
+ ICakeArguments arguments);
}
}