dbuenzli / cmdliner

Declarative definition of command line interfaces for OCaml
http://erratique.ch/software/cmdliner
ISC License
296 stars 56 forks source link

Add --help=commands #177

Open Julow opened 1 year ago

Julow commented 1 year ago

This adds --help=commands, which prints the list of all the sub-commands accepted by the executable. This list can be used to quickly navigate between the different manpages and can be parsed.

The output on test/darcs_ex is:

darcs
darcs initialize
darcs record
darcs help

Unlike other help formats, it outputs to stdout and use a strict format that can be parsed: newline-separated list.

This is an argument to the --help option instead of a new option because it can also be used by humans. It is not exposed in the library.

The main motivation is to be able to generate odoc pages containing the manpage of each commands. I've tried this in the past for Odoc (https://github.com/ocaml/odoc/pull/903) and I'm considering this for ocamlformat. What do you think of this ?

dbuenzli commented 1 year ago

What do you think of this ?

I think that once https://github.com/dbuenzli/cmdliner/issues/1 is solved in some way this becomes redundant so I'd rather not add this.

I know #1 has been an extreeeeemly long standing problem but I hope to get to it at some point. Last time I looked at it, it eventually seemed in reach (see the last messages in the issue).

Julow commented 1 year ago

That's interesting! Though auto completion is intended to complete command lines and communicate with humans. --help=commands is simple enough to be reliably parsed by generator tools.

Do you think auto completion could accept queries like "list all the sub-commands" ? For example, a tool that have deep sub commands:

prog
prog foo
prog foo bar

A sub-command is anything that can accept --help and has no other flags/options/positional argument.

I want to be sure not to get:

prog
prog foo
prog --help
prog --version
dbuenzli commented 1 year ago

That's interesting! Though auto completion is intended to complete command lines and communicate with humans.

If you ask it to complete the a command starting with the empty string it will give you all the commands.

In general I'm not decided yet whether it would maybe not be better to dump all the cmdliner metadata in a machine readable format like json which can then be massaged at will by any third-party system, including completion. Or try to have subtler integration with completion like I was starting to get to in #1.

dbuenzli commented 1 year ago

I want to be sure not to get: [...]

I read too fast yes, of course we should think about that.

Leonidas-from-XIV commented 1 year ago

A sub-command is anything that can accept --help and has no other flags/options/positional argument.

But wouldn't the command list that you don't want to get a superset of the information you want? You can search for lines with --help and then get the subcommands from there. It even guarantees that the command supports --help.

Julow commented 1 year ago

It would list all options/arguments for every sub-commands ?

prog
prog foo
prog foo bar
prog foo bar --help
prog foo bar <other args>
prog foo --help
prog --help

This looks like an interesting output that doesn't require parsing JSON (useful in bash), though the syntax might become complex with added metadata like type of argument (directory, enum).

dbuenzli commented 5 months ago

Beyond some form of built-in completion that more and more looks like Duke Nukem Forever, I think it would be nice to be able to dump all the metadata (including man pages) cmdliner users provide to the library on say --help=json for further processing by third-parties.

The problem is that we'd need to devise a format that is reasonably stable and not too tied to current implementation which takes… time.

Julow commented 5 months ago

I could use a metadata dump to achieve my usecase, though the added maintenance to cmdliner looks huge. What are the other use cases for a complete metadata dump ?

dbuenzli commented 5 months ago

Not sure if it would be a maintenance burden. The burden is rather designing and documenting the format in the first place but:

What are the other use cases for a complete metadata dump ?

Good question :-) I guess you could certainly then relegate the nasty story of generating completion routines for all these crazy shell completion mecanisms to a third party tool. I guess some people would use it to generate docs in different format without having to parse groff (IIRC correctly that's what opam actually does 🥺)

And dreams on. If shells could agree on some kind of machine readable documentation format there's all sorts of nice UI tricks you could beyond completion like get the documentation of the option under my cursor etc.

Julow commented 5 months ago

My use case is to generate Odoc pages for a tool's CLI. The current PR would help get the list of commands, which would then be called with --help appended and concatenated into a .mld page. This leads to a ugly document. Having complete metadata would allow to implement this in a nicer way, using more of Odoc's features but requiring the maintenance of an other tool.

Perhaps cmdliner could take care of that ? It supports several documentation formats, except OCaml's one. Designing a new --help=odoc format would implement my use case without leaking the metadata (except perhaps the list of commands again).

Julow commented 5 months ago

Here's how it looks in ocamlformat, which has only one command: https://ocaml.org/p/ocamlformat/latest/doc/manpage_ocamlformat.html

dbuenzli commented 5 months ago

Designing a new --help=odoc format

And the next person will want --help=md :-) That the reason why I rather output a json which does "leak" all the data in structured format.

A tool that converts this json to .mld could be part of cmdliner itself. But I don't think it's useful to have it in every cmdliner based program. I'd like to avoid cmdliner adding too much bloat to programs (I already find it too large for what it's doing).

The "multiple formats" that are currently in are there to integrate well in the cli infrastructure.

Julow commented 5 months ago

Makes sense. In the meantime, let's close this.

dbuenzli commented 5 months ago

I'm actually interested in looking how/where you hooked the thing. So I'll keep it open for now.