Open ChrisPenner opened 2 years ago
The parser you mentioned should just work and be pretty intuitive. An option passed for the launch command will lock in one side alternative. Indeed everything should be wrapped parenthetically with an alternative marker.
Can you give me an example of what the help looks like and what you think it should look like? Or some CLI examples with desired vs current behaviour given a particular parser?
The executable itself works as expected, it seems to be just the help messages that are out of whack; The issue is that currently optparse-applicative interprets all of the options of launch as global options, even though all of those options will fail if passed to the run subcommand for example.
So, for example, for the unison executable, launch
has a --port
flag, but run
does not.
If I get the help for run
, it shows ALL of the options for launch
under "Global options" even though some of them only work for the launch command specifically (or the empty top-level command which ends up calling launch)
$ ucm run --help
Usage: unison-trunk run SYMBOL [RUN-ARGS]
Execute a definition from the codebase, passing on the provided arguments. To pass flags to your
program, use `run <symbol> -- --my-flag`
Available options:
-h,--help Show this help text
Global options:
-v,--version Show version
-c,--codebase CODEBASE/PATH
The path to an existing codebase
-C,--codebase-create CODEBASE/PATH
The path to a new or existing codebase (one will be created if there
isn't one)
--exit Exit repl after the command.
--token STRING API auth token
--host STRING Codebase server host
--port NUMBER Codebase server port
--ui DIR Path to codebase ui root
--no-base if set, a new codebase will be created without downloading the base
library, otherwise the new codebase will download base
Notice that --port
is listed here as a global option, but it's not actually a valid option for the run
command; and opt-parse applicative will correctly show an error if we try to use it (although the option still incorrectly appears in the global options of the usage info):
$ ucm run --port 5050
Invalid option `--port'
Usage: unison-trunk run SYMBOL [RUN-ARGS]
Execute a definition from the codebase, passing on the provided arguments. To pass flags to your
program, use `run <symbol> -- --my-flag`
Available options:
-h,--help Show this help text
Global options:
-v,--version Show version
-c,--codebase CODEBASE/PATH
The path to an existing codebase
-C,--codebase-create CODEBASE/PATH
The path to a new or existing codebase (one will be created if there
isn't one)
--exit Exit repl after the command.
--token STRING API auth token
--host STRING Codebase server host
--port NUMBER Codebase server port
--ui DIR Path to codebase ui root
--no-base if set, a new codebase will be created without downloading the base
library, otherwise the new codebase will download base
Hopefully that helps clear up the issue; it's really just a matter of things showing up in global options that aren't actually global :)
Let me know if any further clarification would help!
Ok I see.
The issue is that global options can appear in the help text which are invalid when an alternative is taken which includes a subparser. And yes, that's not ideal.
The globals are pulled in from the parent parsers as they were before any data was parsed, so they don't "know" about any alternatives accepted. I did this so that you'd still see the help text for options which were provided as well.
If you don't actually have global options, the simplest thing to do is just not include helpShowGlobals when building the parser. In general that flag works best with subparserInline anyway, as then the global ones can actually mix in with the child ones during use.
Alternatively, you can use the noGlobal modifier to suppress individual options which you don't want to bubble into the subparsers.
I'll leave this issue open (and maybe rename it) as there is an underlying bug there.
Manually adding noGlobal
seems to do the trick for now, thanks for the tip!
Hello 👋🏼
The CLI for Unison has one very common use-case (launching the unison shell) and several other 'utility' commands. The way we have things set up right now is as follows:
ucm
without any subcommand runs the 'launch' behaviourucm run
defers to therun
subcommand.The way we've implemented this is by using our
launch
option parser as a fallback for our subcommand parser:Meaning that if the user doesn't provide a command, we interpret it as a 'launch'.
The issue is that currently optparse-applicative interprets all of the options of
launch
as global options, even though all of those options will fail if passed to therun
subcommand for example.Is there any way to indicate options as being only relevant if no subcommand is provided, rather than showing them as global?
Effectively I want the empty command to just be treated as another subcommand.
This may not be the most common setup, but if you can think of a way to make this work I'd love to hear it 😄
Thank you for maintaining such an awesome tool, it saves us a lot of time :D