commandline icon indicating copy to clipboard operation
commandline copied to clipboard

Global parameters before verbs

Open Strongleong opened this issue 3 years ago • 1 comments

So I want to do something like this:

$ app.exe <path-to-the-file> <verb> <options>

First argument is a value, and I want to make it global for every verb in app. For now it is implemented like this:

abstract class BaseOptions
{
  [Value(0)]
  public string file { get; set; }
}

[Verb("verb1")]
class Verb1Options : BaseOptions
{
  [Option('a', "verb-1-option")]
  public bool a{ get; set; }
  
  [Option('b', "verb-1-another-option")]
  public bool a{ get; set; }
}

[Verb("verb2")]
class Verb2Options : BaseOptions
{
  [Option('c', "verb-2-option")]
  public bool c{ get; set; }
}

But the issue is first goes verb then value. I need in reverse Can I do it?

Strongleong avatar Jan 13 '22 07:01 Strongleong

Done it with VERY hacky way:

public int Run(string[] args)
{
    var parser = new Parser(with =>
    {
        with.HelpWriter = null;
        with.CaseInsensitiveEnumValues = true;
    });

    // Default parsing with verb as first arg
    var result = parser.ParseArguments<Verb1Options, Verb2Options>(args);
    return result.MapResult(
        (Verb1Options options) => RunVerb1(options),
        (Verb1Options options) => RunVerb2(options),
        errors => ParseFirstArgNotVerb(args, parser) // if first arg is not verb it is must be file path
    );
}

private int ParseFirstArgNotVerb(string[] args, Parser parser)
{
    // if no verb specified print help message
    if (args.Length == 1) {
        List<string> _args = new List<string>(args);
        _args.Add("help");
        args = _args.ToArray();
    }

    // Just make verb firts lol
    if (!new List<string>() { "help", "--help", "version", "--version" }.Contains(args[0]))
    {
        var temp = args[0];
        args[0] = args[1];
        args[1] = temp;
    }

    var result = parser.ParseArguments<BaseOptions, AddOptions, RemoveOptions, RenameOptions, ExtractOptions, ListOptions>(args);
    return result.MapResult(
        (Verb1Options options) => RunVerb1(options),
        (Verb1Options options) => RunVerb2(options),
        errors => DisplayHelp(result, errors)
   );
}

So basically app checks if first arg is verb (normal input).

$ app.exe <verb> <path-to-the-file> <options>

If it is app works normally, but if isn't it swaps first two arguments and checks again.

Kinda working but I think it needs to be done with the lib

Strongleong avatar Jan 13 '22 07:01 Strongleong