From 903455163d6da3c802a2f4e79fde5db3dfedc6aa Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Thu, 29 Aug 2013 12:45:26 -0700 Subject: [PATCH 1/2] Add group_name to arguments Also unify the public attrs that were added in CLIArgs but not added to the base class. In general, all public interfaces need to be defined in the base CLI class to make it clear what subclasses need to implement. --- awscli/arguments.py | 47 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/awscli/arguments.py b/awscli/arguments.py index 3ba10b6f3190..3ee04bf45ae1 100644 --- a/awscli/arguments.py +++ b/awscli/arguments.py @@ -92,6 +92,10 @@ def add_to_params(self, parameters, value): """ pass + @property + def name(self): + return self._name + @property def cli_name(self): return '--' + self._name @@ -108,18 +112,37 @@ def required(self): def documentation(self): raise NotImplementedError("documentation") + @property + def cli_type(self): + raise NotImplementedError("cli_type") + @property def py_name(self): return self._name.replace('-', '_') @property - def name(self): - return self._name + def choices(self): + return None @name.setter def name(self, value): self._name = value + @property + def group_name(self): + """Get the group name associated with the argument. + + An argument can be part of a group. This property will + return the name of that group. + + This base class has no default behavior for groups, code + that consumes argument objects can use them for whatever + purposes they like (documentation, mututally exclusive group + validation, etc.). + + """ + return None + class CustomArgument(BaseCLIArgument): """ @@ -133,7 +156,7 @@ class CustomArgument(BaseCLIArgument): def __init__(self, name, help_text='', dest=None, default=None, action=None, required=None, choices=None, nargs=None, - cli_type_name=None): + cli_type_name=None, group_name=None): self._name = name self._help = help_text self._dest = dest @@ -142,6 +165,7 @@ def __init__(self, name, help_text='', dest=None, default=None, self._required = required self._nargs = nargs self._cli_type_name = cli_type_name + self._group_name = group_name if choices is None: choices = [] self._choices = choices @@ -204,6 +228,10 @@ def cli_type(self): def choices(self): return self._choices + @property + def group_name(self): + return self._group_name + class CLIArgument(BaseCLIArgument): """Represents a CLI argument that maps to a service parameter. @@ -369,7 +397,7 @@ class BooleanArgument(CLIArgument): """ def __init__(self, name, argument_object, operation_object, - action='store_true', dest=None): + action='store_true', dest=None, group_name=None): super(BooleanArgument, self).__init__(name, argument_object, operation_object) self._mutex_group = None @@ -378,6 +406,10 @@ def __init__(self, name, argument_object, operation_object, self._destination = self.py_name else: self._destination = dest + if group_name is None: + self._group_name = self.name + else: + self._group_name = group_name def add_to_params(self, parameters, value): # If a value was explicitly specified (so value is True/False @@ -399,7 +431,8 @@ def add_to_arg_table(self, argument_table): negative_version = self.__class__(negative_name, self.argument_object, self.operation_object, action='store_false', - dest=self._destination) + dest=self._destination, + group_name=self.group_name) argument_table[negative_name] = negative_version def add_to_parser(self, parser): @@ -408,3 +441,7 @@ def add_to_parser(self, parser): action=self._action, default=None, dest=self._destination) + + @property + def group_name(self): + return self._group_name From bc688f49ab624fb92f29d23e3d880afb0f6a975a Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Thu, 29 Aug 2013 12:51:54 -0700 Subject: [PATCH 2/2] Add extra test for boolean arg merging --- tests/unit/docs/test_help_output.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/unit/docs/test_help_output.py b/tests/unit/docs/test_help_output.py index 7175e40dd881..746db33683c7 100644 --- a/tests/unit/docs/test_help_output.py +++ b/tests/unit/docs/test_help_output.py @@ -156,9 +156,8 @@ def test_boolean_param_documented(self): self.driver.main(['autoscaling', 'terminate-instance-in-auto-scaling-group', 'help']) self.assert_contains( - '``--should-decrement-desired-capacity`` (boolean)') - self.assert_contains( - '``--no-should-decrement-desired-capacity`` (boolean)') + ('``--should-decrement-desired-capacity`` | ' + '``--no-should-decrement-desired-capacity`` (boolean)')) def test_streaming_output_arg(self): self.driver.main(['s3api', 'get-object', 'help']) @@ -193,3 +192,15 @@ def test_builtin_paging_params_removed(self): self.driver.main(['s3api', 'list-objects', 'help']) self.assert_not_contains('``--next-token``') self.assert_not_contains('``--max-keys``') + + +class TestMergeBooleanGroupArgs(BaseAWSHelpOutputTest): + def test_merge_bool_args(self): + # Boolean args need to be group together so rather than + # --foo foo docs + # --no-foo foo docs again + # + # We instead have: + # --foo | --no-foo foo docs + self.driver.main(['ec2', 'run-instances', 'help']) + self.assert_contains('``--dry-run`` | ``--no-dry-run``')