diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/patman/cmdline.py | 21 | ||||
-rw-r--r-- | tools/patman/settings.py | 50 |
2 files changed, 65 insertions, 6 deletions
diff --git a/tools/patman/cmdline.py b/tools/patman/cmdline.py index 108fa52d820..8e10c7bb14f 100644 --- a/tools/patman/cmdline.py +++ b/tools/patman/cmdline.py @@ -21,6 +21,25 @@ PATMAN_DIR = pathlib.Path(__file__).parent HAS_TESTS = os.path.exists(PATMAN_DIR / "func_test.py") +class ErrorCatchingArgumentParser(argparse.ArgumentParser): + def __init__(self, **kwargs): + self.exit_state = None + self.catch_error = False + super().__init__(**kwargs) + + def error(self, message): + if self.catch_error: + self.message = message + else: + super().error(message) + + def exit(self, status=0, message=None): + if self.catch_error: + self.exit_state = True + else: + super().exit(status, message) + + def add_send_args(par): """Add arguments for the 'send' command @@ -150,7 +169,7 @@ def setup_parser(): them as specified by tags you place in the commits. Use -n to do a dry run first.''' - parser = argparse.ArgumentParser(epilog=epilog) + parser = ErrorCatchingArgumentParser(epilog=epilog) parser.add_argument( '-D', '--debug', action='store_true', help='Enabling debugging (provides a full traceback on error)') diff --git a/tools/patman/settings.py b/tools/patman/settings.py index def932db43a..17229e0d823 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -9,8 +9,10 @@ except Exception: import ConfigParser import argparse +from io import StringIO import os import re +import sys from u_boot_pylib import gitutil @@ -254,10 +256,44 @@ def _UpdateDefaults(main_parser, config, argv): defaults = {} parser_defaults = [] argv = list(argv) + orig_argv = argv + + bad = False + full_parser_list = [] for parser in parsers: - pdefs = parser.parse_known_args()[0] - parser_defaults.append(pdefs) - defaults.update(vars(pdefs)) + argv_list = [orig_argv] + special_cases = [] + if hasattr(parser, 'defaults_cmds'): + special_cases = parser.defaults_cmds + for action in parser._actions: + if action.choices: + argv_list = [] + for choice in action.choices: + argv = None + for case in special_cases: + if case[0] == choice: + argv = case + argv_list.append(argv or [choice]) + + for argv in argv_list: + parser.message = None + old_val = parser.catch_error + try: + parser.catch_error = True + pdefs = parser.parse_known_args(argv)[0] + finally: + parser.catch_error = old_val + + # if parser.message: + # print('bad', argv, parser.message) + # bad = True + + parser_defaults.append(pdefs) + defaults.update(vars(pdefs)) + full_parser_list.append(parser) + if bad: + print('Internal parsing error') + sys.exit(1) # Go through the settings and collect defaults for name, val in config.items('settings'): @@ -272,11 +308,15 @@ def _UpdateDefaults(main_parser, config, argv): defaults[name] = val else: print("WARNING: Unknown setting %s" % name) + if 'cmd' in defaults: + del defaults['cmd'] + if 'subcmd' in defaults: + del defaults['subcmd'] # Set all the defaults and manually propagate them to subparsers main_parser.set_defaults(**defaults) - assert len(parsers) == len(parser_defaults) - for parser, pdefs in zip(parsers, parser_defaults): + assert len(full_parser_list) == len(parser_defaults) + for parser, pdefs in zip(full_parser_list, parser_defaults): parser.set_defaults(**{k: v for k, v in defaults.items() if k in pdefs}) return defaults |