Fix redundant help information being displayed for multi-commands.
Review Request #12179 — Created March 19, 2022 and submitted — Latest diff uploaded
Multi-commands (such as
rbt review
) had an issue where usage and help
output would be displayed multiple times. On Python 2.7, we'd get a
usage + help block, followed by a usage block, followed by another
usage + help block. On newer versions, we'd just get two usage + help
blocks.The reason this was happening has to do with how we handle help in
RBTools. We have our own custom--help
handler that's invoked before
any commands are set up, which allows us to dorbt --help
,
rbt <command> --help
, orrbt --help <command>
, along with supporting
passing--help
to any third-partyrbt-*
scripts.When handling help for internal commands, we locate the right command
class, check if it's a multi-command or a standard command, and attempt
to get the right help information. For multi-commands, we do an explicit
parse of the options, which will funnel the--help
to the right
subcommand if needed.This is where the problem was found. This test parse will see the
--help
and will result inArgumentParser.print_help()
being called,
resulting in one usage + help block.Then, on Python 2.7, the argument parser notes that we haven't passed
any required arguments for the subparser and triggers
ArgumentParser.error()
, which prints a second usage block.We then return formatted help, which includes the final usage + help
block. This gets printed to the console.Solving this requires babysitting
argparse
a bit more.We no longer leave invocation to chance. Instead, we first check if
there's a multi-command class, and then grab the first positional
argument. If it matches a known subcommand, we pull out the class and
build a new, fixed set of command line arguments that will generate new
help output.This gives us full control of how help output is generated. We no longer
need to stubargparse
when invoking--help
on a subcommand, and
we're far less sensitive to Python version differences or the position
ofhelp
or-h/--help
.
Tested the following on Python 2.7 and 3.8:
rbt help
rbt help <command>
rbt help <multi-command>
rbt help <multi-command> <subcommand>
rbt --help
rbt --help <command>
rbt --help <multi-command>
rbt --help <multi-command> <subcommand>
rbt <command> --help
rbt <multi-command> --help
rbt <multi-command> --help <subcommand>
rbt <multi-command> <subcommand> --help