dotnet / command-line-api

Command line parsing, invocation, and rendering of terminal output.
https://github.com/dotnet/command-line-api/wiki
MIT License
3.42k stars 383 forks source link

Missing functionality from `Microsoft.Extensions.CommandLineUtils` #1431

Open dorssel opened 3 years ago

dorssel commented 3 years ago

Still available, but no longer developed, there is Microsoft.Extensions.CommandLineUtils. It has the option of specifying ExtendedHelpText, which is displayed at the end of the help for a (sub-)command. Where Description is the short one-liner displayed next to the list of available (sub-)commands, the ExtendedHelpText is the more detailed help text for the (sub-)command itself. For example:

> foo --help
...
Commands:
  bar  Perform bar (* this is the description *)

and

> foo bar --help
bar
  Perform bar (* this is the description *)

Usage:
  foo bar [options]

Options:
  ...

Bar will do blabla. The changes will be persistent. (* these lines are the ExtendedHelpText *)
Exactly one of the options '--option-x' or '--option-y' must be provided.
If the directory does not exist, it will be created.

But maybe I am missing something that is already in place for this?

John0King commented 3 years ago

the Microsoft.Extensions.CommandLineUtils is way easier for people to use, and System.CommandLine use model binding for option and args, but Microsoft.Extensions.CommandLineUtils can use specific variable to get value.

As a basic library in System namespace , it introduce more overhead and un-clear "value assignment" (and use reflection a lot), I don't know why you guys move away from Microsoft.Extensions.CommandLineUtils

and DragonFruit is something I like and hate , I like the idea and easy but not for "redirect to a generated entrypoint", and it's just a few line to put it your real Main method, I don't get why it prefer hide. Won't people ask why their app can run without a real entry point ?

jonsequitur commented 3 years ago

As a basic library in System namespace , it introduce more overhead and un-clear "value assignment" (and use reflection a lot)

A lot of people prefer a method call, hence the method binding approach. This can let you avoid configuring the parser directly, if you prefer. This was the idea behind DragonFruit. It's a matter of API style preference though, and we want to accommodate both.

Only the name-based matching approach uses reflection. The alternative CommandHandler.Create overloads do not, and are more performant because of that. The reflection-based ones offer the advantage of being a bit less verbose. We're discussing splitting these into a separate packages so that the distinction is easier to understand. A third approach, still in the experimental phase, uses source generators.

and DragonFruit is something I like and hate , I like the idea and easy but not for "redirect to a generated entrypoint", and it's just a few line to put it your real Main method, I don't get why it prefer hide. Won't people ask why their app can run without a real entry point ?

DragonFruit is an experiment in a simpler model for command line apps where you don't have to specifically define a parser. It depends on having a Main method and is incompatible with the use of top-level C#, but it works well if you like this style. A successor that uses top-level C# could be built using source generators.