~skeeto/public-inbox

2 2

quick question re: Conventions for Command Line Options

Daniel Sockwell
Details
Message ID
<7df03fe8f8d0304f0ed2cd95d7a839ae@codesections.com>
DKIM signature
pass
Download raw message
I generally agree with the points you made in Conventions for Command Line Options, 
but am curious about your views on one issue: when following those conventions, is 
there any way to pass multiple arguments to a single instance of an option?  (I 
realize you can pass the same option multiple times, but that's not what I'm asking
about.)  The reason I ask is to support the output of shell globing; it would be 
nice if

>  --input-files *.jpg

were parsed as multiple options being passed to --input-files rather than as a
single argument to --input-files followed by multiple positional arguments.  But,
unless I'm missing something, I don't believe there's a way to support using 
multiple values like that while following the conventions you laid out.  Nor can
I think of a way to do so without guessing in the way argparse does -- which would
create obvious difficulties with certain filenames in the example above, in addition
to the other issues you raise.

So do you just accept that there's no way to support that usage pattern and maintain
that the costs of supporting it outweigh any benefits?  Or am I missing some way to
support it while following the conventions you laid out?

I would welcome other perspectives on this as well.

Best regards,
Daniel
Details
Message ID
<20210219015056.ykehuy5vdz2ou3hl@nullprogram.com>
In-Reply-To
<7df03fe8f8d0304f0ed2cd95d7a839ae@codesections.com> (view parent)
DKIM signature
missing
Download raw message
> --input-files *.jpg

This has no way to indicate where the arguments stop such that option 
processing can continue, so this option must go last. If it must go last, 
then these are really just positional arguments. If you do choose some 
sentinel to mark the end (perhaps "--") then there's the risk of an 
argument unintentionally matching as a sentinel, such as blog expansion. 
As you noted, stopping at the first option-like argument (a la argparse) 
is similarly unsound.

You mentioned repeated arguments, probably the most conventional way to 
supply multiple arguments for a particular option. For instance, there's 
ffmpeg's -i option. Though as you also noticed, this isn't friendly to 
globbing.

Another is to use a custom, non-space delimiter that the shell won't 
split, such as a comma, so that the application can do its own splitting 
on the argument. For instance, gcc's -Wl option. Though again, not 
friendly to globbing.

Some programs that may need to accept more arguments than the operating 
system allows but cannot be run multiple times (e.g. via xargs) may accept 
a glob pattern as an argument and expand the pattern itself. In this case 
usage would look like:

> --input-files '*.jpg'

For instance, ImageMagick may potentially have very many inputs and so it 
optionally (though imperfectly) accepts glob patterns.

> So do you just accept that there's no way to support that usage pattern 
> and maintain that the costs of supporting it outweigh any benefits?

Yes, I think that accurately summarizes my position. Popular programs can 
get away with custom conventions (e.g. gcc) so long as they consistently 
stick to them, but less popular programs with unique, unusual conventions 
demand undue extra headspace as users code switch between conventions. For 
instance, Go's flag package still regularly trips me up until I remember 
I'm dealing with a Go program.

Arbitrary argument lists should be positional arguments. If you need 
multiple such lists (e.g. multiple inputs and multiple outputs), all but 
one list should be relegated to a repeated arguments — preferably the ones 
least likely to be used with glob expansion.
Daniel Sockwell
Details
Message ID
<748d39f5264bf11111ee06b52ab468f1@codesections.com>
In-Reply-To
<20210219015056.ykehuy5vdz2ou3hl@nullprogram.com> (view parent)
DKIM signature
pass
Download raw message
Thanks very much for the helpful and through reply!  This (along with your post) has been very
helpful in getting my head around all of this, and has definitely impacted the design decisions 
I'm making as I work to expand the argument parser built in to the Raku standard library.

>> --input-files *.jpg
> 
> This has no way to indicate where the arguments stop such that option processing can continue, so
> this option must go last. If it must go last, then these are really just positional arguments.
> [snip]
> Arbitrary argument lists should be positional arguments. If you need multiple such lists (e.g.
> multiple inputs and multiple outputs), all but one list should be relegated to a repeated arguments
> — preferably the ones least likely to be used with glob expansion.

That's a very helpful way of putting it, and makes me realize that subcommands (in the style of git 
and similar commands can also be useful. If a CLI needs to be able to accept multiple argument lists
but _only one in any given invocation_, then it can use a subcommand followed by positional arguments.
(Or, and this is effectively the same thing, have a boolean option that changes the meaning of the 
positional arguments.)  That doesn't address the use case of needing to process multiple lists in the
same invocation, but it at least narrows the scope of the problem.

Thanks again!
Daniel
Reply to thread Export thread (mbox)