argparse icon indicating copy to clipboard operation
argparse copied to clipboard

Let long/short argument options be atoms (or error out)

Open eproxus opened this issue 3 years ago • 2 comments

It would be nice if the short and long options for arguments could take atoms, or at least throw errors if they won't. I had this configuration:

#{
    arguments => [
        #{name => backgrounds, short => b, long => backgrounds, type => binary, default => "0..8"}
    ]
}

Calling the escript CLI gave this output:

$ ./tool
usage: colortool
$ ./tool -b foo
error: tool: unrecognised argument: -b
usage: tool

Of course, it works if I change it to $b. This one took a long time to debug 😄

If they should take atoms, I think short should only take one letter atoms and error out otherwise, and long should take any string atom and automatically prepend it with "-" so that the default flag format is --flag (since most UNIX CLIs follow that).

eproxus avatar Mar 12 '22 13:03 eproxus

I dug into this specific issue and found that argparse already throws when short is not a printable character, or long is not a printable string. Now what's been happening with cli, it was catching this exception, and printing this to Erlang Logger:

 WARNING REPORT==== 13-Mar-2022::11:14:04.469019 ===
Error calling bare:cli(): error:{argparse,
                                 {invalid_option,
                                  ["erl"],
                                  backgrounds,long,"must be a string"}}
[{argparse,fail,1,
           [{file,"/home/max-au/git/max-au/argparse/src/argparse.erl"},
            {line,834}]},
 {argparse,'-validate_command/2-lc$^0/1-0-',2,
           [{file,"/home/max-au/git/max-au/argparse/src/argparse.erl"},
            {line,881}]},
 {argparse,validate_command,2,
           [{file,"/home/max-au/git/max-au/argparse/src/argparse.erl"},
            {line,881}]},
 {cli,'-discover_commands/2-fun-0-',5,
      [{file,"/home/max-au/git/max-au/argparse/src/cli.erl"},{line,128}]},
 ...

This is a deliberate decision, to keep running cli even when some command has invalid description, and just log instead. The reason is, we often have dozens and even hundreds of modules exporting cli, and it happens that some commands may have a broken description, or something else broken. Therefore we cannot fail the entire cli, and have to ignore the malformed command. I understand that this behaviour is not exactly useful for smaller projects. What I think of, there is warn option available for cli:run/2, that can be set to warn (default meaning "print the discovered issue to logger") and suppress (silently ignore). I can add another value, halt, that would mean "print the problem to stdout and halt the VM".

max-au avatar Mar 13 '22 18:03 max-au

Another clue is given by Dialyzer, it immediately warns against atoms set as short or long attributes. It might be enough signal to figure out the invalid argument description.

max-au avatar Mar 13 '22 19:03 max-au