commandline icon indicating copy to clipboard operation
commandline copied to clipboard

Parameters based on condition

Open giovannigambino1980 opened this issue 4 years ago • 3 comments

Hi, I would to know if it's possibile to configure this kind of commands:

--onmatch move "c:\destination\path"
--onmatch copy "c:\destination\path"
--onmatch ignore

I mean, if with onmatch parameter I specify the enum move or copy, then I also need to fill a required path parameter. On ignore, do nothing...

I know I could reach the goal changing the commands as:

--onmatchcopyto "c:\destination\path" 
--onmatchmoveto "c:\destination\path"

in mutual exclusion, but I would to know if it's possibile to implement as in the first example.

Tnx, Giovanni

giovannigambino1980 avatar Oct 31 '21 09:10 giovannigambino1980

The first example would be a bit tricky to implement, since you're essentially using a verb within an option. Without knowing the structure of the rest of your commands, I'd recommend using an onmatch verb with mutually exclusive --move, --copy, and --ignore options:

onmatch --move "c:\destination\path"
onmatch --copy "c:\destination\path"
onmatch --ignore

The implementation of the verb would look similar to this:

[Verb("onmatch")]
public class OnMatch
{
    [Option("move",
            SetName = "flag")]
    public string Move { get; set; }

    [Option("copy",
            SetName = "flag")]
    public string Copy { get; set; }

    [Option("ignore",
            SetName = "flag")]
    public bool Ignore { get; set; }
}

If you can't change the command syntax, you could implement your first example by checking if the --onmatch option was specified, then parse your arguments again using move, copy, and ignore as subverbs, similar to my answer here.

Code snippet from the link:

[Verb("tool")]
public class Tool
{
    [Verb("install")]
    public class Install { }

    [Verb("uninstall")]
    public class Uninstall { }

    public static int ParseTool(Tool options, string[] args)
    {
        args = args.Skip(1).ToArray();

        var result = CommandLine.Parser.Default.ParseArguments(args, typeof(Install), typeof(Uninstall));
        var exitCode = result.MapResult(
            (Install opts) => ExecuteToolInstall(opts),
            (Uninstall opts) => ExecuteToolUninstall(opts),
            errs => HandleErrors(errs));

        return exitCode;
    }
}

mhbarnes avatar Nov 02 '21 20:11 mhbarnes

Hi, tnx you all for answering. Sorry if I forgot to say that I'm already using the verbs. I'll try to explain to you a full example of what I would to realize. Let's suppose I've:

  • action, an enum:ignore, copy, move
  • onmatch: makes an internal check, then uses the action to make something else (i.e. copy the file somewhere, ...)
  • onerror: if some error happens then its own action will move, copy or ignore the file in error.
  • inputfiles: the files to process

I would realize something like this:

myapp.exe checkfile --onmatch copy "destinationfolder" --onerror move "rejectedfolder" --inputfiles a, b, c, d....

or if I just want to run a simulation, without move or copy the files

myapp.exe checkfile --onmatch ignore --onerror ignore --inputfiles a, b, c, d....

Do you think it's possible to do it?

p.s. I got your example. Cool! I try to think commands in a different way.

Thank so much again, Giovanni

giovannigambino1980 avatar Nov 03 '21 17:11 giovannigambino1980

I got your example. Cool! I try to think commands in a different way.

Seems like you're on the right track. One possibility is to use string[] for --onmatch and --onerror, and do some input handling and set the maximum number of items to 2 (see Option Attribute on the Wiki).

Also, you could implement it so "ignore" is the default option for --onmatch and --onerror if you wanted to make your interface more succinct.

Best of luck.

mhbarnes avatar Nov 04 '21 00:11 mhbarnes