Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH4374: Fix Frosting argument parsing #4375

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@ Task("Frosting-Integration-Tests")

DotNetRun(test.Project.FullPath,
new ProcessArgumentBuilder()
.AppendSwitchQuoted("--verbosity", "=", "quiet"),
.AppendSwitchQuoted("--verbosity", "=", "quiet")
.AppendSwitchQuoted("--name", "=", "world"),
new DotNetRunSettings
{
Configuration = parameters.Configuration,
Expand Down
60 changes: 60 additions & 0 deletions src/Cake.Cli/Infrastructure/RemainingArgsParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cake.Core;
using Spectre.Console.Cli;

namespace Cake.Cli.Infrastructure
{
/// <summary>
/// Spectre.Console <see cref="IRemainingArguments"/> extensions.
/// </summary>
public static class IRemainingArgumentsExtensions
{
/// <summary>
/// Parses Spectre.Console <see cref="IRemainingArguments"/> to <see cref="CakeArguments"/>.
/// </summary>
/// <param name="remainingArguments">The remainingArguments.</param>
/// <param name="targets">The optional targets, i.e. if specified by command.</param>
/// <param name="preProcessArgs">The optional pre-process arguments.</param>
/// <returns><see cref="CakeArguments"/>.</returns>
public static CakeArguments ToCakeArguments(
this IRemainingArguments remainingArguments,
string[] targets = null,
Action<IDictionary<string, List<string>>> preProcessArgs = null)
{
var arguments = new Dictionary<string, List<string>>(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<string>();
foreach (var argument in group)
{
arguments[key].Add(argument);
}
}

// 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))
{
arguments[targetArgumentName] = new List<string>();
}

if (targets != null)
{
foreach (var target in targets)
{
arguments[targetArgumentName].Add(target);
}
}

preProcessArgs?.Invoke(arguments);

var argumentLookUp = arguments.SelectMany(a => a.Value, Tuple.Create).ToLookup(a => a.Item1.Key, a => a.Item2);
return new CakeArguments(argumentLookUp);
}
}
}
27 changes: 2 additions & 25 deletions src/Cake.Frosting/Internal/Commands/DefaultCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using Cake.Cli;
using Cake.Cli.Infrastructure;
using Cake.Core;
using Cake.Core.Diagnostics;
using Cake.Core.IO;
Expand Down Expand Up @@ -81,31 +82,7 @@ public override int Execute(CommandContext context, DefaultCommandSettings setti

private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings)
{
var arguments = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);

// Keep the actual remaining arguments in the cake arguments
foreach (var group in remainingArguments.Parsed)
{
arguments[group.Key] = new List<string>();
foreach (var argument in group)
{
arguments[group.Key].Add(argument);
}
}

// 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))
{
arguments[targetArgumentName] = new List<string>();
}
foreach (var target in settings.Targets)
{
arguments[targetArgumentName].Add(target);
}

var argumentLookUp = arguments.SelectMany(a => a.Value, Tuple.Create).ToLookup(a => a.Item1.Key, a => a.Item2);
return new CakeArguments(argumentLookUp);
return remainingArguments.ToCakeArguments(settings.Targets);
}

private void InstallTools(ServiceProvider provider)
Expand Down
33 changes: 11 additions & 22 deletions src/Cake/Commands/DefaultCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using Cake.Cli;
using Cake.Cli.Infrastructure;
using Cake.Core;
using Cake.Core.Diagnostics;
using Cake.Features.Bootstrapping;
Expand Down Expand Up @@ -124,29 +125,17 @@ private int PerformBootstrapping(CommandContext context, DefaultCommandSettings

private static CakeArguments CreateCakeArguments(IRemainingArguments remainingArguments, DefaultCommandSettings settings)
{
var arguments = new Dictionary<string, List<string>>(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<string>();
foreach (var argument in group)
return remainingArguments.ToCakeArguments(
preProcessArgs: arguments =>
{
arguments[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<string>();
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);
// 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<string>();
arguments[recompileArgumentName].Add(true.ToString());
}
});
}
}
}
3 changes: 2 additions & 1 deletion tests/integration/Cake.Frosting/build/Tasks/Hello.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Cake.Common;
using Cake.Common.Diagnostics;
using Cake.Frosting;

Expand All @@ -6,6 +7,6 @@ public sealed class Hello : FrostingTask<Context>
{
public override void Run(Context context)
{
context.Information("Hello World");
context.Information("Hello {0}", context.Argument<string>("name"));
}
}
Loading