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 use multiple verbs with example? #882

Closed joe-agent closed 1 year ago

joe-agent commented 1 year ago

Currently, I have a program which uses CommandLine.Option with a default verb (let say export) like below:

abc.exe --source bla bla --target bla bla

Now there is a new verb called polling with a parameters like below:

--interval 0:10:00

If the interval is specified in the export verb, then polling will be enabled in the export verb. If user does not want to run export & only want polling, the command line would look like:

abc.exe polling --interval 0:10:00

Can commandline library support this? If yes, can you share some example please? Thanks

P/S: I cannot find a Question section in this repo page. Please direct me to a correct forum/website for me to ask a question.

elgonzo commented 1 year ago

With this library, trying to realize this will be a bit awkward.

Remember, the default verb is export. Therefore,

abc.exe --interval 0:10:00

would be functionally equivalent to

abc.exe export --interval 0:10:00

However, if i understand you correctly, you want

abc.exe --interval 0:10:00

to behave like

abc.exe polling --interval 0:10:00

which isn't really abc.exe export --interval 0:10:00.

If the desired CLI semantics of the no-verb command being dependent on the presence of certain options is a must for you, you might perhaps look for another CLI library that's more suitable for this scenario. (It's not just the task of getting the logic to work. It's then also the task of producing meaningful and correct help output...) Sure, there are ways to "manually" manipulate the args array to make the desired CLI logic fit the library's behavior, but that's rather dirty and hackish and doesn't help with the help output anyways...

joe-agent commented 1 year ago

Thanks for the reply. Perhaps I need to clarify my example better. Here is what I am looking for:

If interval is specified in the default verb export like below:

abc.exe --source bla bla --target bla bla --interval 0:10:00

I expect the command line parser to run the export action using source, target parameters. Then it runs the polling action after that using the interval parameter

If the command line argument is written like:

abc.exe --interval 0:10:00

I expect the command line parser to throw an exception as the default verb is export. The source, target parameters are not provided & hence it throws an error.

When the command line argument is written as:

abc.exe polling --interval 0:10:00

then, the export action will not run. Instead only the polling action is excecuted.

Is my description above clear? Can it be done with commandline library? Thanks

elgonzo commented 1 year ago

abc.exe --interval 0:10:00 I expect the command line parser to throw an exception as the default verb is export.

Ah, okay. Does that mean, the options --source and --target are both required for the export command, or is only one of these required, or something else?

joe-agent commented 1 year ago

abc.exe --interval 0:10:00 I expect the command line parser to throw an exception as the default verb is export. the options --source and --target are both required for the export command

@elgonzo The statements above are correct. The --source & --target are needed for the export command

elgonzo commented 1 year ago

The --source & --target are needed for the export command

Then set the Required property on the [Option] attributes for --source and --target to true (https://github.com/commandlineparser/commandline/wiki/T_CommandLine_OptionAttribute#properties).

joe-agent commented 1 year ago

A final question about multiple verbs. Please direct me at the correct forum to post the questions:

Consider I have option called ExportOptions like below:

[Verb("export", HelpText = "bla")]
public class ExportOptions {
   [Option("source", Required = true)
   public string Source {get; set;}

   [Option("target", Required = true)
   public string Target {get; set;}

   ...
}

And I have another option called PollingOptions

[Verb("polling", HelpText = "bla")]
public class PollingOptions{
   [Option("source", Required = true)
   public string Source {get; set;}

   [Option("target", Required = true)
   public string Target {get; set;}

   [Option("interval", Required = true)
   public int Interval{get; set;}
   ...
}

There are too many duplicated properties in ExportOptions & PollingOptions What is the best way to refactor the properties without causing any issue to the commandlineparser library?

Any example is appreciated!

elgonzo commented 1 year ago

What is the best way to refactor the properties without causing any issue to the commandlineparser library?

Put them into an (abstract) base class, and let your ExportOptions and PollingOptions classes derive from it. This dotnetfiddle mentioned on the FAQ page of the wiki also utilizes this approach: https://dotnetfiddle.net/x54u8G

Please direct me at the correct forum to post the questions:

There is no dedicated discussion forum. Either ask here in the issue tracker or over on stackoverflow.com :-)

joe-agent commented 1 year ago

Thanks for your help & responses @elgonzo