Fix: correctly handle help with any argument possibility
Change-Id: I13478ccfe805c3cb6c21b3d395122cebae176dcd
This commit is contained in:
parent
d7e7080638
commit
a9d93864dd
@ -29,6 +29,11 @@ import sys
|
|||||||
|
|
||||||
class SurveilShell(object):
|
class SurveilShell(object):
|
||||||
|
|
||||||
|
default_api_version = '1_0'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.parser = self.get_base_parser()
|
||||||
|
|
||||||
def get_base_parser(self):
|
def get_base_parser(self):
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog='surveil',
|
prog='surveil',
|
||||||
@ -39,6 +44,8 @@ class SurveilShell(object):
|
|||||||
formatter_class=HelpFormatter,
|
formatter_class=HelpFormatter,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument('-h', '--help', action='store_true')
|
||||||
|
|
||||||
parser.add_argument('--surveil-api-url',
|
parser.add_argument('--surveil-api-url',
|
||||||
default=utils.env('SURVEIL_API_URL'),
|
default=utils.env('SURVEIL_API_URL'),
|
||||||
help='Defaults to env[SURVEIL_API_URL].')
|
help='Defaults to env[SURVEIL_API_URL].')
|
||||||
@ -46,8 +53,9 @@ class SurveilShell(object):
|
|||||||
parser.add_argument('--surveil-api-version',
|
parser.add_argument('--surveil-api-version',
|
||||||
default=utils.env(
|
default=utils.env(
|
||||||
'SURVEIL_API_VERSION',
|
'SURVEIL_API_VERSION',
|
||||||
default='1_0'),
|
default=self.default_api_version),
|
||||||
help='Defaults to env[SURVEIL_API_VERSION] or 1_0')
|
help='Defaults to env[SURVEIL_API_VERSION] or %s' %
|
||||||
|
self.default_api_version)
|
||||||
|
|
||||||
parser.add_argument('-j', '--json',
|
parser.add_argument('-j', '--json',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@ -55,14 +63,16 @@ class SurveilShell(object):
|
|||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def get_subcommand_parser(self, version):
|
def get_subcommand_parser(self, version=default_api_version):
|
||||||
parser = self.get_base_parser()
|
parser = self.get_base_parser()
|
||||||
self.subcommands = {}
|
self.subcommands = {}
|
||||||
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
subparsers = parser.add_subparsers(metavar='<subcommand>',
|
||||||
|
dest='subcommand')
|
||||||
submodule = utils.import_versioned_module(version, 'shell')
|
submodule = utils.import_versioned_module(version, 'shell')
|
||||||
self._find_actions(subparsers, submodule)
|
self._find_actions(subparsers, submodule)
|
||||||
self._find_actions(subparsers, self)
|
self._find_actions(subparsers, self)
|
||||||
self._add_bash_completion_subparser(subparsers)
|
self._add_bash_completion_subparser(subparsers)
|
||||||
|
self.parser = parser
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _add_bash_completion_subparser(self, subparsers):
|
def _add_bash_completion_subparser(self, subparsers):
|
||||||
@ -86,11 +96,7 @@ class SurveilShell(object):
|
|||||||
subparser = subparsers.add_parser(command,
|
subparser = subparsers.add_parser(command,
|
||||||
help=help,
|
help=help,
|
||||||
description=desc,
|
description=desc,
|
||||||
add_help=False,
|
|
||||||
formatter_class=HelpFormatter)
|
formatter_class=HelpFormatter)
|
||||||
subparser.add_argument('-h', '--help',
|
|
||||||
action='help',
|
|
||||||
help=argparse.SUPPRESS)
|
|
||||||
self.subcommands[command] = subparser
|
self.subcommands[command] = subparser
|
||||||
for (args, kwargs) in arguments:
|
for (args, kwargs) in arguments:
|
||||||
subparser.add_argument(*args, **kwargs)
|
subparser.add_argument(*args, **kwargs)
|
||||||
@ -98,7 +104,7 @@ class SurveilShell(object):
|
|||||||
|
|
||||||
@utils.arg('command', metavar='<subcommand>', nargs='?',
|
@utils.arg('command', metavar='<subcommand>', nargs='?',
|
||||||
help='Display help for <subcommand>.')
|
help='Display help for <subcommand>.')
|
||||||
def do_help(self, args):
|
def do_help(self, args=None):
|
||||||
"""Display help about this program or one of its subcommands."""
|
"""Display help about this program or one of its subcommands."""
|
||||||
if getattr(args, 'command', None):
|
if getattr(args, 'command', None):
|
||||||
if args.command in self.subcommands:
|
if args.command in self.subcommands:
|
||||||
@ -126,42 +132,31 @@ class SurveilShell(object):
|
|||||||
print(' '.join(commands | options))
|
print(' '.join(commands | options))
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
# Parse args once to find version
|
|
||||||
parser = self.get_base_parser()
|
|
||||||
(options, args) = parser.parse_known_args(argv)
|
|
||||||
|
|
||||||
# build available subcommands based on version
|
cfg, args = self.parser.parse_known_args(argv)
|
||||||
api_version = options.surveil_api_version
|
|
||||||
subcommand_parser = self.get_subcommand_parser(api_version)
|
|
||||||
self.parser = subcommand_parser
|
|
||||||
|
|
||||||
# Handle top-level --help/-h before attempting to parse
|
parser = self.get_subcommand_parser(cfg.surveil_api_version)
|
||||||
# a command off the command line
|
if not argv or (cfg.help and not args):
|
||||||
if not args and options.help or not argv:
|
self.do_help()
|
||||||
self.do_help(options)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Parse args again and call whatever callback was selected
|
cfg = parser.parse_args(argv)
|
||||||
args = subcommand_parser.parse_args(argv)
|
if cfg.help or cfg.func == self.do_help:
|
||||||
|
self.do_help(cfg)
|
||||||
# Short-circuit and deal with help command right away.
|
|
||||||
if args.func == self.do_help:
|
|
||||||
self.do_help(args)
|
|
||||||
return 0
|
|
||||||
elif args.func == self.do_bash_completion:
|
|
||||||
self.do_bash_completion(args)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if not args.surveil_api_url:
|
if cfg.func == self.do_bash_completion:
|
||||||
|
self.do_bash_completion(cfg)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
endpoint = cfg.surveil_api_url
|
||||||
|
if not endpoint:
|
||||||
raise exc.CommandError("you must specify a Surveil API URL"
|
raise exc.CommandError("you must specify a Surveil API URL"
|
||||||
" via either --surveil-api-url or"
|
" via either --surveil-api-url or"
|
||||||
" env[SURVEIL_API_URL]")
|
" env[SURVEIL_API_URL]")
|
||||||
|
client = surveil_client.Client(endpoint,
|
||||||
endpoint = args.surveil_api_url
|
version=cfg.surveil_api_version)
|
||||||
|
return cfg.func(client, cfg)
|
||||||
client = surveil_client.Client(endpoint, version=api_version)
|
|
||||||
|
|
||||||
args.func(client, args)
|
|
||||||
|
|
||||||
|
|
||||||
class HelpFormatter(argparse.HelpFormatter):
|
class HelpFormatter(argparse.HelpFormatter):
|
||||||
@ -174,11 +169,16 @@ class HelpFormatter(argparse.HelpFormatter):
|
|||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
SurveilShell().main(sys.argv[1:])
|
SurveilShell().main(sys.argv[1:])
|
||||||
|
except exc.CommandError as err:
|
||||||
|
print(err, file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("... terminating surveil client", file=sys.stderr)
|
print("... terminating surveil client", file=sys.stderr)
|
||||||
sys.exit(130)
|
sys.exit(130)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
print(str(e), file=sys.stderr)
|
print(str(e), file=sys.stderr)
|
||||||
|
print(traceback.format_exc())
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user