Skip to content

Instantly share code, notes, and snippets.

@baronfel
Created June 10, 2022 21:11
Show Gist options
  • Save baronfel/9da0fb9e5368735586c5426d34539031 to your computer and use it in GitHub Desktop.
Save baronfel/9da0fb9e5368735586c5426d34539031 to your computer and use it in GitHub Desktop.
SCL multiple array arguments problem
>dotnet run a b c
got 2 tokens, no dashes
got 1 tokens
Sln: <null>
Forwarded:
b
c
Inline Run:
c
// I expected to see that Forwarded was a, b, c, instead got
// [ test [ sln <> ] [ adapter-args <b> <c> ] [ inline-run-settings <c> ] ]
using System.CommandLine;
using System.CommandLine.Completions;
using System.CommandLine.Parsing;
using System.CommandLine.Builder;
new CommandLineBuilder(new TestCommand())
.UseParseDirective()
.UseSuggestDirective()
.Build()
.InvokeAsync(args);
class TestCommand : Command
{
private static ParseArgument<string?> IsProjectOrSln =
(ctx) =>
{
if (ctx.Tokens.Count == 0)
{
ctx.OnlyTake(0);
return null;
}
else
{
var ext = System.IO.Path.GetExtension(ctx.Tokens[0].Value);
if (ext.EndsWith("proj") || ext.EndsWith(".sln"))
{
ctx.OnlyTake(1);
return ctx.Tokens[0].Value;
}
else
{
ctx.OnlyTake(0);
return null;
}
}
};
public static readonly Argument<string?> SlnOrProjectArgument = new Argument<string?>("sln", parse: IsProjectOrSln)
{
Arity = ArgumentArity.ZeroOrOne
};
private static ParseArgument<string[]?> ParseUntilFirstDoubleDash =
(ctx) =>
{
if (ctx.Tokens.Count == 0)
{
ctx.OnlyTake(0);
return null;
}
var doubleDashIndex = ctx.Tokens.ToList().FindIndex((Token item) => item.Value.Equals("=="));
if (doubleDashIndex is -1)
{
Console.WriteLine($"got {ctx.Tokens.Count} tokens, no dashes");
ctx.OnlyTake(ctx.Tokens.Count);
return ctx.Tokens.Select(token => token.Value).ToArray();
}
else
{
Console.WriteLine($"got {ctx.Tokens.Count} tokens, dash at {doubleDashIndex}");
ctx.OnlyTake(doubleDashIndex + 1);
return ctx.Tokens.Take(doubleDashIndex + 1).Select(token => token.Value).ToArray();
}
};
public static readonly Argument<string[]?> ForwardedArgs = new("adapter-args", parse: ParseUntilFirstDoubleDash)
{
Arity = ArgumentArity.ZeroOrMore
};
public static readonly Argument<string[]?> InlineRunSettings = new("inline-run-settings", parse: (ctx) =>
{
Console.WriteLine($"got {ctx.Tokens.Count} tokens");
return ctx.Tokens.Select(t => t.Value).ToArray();
})
{
Arity = ArgumentArity.ZeroOrMore
};
public TestCommand() : base("test", "do the testy") {
this.Add(SlnOrProjectArgument);
this.Add(ForwardedArgs);
this.Add(InlineRunSettings);
this.SetHandler((sln, forward, run) => {
Console.WriteLine($"Sln:\t{sln ?? "<null>"}");
Console.WriteLine("Forwarded:");
foreach (var arg in forward ?? Array.Empty<string>()) {
Console.WriteLine($"\t{arg}");
}
Console.WriteLine("Inline Run:");
foreach (var arg in run ?? Array.Empty<string>()) {
Console.WriteLine($"\t{arg}");
}
}, SlnOrProjectArgument, ForwardedArgs, InlineRunSettings);
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>scl_dynamic_completion</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment