diff options
| -rw-r--r-- | hazwaz/__init__.py | 2 | ||||
| -rw-r--r-- | hazwaz/command.py | 34 | ||||
| -rw-r--r-- | tests/test_command.py | 62 | 
3 files changed, 87 insertions, 11 deletions
diff --git a/hazwaz/__init__.py b/hazwaz/__init__.py index f5f0a6d..4986238 100644 --- a/hazwaz/__init__.py +++ b/hazwaz/__init__.py @@ -1 +1 @@ -from .command import MainCommand  # noqa: F401 +from .command import MainCommand, Command  # noqa: F401 diff --git a/hazwaz/command.py b/hazwaz/command.py index c99e012..a8866ab 100644 --- a/hazwaz/command.py +++ b/hazwaz/command.py @@ -10,6 +10,7 @@ def _get_first_docstring_line(obj):      except (AttributeError, IndexError):          return None +  def _get_remaining_docstring_lines(obj):      try:          return "\n".join(obj.__doc__.split('\n')[2:]).strip() @@ -30,15 +31,15 @@ class MainCommand:          self.add_arguments(self.parser)          self.parser.set_defaults(func=self._main)          self.subparsers = self.parser.add_subparsers() -        for name, sub in self.commands: +        for sub in self.commands:              sub_help = _get_first_docstring_line(sub) +            sub_epilog = _get_remaining_docstring_lines(sub)              sub_parser = self.subparsers.add_parser( -                name, -                help=sub_help, -                description=sub.__doc__, +                sub.name, +                description=sub_help, +                epilog=sub_epilog,              ) -            for arg in sub.arguments: -                sub_parser.add_argument(*arg[0], **arg[1]) +            sub.add_arguments(sub_parser)              sub_parser.set_defaults(func=sub._main)      def _main(self, args): @@ -60,9 +61,26 @@ class MainCommand:      def main(self):          self.args = self.parser.parse_args() -        if self.args.verbose: -            logger.setLevel(logging.VERBOSE)          if self.args.debug:              logger.setLevel(logging.DEBUG) +        elif self.args.verbose: +            logger.setLevel(logging.INFO) +        else: +            logger.setLevel(logging.WARNING)          self.args.func(self.args) + + +class Command: +    name = None + +    def __init__(self): +        if self.name is None: +            self.name = self.__class__.__name__.lower() + +    def _main(self, args): +        self.args = args +        self.main() + +    def add_arguments(self, parser): +        pass diff --git a/tests/test_command.py b/tests/test_command.py index eed6e1f..d0b6437 100644 --- a/tests/test_command.py +++ b/tests/test_command.py @@ -6,19 +6,41 @@ import unittest  import hazwaz +class MySubCommand(hazwaz.Command): +    """ +    A subcommand. + +    This does very little. +    """ + +    def add_arguments(self, parser): +        super().add_arguments(parser) +        parser.add_argument( +            "--bar", +            action="store_true", +            help="barfoo things" +        ) + +    def main(self): +        print("Hello World") + +  class MyCommand(hazwaz.MainCommand):      """      A command that does things.      This is a command, but honestly it doesn't really do anything.      """ -    commands = () +    commands = ( +        MySubCommand(), +    )      def add_arguments(self, parser):          super().add_arguments(parser)          parser.add_argument(              "--foo", -            help="foobar things" +            action="store_true", +            help="foobar things",          ) @@ -68,12 +90,48 @@ class testCommand(unittest.TestCase):          self.assertIn("--verbose", cmd_help)          self.assertIn("--foo", cmd_help) +    def test_subparser(self): +        cmd = MyCommand() +        sub_parser = cmd.subparsers.choices["mysubcommand"] +        self.assertEqual(sub_parser.description, "A subcommand.") +        self.assertEqual( +            sub_parser.epilog, +            "This does very little.", +        ) +      def test_run(self):          cmd = MyCommand()          cmd_help = cmd.parser.format_help()          stream = self._run_with_argv(cmd, ["mycommand"])          self.assertEqual(stream["stdout"].getvalue(), cmd_help) +    def test_run_with_option(self): +        cmd = MyCommand() +        cmd_help = cmd.parser.format_help() +        stream = self._run_with_argv(cmd, [ +            "mycommand", +            "--verbose", +        ]) +        self.assertEqual(stream["stdout"].getvalue(), cmd_help) +        stream = self._run_with_argv(cmd, [ +            "mycommand", +            "--debug", +        ]) +        self.assertEqual(stream["stdout"].getvalue(), cmd_help) + +    def test_run_subcommand(self): +        cmd = MyCommand() +        stream = self._run_with_argv(cmd, ["mycommand", "mysubcommand"]) +        self.assertEqual(stream["stdout"].getvalue(), "Hello World\n") + +    def test_run_subcommand_with_option(self): +        cmd = MyCommand() +        stream = self._run_with_argv(cmd, [ +            "mycommand", +            "mysubcommand", +            "--bar", +        ]) +        self.assertEqual(stream["stdout"].getvalue(), "Hello World\n")  if __name__ == '__main__':  | 
