add before and after hooks
Add hooks that are called before and after the take_action() method of the command. Change-Id: Id6527dfe0946c0ab169fc165b84d40f3ff95e08c Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
45de8e45ef
commit
95c749d55e
|
@ -133,7 +133,12 @@ class Command(object):
|
||||||
|
|
||||||
Return the value returned by :meth:`take_action` or 0.
|
Return the value returned by :meth:`take_action` or 0.
|
||||||
"""
|
"""
|
||||||
return self.take_action(parsed_args) or 0
|
for hook in self._hooks:
|
||||||
|
hook.obj.before(parsed_args)
|
||||||
|
return_code = self.take_action(parsed_args) or 0
|
||||||
|
for hook in self._hooks:
|
||||||
|
hook.obj.after(parsed_args, return_code)
|
||||||
|
return return_code
|
||||||
|
|
||||||
|
|
||||||
class _SmartHelpFormatter(_argparse.HelpFormatter):
|
class _SmartHelpFormatter(_argparse.HelpFormatter):
|
||||||
|
|
|
@ -41,3 +41,25 @@ class CommandHook(object):
|
||||||
def get_epilog(self):
|
def get_epilog(self):
|
||||||
"Return text to add to the command help epilog."
|
"Return text to add to the command help epilog."
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def before(self, parsed_args):
|
||||||
|
"""Called before the command's take_action() method.
|
||||||
|
|
||||||
|
Any return value is ignored.
|
||||||
|
|
||||||
|
:param parsed_args: The arguments to the command.
|
||||||
|
:paramtype parsed_args: argparse.Namespace
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def after(self, parsed_args, return_code):
|
||||||
|
"""Called after the command's take_action() method.
|
||||||
|
|
||||||
|
Any return value is ignored.
|
||||||
|
|
||||||
|
:param parsed_args: The arguments to the command.
|
||||||
|
:paramtype parsed_args: argparse.Namespace
|
||||||
|
:param return_code: The value returned from take_action().
|
||||||
|
:paramtype return_code: int
|
||||||
|
"""
|
||||||
|
|
|
@ -62,6 +62,9 @@ class TestCommand(command.Command):
|
||||||
|
|
||||||
class TestHook(hooks.CommandHook):
|
class TestHook(hooks.CommandHook):
|
||||||
|
|
||||||
|
_before_called = False
|
||||||
|
_after_called = False
|
||||||
|
|
||||||
def get_parser(self, parser):
|
def get_parser(self, parser):
|
||||||
parser.add_argument('--added-by-hook')
|
parser.add_argument('--added-by-hook')
|
||||||
return parser
|
return parser
|
||||||
|
@ -69,6 +72,12 @@ class TestHook(hooks.CommandHook):
|
||||||
def get_epilog(self):
|
def get_epilog(self):
|
||||||
return 'hook epilog'
|
return 'hook epilog'
|
||||||
|
|
||||||
|
def before(self, parsed_args):
|
||||||
|
self._before_called = True
|
||||||
|
|
||||||
|
def after(self, parsed_args, return_code):
|
||||||
|
self._after_called = True
|
||||||
|
|
||||||
|
|
||||||
class TestCommandLoadHooks(base.TestBase):
|
class TestCommandLoadHooks(base.TestBase):
|
||||||
|
|
||||||
|
@ -112,3 +121,13 @@ class TestHooks(base.TestBase):
|
||||||
def test_get_epilog(self):
|
def test_get_epilog(self):
|
||||||
results = self.cmd.get_epilog()
|
results = self.cmd.get_epilog()
|
||||||
self.assertIn('hook epilog', results)
|
self.assertIn('hook epilog', results)
|
||||||
|
|
||||||
|
def test_before(self):
|
||||||
|
self.assertFalse(self.hook._before_called)
|
||||||
|
self.cmd.run(None)
|
||||||
|
self.assertTrue(self.hook._before_called)
|
||||||
|
|
||||||
|
def test_after(self):
|
||||||
|
self.assertFalse(self.hook._after_called)
|
||||||
|
self.cmd.run(None)
|
||||||
|
self.assertTrue(self.hook._after_called)
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Hooked(Command):
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
self.app.stdout.write('this command has an extension')
|
self.app.stdout.write('this command has an extension\n')
|
||||||
|
|
||||||
|
|
||||||
class Hook(CommandHook):
|
class Hook(CommandHook):
|
||||||
|
@ -42,3 +42,9 @@ class Hook(CommandHook):
|
||||||
|
|
||||||
def get_epilog(self):
|
def get_epilog(self):
|
||||||
return 'extension epilog text'
|
return 'extension epilog text'
|
||||||
|
|
||||||
|
def before(self, parsed_args):
|
||||||
|
self.cmd.app.stdout.write('before\n')
|
||||||
|
|
||||||
|
def after(self, parsed_args, return_code):
|
||||||
|
self.cmd.app.stdout.write('after\n')
|
||||||
|
|
|
@ -295,6 +295,12 @@ single ``--added-by-hook`` option.
|
||||||
|
|
||||||
extension epilog text
|
extension epilog text
|
||||||
|
|
||||||
|
(.venv)$ cliffdemo hooked
|
||||||
|
sample hook get_parser()
|
||||||
|
before
|
||||||
|
this command has an extension
|
||||||
|
after
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
:class:`cliff.hooks.CommandHook` -- The API for command hooks.
|
:class:`cliff.hooks.CommandHook` -- The API for command hooks.
|
||||||
|
|
Loading…
Reference in New Issue