Skip to content

Initial thoughts on generation #1829

Open
@KathleenDollard

Description

@KathleenDollard

@davidfowl

Here is the shape we are considering - very early thoughts.

An entry point in the System.CommandLine namespace or package namespace that is currently named ParserBuilder because an preliminary user study identified that some folks that are do not plan subcommands associate "Command" with that and think something named "Command" is the wrong choice. Also, argparse in Python makes folks with that background think parser.

To create the parser:

  • ParserBuilder.CreateFromMethod(<delegate as method group>) This evaluates the method, its attributes, parameter attributes and XmlComments to gather information for the command. You can also access the command after it is created. This is great for simple one level CLIs and would replace DragonFruit without using reflection.
  • ParserBuilder.CreateFromMethods(<tree, with node types to guide creation and delegates as method groups>) Multi-level CLIs only differ from the single level in that the programmer needs to define the relationship between the methods. This method explicitly does that.
  • ParserBuilder.CreateFromType(<type>) Some folks work on really big CLIs with more options than anyone would want to see as method parameters. This approach is very similar to CreateFromMethod, except it uses type properties and possibly fields.
  • ParserBuilder.CreateFromLambda(<delegate as lambda>) Similar to the above (although generation may be more problematic in imperfect code)
  • ParserBuilder.Create() With this approach, the user would explicitly add subcommands, options and arguments. There is more flexibility in the code that is run with this approach.

The resulting parser is a wrapper for System.CommandLine.Command and offers strongly typed access to the tree. IOW, this is valid for a StarTrek parser:

var janewayOption = pb.NextGeneration.Voyager.Janeway;

We are still looking at the relationship between parsing and invocation. System.CommandLine supplies a bunch of features via this pipeline (most things except validation). The simple case is very simple:

var pb = ParserBuilder.CreateFromMethod(Greet);   // Greet is a method with descriptions in XML comments
return pb.Invoke();  // If args are not specified Environment.CommandLineArgs is used. 

Note that this and the Greet method is the entire application.

Finding args in Top level statement apps not obvious, thus the default to Environment... When folks are using old-style apps, they will want to know where to put the args, so that overload also exists.

If you just want to get the results, and then switch on them, strongly typed results are provided via GetResults.

If you are interested in customizing the pipeline (including removing things from it) I would like to know the scenario to plan how much we balance making this easy vs exposing the metal.

What do you want to make sure you can easily do?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions