M test/test_cli_commands.py +19 -0
@@ 107,5 107,24 @@ class TestCliCommands(unittest.TestCase)
self.assertEqual(opts, dict(verbose=True, quiet=None))
+ def test_decorated_table(self):
+ cmds = commander.CommandTable([])
+ @cmds.add('frob')
+ def frob(test):
+ return test
+ @cmds.add('blipp', opts=[('check', 'c', None, 'be careful')])
+ def blipp(also):
+ return also + 1
+
+ arguments = 'frob -v'.split()
+ cmd, opts, args = commander.parse(GOPT_A, cmds, arguments)
+ self.assertEqual(cmd.target, frob)
+ self.assertTrue(opts['verbose'])
+ arguments = 'bli -c'.split()
+ cmd, opts, args = commander.parse(GOPT_A, cmds, arguments)
+ self.assertEqual(cmd.target, blipp)
+ self.assertTrue(opts['check'])
+
+
if __name__ == '__main__':
unittest.main()
M vanity/commander.py +20 -3
@@ 158,9 158,26 @@ class CommandTable(object):
else:
raise AmbiguousCommand(canidates)
- # TODO: "add" decorator
-
-
+ def add(self, name=None, aliases=None, opts=None, help=None):
+ """Returns a decorator to add a function to the current table.
+
+ * ``name`` - command name; automatically determined if not given
+ * ``aliases`` - a pipe delimited strint of alternate names
+ * ``opts`` - an options table; see vanity.cli for details
+ * ``help`` - a short command help string
+ """
+ if not name:
+ name = func.__name__
+ if not opts:
+ opts = []
+ if not help:
+ help = '[OPTIONS] [ARGS]'
+ def _wrap(func):
+ cmd = Command(name, func, aliases, opts, help)
+ self._table[cmd.name] = cmd
+ return func
+ return _wrap
+
'''