Skip to content

Commit

Permalink
(GH-4374) Fix Frosting argument parsing
Browse files Browse the repository at this point in the history
* Add argument to Forsting integration tests
* Unify Scripting / Frosting Spectre.Console IRemainingArguments to CakeArguments parsing
* fixes #4374
  • Loading branch information
devlead committed Oct 23, 2024
1 parent 795eed0 commit 5fae5cf
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 49 deletions.
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"));
}
}

0 comments on commit 5fae5cf

Please sign in to comment.