Skip to content

Commit

Permalink
Add lineage attribute across commands
Browse files Browse the repository at this point in the history
  • Loading branch information
kyleknap committed Feb 6, 2015
1 parent 7350250 commit 4bd57fa
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
39 changes: 39 additions & 0 deletions awscli/clidriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ def name(self, value):
# Subclasses must implement setting/changing the cmd name.
raise NotImplementedError("name")

@property
def lineage(self):
# Represents how to get to a specific command using the CLI.
# It includes all commands that came before it and itself in
# a list.
return [self]

def __call__(self, args, parsed_globals):
"""Invoke CLI operation.
Expand Down Expand Up @@ -324,6 +331,7 @@ def __init__(self, cli_name, session, service_name=None):
self._service_name = cli_name
else:
self._service_name = service_name
self._lineage = [self]

@property
def name(self):
Expand All @@ -337,6 +345,14 @@ def name(self, value):
def service_object(self):
return self._service_object

@property
def lineage(self):
return self._lineage

@lineage.setter
def lineage(self, value):
self._lineage = value

def _get_command_table(self):
if self._command_table is None:
self._command_table = self._create_command_table()
Expand Down Expand Up @@ -371,8 +387,14 @@ def _create_command_table(self):
command_table=command_table,
session=self.session,
command_object=self)
self._add_lineage(command_table)
return command_table

def _add_lineage(self, command_table):
for command in command_table:
command_obj = command_table[command]
command_obj.lineage = self.lineage + [command_obj]

def create_help_command(self):
command_table = self._get_command_table()
service_object = self._get_service_object()
Expand Down Expand Up @@ -434,6 +456,23 @@ def __init__(self, name, parent_name, operation_object, operation_caller,
self._operation_object = operation_object
self._operation_caller = operation_caller
self._service_object = service_object
self._lineage = [self]

@property
def name(self):
return self._name

@name.setter
def name(self, value):
self._name = value

@property
def lineage(self):
return self._lineage

@lineage.setter
def lineage(self, value):
self._lineage = value

@property
def arg_table(self):
Expand Down
15 changes: 15 additions & 0 deletions awscli/customizations/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def __init__(self, session):
self._session = session
self._arg_table = None
self._subcommand_table = None
self._lineage = [self]

def __call__(self, args, parsed_globals):
# args is the remaining unparsed args.
Expand Down Expand Up @@ -213,6 +214,7 @@ def _build_subcommand_table(self):
command_table=subcommand_table,
session=self._session,
command_object=self)
self._add_lineage(subcommand_table)
return subcommand_table

def _display_help(self, parsed_args, parsed_globals):
Expand Down Expand Up @@ -253,6 +255,11 @@ def _build_arg_table(self):
arg_table[arg_data['name']] = custom_argument
return arg_table

def _add_lineage(self, command_table):
for command in command_table:
command_obj = command_table[command]
command_obj.lineage = self.lineage + [command_obj]

@property
def arg_table(self):
if self._arg_table is None:
Expand All @@ -273,6 +280,14 @@ def add_command(cls, command_table, session, **kwargs):
def name(self):
return self.NAME

@property
def lineage(self):
return self._lineage

@lineage.setter
def lineage(self, value):
self._lineage = value


class BasicHelp(HelpCommand):
event_class = 'command'
Expand Down
1 change: 1 addition & 0 deletions awscli/customizations/waiters.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def _run_main(self, parsed_args, parsed_globals):
def _build_subcommand_table(self):
subcommand_table = super(WaitCommand, self)._build_subcommand_table()
self.waiter_cmd_builder.build_all_waiter_state_cmds(subcommand_table)
self._add_lineage(subcommand_table)
return subcommand_table

def create_help_command(self):
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/customizations/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,18 @@ def test_load_subcommand_table_property(self):
# Ensure the ``subcommand_table`` is not built again if
# ``subcommand_table`` property is called again.
self.assertIs(orig_subcommand_table, self.command.subcommand_table)

def test_load_lineage(self):
self.assertEqual(self.command.lineage, [self.command])

def test_pass_lineage_to_child_command(self):
subcommands = [{'name': 'bar', 'command_class': BasicCommand}]
basic_command_class = 'awscli.customizations.commands.BasicCommand'
name_patch = basic_command_class + '.NAME'
subcommand_patch = basic_command_class + '.SUBCOMMANDS'
with mock.patch(subcommand_patch, subcommands):
lineage = self.command.subcommand_table['bar'].lineage
self.assertEqual(len(lineage), 2)
self.assertEqual(lineage[0], self.command)
self.assertIsInstance(lineage[1], BasicCommand)

6 changes: 6 additions & 0 deletions tests/unit/customizations/test_waiters.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ def setUp(self):
self.service_object = mock.Mock()
self.cmd = WaitCommand(self.model, self.service_object)

def test_passes_on_lineage(self):
child_cmd = self.cmd.subcommand_table['foo']
self.assertEqual(len(child_cmd.lineage), 2)
self.assertEqual(child_cmd.lineage[0], self.cmd)
self.assertIsInstance(child_cmd.lineage[1], WaiterStateCommand)

def test_run_main_error(self):
self.parsed_args = mock.Mock()
self.parsed_args.subcommand = None
Expand Down

0 comments on commit 4bd57fa

Please sign in to comment.