commandlineparser / commandline

The best C# command line parser that brings standardized *nix getopt style, for .NET. Includes F# support
MIT License
4.46k stars 473 forks source link

How to pass and retain subsequent arguments to a verb with exact format? #902

Open HofmeisterAn opened 9 months ago

HofmeisterAn commented 9 months ago

I am trying to create a verb that includes all subsequent arguments. I require it to retain the exact format in which it is passed to the verb. My intention is to forward the arguments as a shell command. I have tried the following configuration:

[Verb("foreach")]
public readonly struct ForeachVerb
{
    [Value(0)]
    public IEnumerable<string> Command { get; set; }
}

But unfortunately, I am encountering errors indicating that options f, foo, and bar are missing for this test argument:

foreach foo bar baz -f true --foo --bar 1

As a workaround, I can fall back to the original args, but I am curious if there is any chance to utilize the capabilities that CommandLineParser offers. Does anyone have an idea on how to configure CommandLineParser to achieve this?

SJFriedl commented 9 months ago

You're basically asking for everything after the verb to be included in the Command property, with no more parsing of dashes and the like?

HofmeisterAn commented 9 months ago

You're basically asking for everything after the verb to be included in the Command property, with no more parsing of dashes and the like?

✅ Yes, exactly.

SJFriedl commented 9 months ago

I've never seen a mechanism like this, but it would be serviced deep in the tokenizer if it were there.

My guess is the best you can do is put the whole expression in quotes, and then tokenize it yourself as a single Value

HofmeisterAn commented 9 months ago

My guess is the best you can do is put the whole expression in quotes, and then tokenize it yourself as a single Value

I have also thought of that, or simply use a verb without any options at all (to detect the command) and fallback to the original args object that is passed to the binary, thanks.

SJFriedl commented 9 months ago

Alternately, do the check prior to even calling the parser:

public static int Main(string [] args)
{
    if (args[0] == "foreach")
    {
        //  special processing
    }
    else
    {
        // usual Parser.Default.ParseArguments(args, ...) stuff
    }