chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 419 forks source link

How should `help` message and metadata be defined for ArgumentParser options/flags etc? #18646

Open arezaii opened 2 years ago

arezaii commented 2 years ago

As we continue work on the ArgumentParser library, we would like to allow for help messages to be generated for the user. Other argument parsers have some parameters, typically set at the time the argument is defined, to control the help text and some additional features that may affect the usage string.

For example, Python's argparse has parameters in the add_argument method named help, which is a short string to describe the argument, and metavar, which is used to override the default behavior of using the argument's dest field in the generated help text. (dest is an optional parameter that defaults to what our ArgumentParser calls the name parameter.)

Rust's clap crate has a help method on the Arg struct to set the short help text displayed, in addition to a hidden method to hide the argument from displaying in help. (argparse similarly controls visibility with an enum passed in the help parameter) (there are many more properties to set for an Arg in clap, more so than either Python or Swift)

Swift's ArgumentParser defines an ArgumentHelp struct with public members:

When declaring an argument, there is a help argument where values for the ArgumentHelp fields can be populated.

I would propose a way to define the short description, visibility, and alternative display name. This could be done through additional parameters to the addArgument, addOption, addFlag, etc. methods on the argumenParser record. I do not see a need for a separate long description (as discussion) parameter at this time, but feel free to voice support and explain why we need it.

The implementation could look something like this:

proc addArgument(<fields already defined>, help="", visible=true, valueName:?t=none)

where valueName would default to the value of the name parameter, previously defined.

Argument declarations might look like:

var myFiles = parser.addArgument(name="fileNames", numArgs=1.., help="one or more filenames to process");
var developerFlag = parser.addFlag(name="secret-debug", defaultValue=false, visible=false);
dlongnecke-cray commented 2 years ago

Your initial proposal sounds reasonable to me. I'm up in the air about help or about for providing a short description of a flag. I really like the notion of visible for controlling whether or not a flag is displayed or not. I don't think I've ever used that in my argparsers before, but can totally see useful applications for it.

aconsroe-hpe commented 2 years ago

+1 for help. I don't immediately see a need for visible (but I'm sure there are). But assuming it does go in, is there a plan for having a way to print out all the options, even where visible=false?

arezaii commented 2 years ago

Each of the libraries I surveyed had a way to set visibility per argument, so that is a big driver of a design that includes the same.

is there a plan for having a way to print out all the options, even where visible=false?

I had not considered that feature. To my knowledge, the libraries I surveyed do not have that feature, although clap mentions that hidden arguments will still be displayed in usage strings on error. It's possible I overlooked this feature in other libraries so feel free to point it out.

mppf commented 2 years ago

Generally speaking, I like the idea of having the Swift ArgumentHelp elements available, even if we don't choose to make that available as a record. (But making it a record does seem to simplify the API a good deal because it sortof bundles up the help details for the argument). I think that the Swift names are reasonable if we are choosing to make a record like e.g. record helpDetails.

I do not see a need for a separate long description (as discussion) parameter at this time, but feel free to voice support and explain why we need it.

I like the idea of having a long description / discussion argument. Then I would expect that the argument parser can give additional help on specific arguments with something like ./myprog -h --myarg. I don't think the short discussion is always enough to understand the usage of an argument. I think the question is, what alternative documentation method would you want people to use?

arezaii commented 2 years ago

I'm not opposed to a long description, I just didn't have plans to support what you are suggesting with ./myprog -h --myarg, so it seemed like an unnecessary field to add at this time.

... what alternative documentation method would you want people to use?

I don't know that I have considered that a core part of the argument parser to this point. I can see how it could be helpful to incorporate something like that in the future, but it isn't a common feature from what I've seen. The closest implementation I've identified is in clap, where -h prints the full help message using short descriptions, while --help does the same but with the long descriptions.

mppf commented 2 years ago

Of course it would be OK to leave the long descriptions as an enhancement for future work -- I was just saying I see value in it.

arezaii commented 2 years ago

You can see the draft and comment on specifics in this PR, #18688

bradcray commented 2 years ago

w.r.t. Michael's proposal to have ./myprog -h --myarg give help about --myarg, one thought that comes to mind for me is that if I run a command and it fails in some way, or I want to add new arguments to it, I re-run it with -h. Often, I cursor-up in my shell and tack this onto the end of the command-line, but if I cursor-up'd and added it to the beginning, the interpretation would now be different (i.e., "don't give me help on the program itself, but on the first flag I mentioned after -h/--help). I.e., chpl --fast foo.chpl -h and chpl -h --fast foo.chpl would have very different meanings. That seems potentially confusing to me.

I also wonder whether the line between discussion and "maybe you should go read the man page" lies? I.e., are we trying to bake too much into the help when we should be relying on the man page more? Are we creating a maintenance burden for users? (now you have to update the discussion and the man page when you change things). Or is there a thought that the ArgumentParser will start to generate man pages from the discussion items (that seems tough to me...). Or are man pages so passe at this point, that that entire line of questioning feels quaint?

arezaii commented 2 years ago

w.r.t. Michael's proposal to have ./myprog -h --myarg give help about --myarg...That seems potentially confusing to me.

I don't see this behavior directly supported by other argument parsers, so I am inclined to not include it unless there is some motivating argument.

I also wonder whether the line between discussion and "maybe you should go read the man page" lies?

I think an ideal help output should be succinct enough to fit on the screen and still remind you of the syntax and basic meaning of an argument. Beyond that, a visit to the man page or webpage may be warranted. There is no limit on the size of the string the developer specifies in the help argument, so there is flexibility for them to put in as much or as little as they want.

Or are man pages so passe at this point, that that entire line of questioning feels quaint?

😆

I hadn't planned to develop man page support in the argument parser, it doesn't seem to be a feature of the other libraries. Python has a separate library that can construct a man page from an ArgumentParser object and I would argue this is a utility feature not needed by the core library. In the future we could offer an option to generate and print the man page at runtime, but there is also the task of setting up the environment so that man myProg worked correctly, which I think is best handled outside of the runtime.

There are other features, such as tab completion and context aware help (I don't recognize --halp, did you mean --help?), that have precedent in the other libraries and I see them as higher priority for future work.