commands: Add basic format usage helper
This commit is contained in:
parent
754865d8b6
commit
fa7eee3bdf
@ -1,5 +1,6 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import collections
|
import collections
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class CommandError(Exception):
|
class CommandError(Exception):
|
||||||
@ -11,18 +12,19 @@ class Command(object):
|
|||||||
self._children = collections.OrderedDict()
|
self._children = collections.OrderedDict()
|
||||||
self._arguments = []
|
self._arguments = []
|
||||||
|
|
||||||
def _build_parser(self):
|
def _build(self):
|
||||||
|
actions = []
|
||||||
parser = argparse.ArgumentParser(add_help=False)
|
parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
|
||||||
for args, kwargs in self._arguments:
|
for args, kwargs in self._arguments:
|
||||||
parser.add_argument(*args, **kwargs)
|
actions.append(parser.add_argument(*args, **kwargs))
|
||||||
|
|
||||||
if self._children:
|
if self._children:
|
||||||
parser.add_argument('_args', nargs=argparse.REMAINDER)
|
parser.add_argument('_args', nargs=argparse.REMAINDER)
|
||||||
else:
|
else:
|
||||||
parser.set_defaults(_args=[])
|
parser.set_defaults(_args=[])
|
||||||
|
|
||||||
return parser
|
return parser, actions
|
||||||
|
|
||||||
def add_child(self, name, command):
|
def add_child(self, name, command):
|
||||||
self._children[name] = command
|
self._children[name] = command
|
||||||
@ -30,11 +32,17 @@ class Command(object):
|
|||||||
def add_argument(self, *args, **kwargs):
|
def add_argument(self, *args, **kwargs):
|
||||||
self._arguments.append((args, kwargs))
|
self._arguments.append((args, kwargs))
|
||||||
|
|
||||||
|
def format_usage(self, prog=None):
|
||||||
|
actions = self._build()[1]
|
||||||
|
formatter = argparse.HelpFormatter(prog or sys.argv[0])
|
||||||
|
formatter.add_usage(None, actions, [])
|
||||||
|
return formatter.format_help()
|
||||||
|
|
||||||
def parse(self, args, namespace=None):
|
def parse(self, args, namespace=None):
|
||||||
if not namespace:
|
if not namespace:
|
||||||
namespace = argparse.Namespace()
|
namespace = argparse.Namespace()
|
||||||
|
|
||||||
parser = self._build_parser()
|
parser = self._build()[0]
|
||||||
result, unknown = parser.parse_known_args(args, namespace)
|
result, unknown = parser.parse_known_args(args, namespace)
|
||||||
|
|
||||||
if unknown:
|
if unknown:
|
||||||
|
|||||||
@ -102,3 +102,39 @@ class CommandParsingTest(unittest.TestCase):
|
|||||||
|
|
||||||
result = cmd.parse([])
|
result = cmd.parse([])
|
||||||
self.assertEqual(result.command, cmd)
|
self.assertEqual(result.command, cmd)
|
||||||
|
|
||||||
|
|
||||||
|
class UsageTest(unittest.TestCase):
|
||||||
|
@mock.patch('sys.argv')
|
||||||
|
def test_basic_usage(self, argv_mock):
|
||||||
|
argv_mock.__getitem__.return_value = 'foo'
|
||||||
|
|
||||||
|
cmd = command.Command()
|
||||||
|
self.assertEqual('usage: foo', cmd.format_usage().strip())
|
||||||
|
|
||||||
|
self.assertEqual('usage: baz', cmd.format_usage('baz').strip())
|
||||||
|
|
||||||
|
cmd.add_argument('-h', '--help', action='store_true')
|
||||||
|
self.assertEqual('usage: foo [-h]', cmd.format_usage().strip())
|
||||||
|
|
||||||
|
cmd.add_argument('bar')
|
||||||
|
self.assertEqual('usage: foo [-h] bar', cmd.format_usage().strip())
|
||||||
|
|
||||||
|
@mock.patch('sys.argv')
|
||||||
|
def test_nested_usage(self, argv_mock):
|
||||||
|
argv_mock.__getitem__.return_value = 'foo'
|
||||||
|
|
||||||
|
child = command.Command()
|
||||||
|
cmd = command.Command()
|
||||||
|
cmd.add_child('bar', child)
|
||||||
|
|
||||||
|
self.assertEqual('usage: foo', cmd.format_usage().strip())
|
||||||
|
self.assertEqual('usage: foo bar', cmd.format_usage('foo bar').strip())
|
||||||
|
|
||||||
|
cmd.add_argument('-h', '--help', action='store_true')
|
||||||
|
self.assertEqual('usage: foo bar',
|
||||||
|
child.format_usage('foo bar').strip())
|
||||||
|
|
||||||
|
child.add_argument('-h', '--help', action='store_true')
|
||||||
|
self.assertEqual('usage: foo bar [-h]',
|
||||||
|
child.format_usage('foo bar').strip())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user