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 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``')