diff --git a/.plano.py b/.plano.py index 8986775..693c66f 100644 --- a/.plano.py +++ b/.plano.py @@ -36,6 +36,10 @@ def test(verbose=False, quiet=False, passthrough_args=[]): @command def coverage(): + """ + Run the tests and measure code coverage + """ + check_program("coverage") with working_env(PYTHONPATH="python"): diff --git a/external/plano-main/src/plano/_tests.py b/external/plano-main/src/plano/_tests.py index 5449155..ebc3dcc 100644 --- a/external/plano-main/src/plano/_tests.py +++ b/external/plano-main/src/plano/_tests.py @@ -66,9 +66,14 @@ def archive_operations(): def command_operations(): class SomeCommand(BaseCommand): def __init__(self): + super().__init__() + self.parser = BaseArgumentParser() self.parser.add_argument("--interrupt", action="store_true") self.parser.add_argument("--explode", action="store_true") + self.parser.add_argument("--verbose", action="store_true") + self.parser.add_argument("--quiet", action="store_true") + self.parser.add_argument("--init-only", action="store_true") def parse_args(self, args): return self.parser.parse_args(args) @@ -90,10 +95,9 @@ def run(self): SomeCommand().main([]) SomeCommand().main(["--interrupt"]) - SomeCommand().main(["--debug"]) with expect_system_exit(): - SomeCommand().main(["--verbose", "--debug", "--explode"]) + SomeCommand().main(["--verbose", "--explode"]) @test def console_operations(): diff --git a/external/plano-main/src/plano/command.py b/external/plano-main/src/plano/command.py index 0439f6b..82310f6 100644 --- a/external/plano-main/src/plano/command.py +++ b/external/plano-main/src/plano/command.py @@ -27,10 +27,24 @@ import traceback as _traceback class BaseCommand: - initial_logging_level = "warning" + default_logging_level = "warning" verbose_logging_level = "notice" quiet_logging_level = "error" + def __init__(self): + self.verbose = False + self.quiet = False + self.init_only = False + + def parse_args(self, args): # pragma: nocover + raise NotImplementedError() + + def init(self, args): # pragma: nocover + pass + + def run(self): # pragma: nocover + raise NotImplementedError() + def main(self, args=None): if args is None: args = ARGS[1:] @@ -39,12 +53,7 @@ def main(self, args=None): assert isinstance(args, _argparse.Namespace), args - self.verbose = args.verbose or args.debug - self.quiet = args.quiet - self.debug = args.debug - self.init_only = args.init_only - - level = self.initial_logging_level + level = self.default_logging_level if self.verbose: level = self.verbose_logging_level @@ -52,9 +61,6 @@ def main(self, args=None): if self.quiet: level = self.quiet_logging_level - if self.debug: - level = "debug" - with logging_enabled(level=level): try: self.init(args) @@ -66,21 +72,12 @@ def main(self, args=None): except KeyboardInterrupt: pass except PlanoError as e: - if self.debug: + if PLANO_DEBUG: _traceback.print_exc() exit(1) else: exit(str(e)) - def parse_args(self, args): # pragma: nocover - raise NotImplementedError() - - def init(self, args): # pragma: nocover - pass - - def run(self): # pragma: nocover - raise NotImplementedError() - class BaseArgumentParser(_argparse.ArgumentParser): def __init__(self, **kwargs): super().__init__(**kwargs) @@ -88,24 +85,18 @@ def __init__(self, **kwargs): self.allow_abbrev = False self.formatter_class = _argparse.RawDescriptionHelpFormatter - self.add_argument("--verbose", action="store_true", - help="Print detailed logging to the console") - self.add_argument("--quiet", action="store_true", - help="Print no logging to the console") - self.add_argument("--debug", action="store_true", - help="Print debugging output to the console") - self.add_argument("--init-only", action="store_true", - help=_argparse.SUPPRESS) - _capitalize_help(self) _plano_command = None class PlanoCommand(BaseCommand): - initial_logging_level = "notice" + default_logging_level = "notice" verbose_logging_level = "debug" + quiet_logging_level = "error" def __init__(self, module=None, description="Run commands defined as Python functions", epilog=None): + super().__init__() + self.module = module self.bound_commands = dict() self.running_commands = list() @@ -172,6 +163,11 @@ def init(self, args): self.command_kwargs = dict() if args.command is not None: + # These args are taken from the subcommand + self.verbose = args.verbose + self.quiet = args.quiet + self.init_only = args.init_only + for command in self.preceding_commands: command() @@ -269,8 +265,17 @@ def _process_commands(self): subparser = subparsers.add_parser(command.name, help=help, add_help=add_help, description=description, formatter_class=_argparse.RawDescriptionHelpFormatter) + subparser.add_argument("--verbose", action="store_true", + help="Print detailed logging to the console") + subparser.add_argument("--quiet", action="store_true", + help="Print no logging to the console") + subparser.add_argument("--init-only", action="store_true", + help=_argparse.SUPPRESS) for param in command.parameters.values(): + if param.name in ("verbose", "quiet", "init_only"): + continue + if param.positional: if param.multiple: subparser.add_argument(param.name, metavar=param.metavar, type=param.type, help=param.help, @@ -323,9 +328,9 @@ def __init__(self, function): self.parent = parent if self.parent is None: - # Strip trailing underscores and convert remaining - # underscores to hyphens - default = self.function.__name__.rstrip("_").replace("_", "-") + # Strip leading and trailing underscores and convert + # remaining underscores to hyphens + default = self.function.__name__.strip("_").replace("_", "-") self.name = nvl(self.name, default) self.parameters = self._process_parameters(parameters) @@ -500,7 +505,7 @@ def __init__(self, name, display_name=None, type=None, metavar=None, help=None, self.multiple = False def __repr__(self): - return "argument '{}' (default {})".format(self.name, repr(self.default)) + return "parameter '{}' (default {})".format(self.name, repr(self.default)) # Patch the default help text def _capitalize_help(parser): diff --git a/external/plano-main/src/plano/main.py b/external/plano-main/src/plano/main.py index 7e7b6a0..78b31ad 100644 --- a/external/plano-main/src/plano/main.py +++ b/external/plano-main/src/plano/main.py @@ -910,7 +910,7 @@ def _print_message(level, message, args): line.append(cformat(program_text, color="gray")) - level_text = "{}:".format(_logging_levels[level]).ljust(8) + level_text = "{}:".format(_logging_levels[level]) level_color = ("white", "cyan", "yellow", "red", None)[level] level_bright = (False, False, False, True, False)[level] @@ -1247,7 +1247,7 @@ def wait(proc, timeout=None, check=False, quiet=False): try: proc.wait(timeout=timeout) except _subprocess.TimeoutExpired: - # XXX warning or error + error("{} timed out after {} seconds", proc, timeout) raise PlanoTimeout() if proc.exit_code == 0: diff --git a/external/plano-main/src/plano/test.py b/external/plano-main/src/plano/test.py index 9067c33..8450889 100644 --- a/external/plano-main/src/plano/test.py +++ b/external/plano-main/src/plano/test.py @@ -29,7 +29,7 @@ class PlanoTestCommand(BaseCommand): def __init__(self, test_modules=[]): - super(PlanoTestCommand, self).__init__() + super().__init__() self.test_modules = test_modules @@ -55,6 +55,12 @@ def __init__(self, test_modules=[]): help="Exit on the first failure encountered in a test run") self.parser.add_argument("--iterations", metavar="COUNT", type=int, default=1, help="Run the tests COUNT times (default 1)") + self.parser.add_argument("--verbose", action="store_true", + help="Print detailed logging to the console") + self.parser.add_argument("--quiet", action="store_true", + help="Print no logging to the console") + self.parser.add_argument("--init-only", action="store_true", + help=_argparse.SUPPRESS) def parse_args(self, args): return self.parser.parse_args(args)