diff --git a/cliff/commandmanager.py b/cliff/commandmanager.py index 7350e326..d9f74392 100644 --- a/cliff/commandmanager.py +++ b/cliff/commandmanager.py @@ -61,6 +61,7 @@ class CommandManager(object): self._legacy = {} self.namespace = namespace self.convert_underscores = convert_underscores + self.group_list = [] self._load_commands() def _load_commands(self): @@ -70,6 +71,7 @@ class CommandManager(object): def load_commands(self, namespace): """Load all the commands from an entrypoint""" + self.group_list.append(namespace) for ep in pkg_resources.iter_entry_points(namespace): LOG.debug('found command %r', ep.name) cmd_name = (ep.name.replace('_', ' ') @@ -143,3 +145,26 @@ class CommandManager(object): if arg.startswith('-'): return i return len(argv) + + def add_command_group(self, group=None): + """Adds another group of command entrypoints""" + if group: + self.load_commands(group) + + def get_command_groups(self): + """Returns a list of the loaded command groups""" + return self.group_list + + def get_command_names(self, group=None): + """Returns a list of commands loaded for the specified group""" + group_list = [] + if group is not None: + for ep in pkg_resources.iter_entry_points(group): + cmd_name = ( + ep.name.replace('_', ' ') + if self.convert_underscores + else ep.name + ) + group_list.append(cmd_name) + return group_list + return list(self.commands.keys()) diff --git a/cliff/tests/test_commandmanager.py b/cliff/tests/test_commandmanager.py index 27b97d66..a704658d 100644 --- a/cliff/tests/test_commandmanager.py +++ b/cliff/tests/test_commandmanager.py @@ -253,3 +253,92 @@ class TestGetByPartialName(base.TestBase): ['server list'], commandmanager._get_commands_by_partial_name( ['serve', 'l'], self.commands)) + + +class FakeCommand(object): + + @classmethod + def load(cls): + return cls + + def __init__(self): + return + + +FAKE_CMD_ONE = FakeCommand +FAKE_CMD_TWO = FakeCommand +FAKE_CMD_ALPHA = FakeCommand +FAKE_CMD_BETA = FakeCommand + + +class FakeCommandManager(commandmanager.CommandManager): + commands = {} + + def load_commands(self, namespace): + if namespace == 'test': + self.commands['one'] = FAKE_CMD_ONE + self.commands['two'] = FAKE_CMD_TWO + self.group_list.append(namespace) + elif namespace == 'greek': + self.commands['alpha'] = FAKE_CMD_ALPHA + self.commands['beta'] = FAKE_CMD_BETA + self.group_list.append(namespace) + + +class TestCommandManagerGroups(base.TestBase): + + def test_add_command_group(self): + mgr = FakeCommandManager('test') + + # Make sure add_command() still functions + mock_cmd_one = mock.Mock() + mgr.add_command('mock', mock_cmd_one) + cmd_mock, name, args = mgr.find_command(['mock']) + self.assertEqual(mock_cmd_one, cmd_mock) + + # Find a command added in initialization + cmd_one, name, args = mgr.find_command(['one']) + self.assertEqual(FAKE_CMD_ONE, cmd_one) + + # Load another command group + mgr.add_command_group('greek') + + # Find a new command + cmd_alpha, name, args = mgr.find_command(['alpha']) + self.assertEqual(FAKE_CMD_ALPHA, cmd_alpha) + + # Ensure that the original commands were not overwritten + cmd_two, name, args = mgr.find_command(['two']) + self.assertEqual(FAKE_CMD_TWO, cmd_two) + + def test_get_command_groups(self): + mgr = FakeCommandManager('test') + + # Make sure add_command() still functions + mock_cmd_one = mock.Mock() + mgr.add_command('mock', mock_cmd_one) + cmd_mock, name, args = mgr.find_command(['mock']) + self.assertEqual(mock_cmd_one, cmd_mock) + + # Load another command group + mgr.add_command_group('greek') + + gl = mgr.get_command_groups() + self.assertEqual(['test', 'greek'], gl) + + def test_get_command_names(self): + mock_cmd_one = mock.Mock() + mock_cmd_one.name = 'one' + mock_cmd_two = mock.Mock() + mock_cmd_two.name = 'cmd two' + mock_pkg_resources = mock.Mock( + return_value=[mock_cmd_one, mock_cmd_two], + ) + with mock.patch( + 'pkg_resources.iter_entry_points', + mock_pkg_resources, + ) as iter_entry_points: + mgr = commandmanager.CommandManager('test') + iter_entry_points.assert_called_once_with('test') + cmds = mgr.get_command_names('test') + self.assertEqual(['one', 'cmd two'], cmds) diff --git a/releasenotes/notes/command-group-8c00f260340a130c.yaml b/releasenotes/notes/command-group-8c00f260340a130c.yaml new file mode 100644 index 00000000..d832572a --- /dev/null +++ b/releasenotes/notes/command-group-8c00f260340a130c.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added support for command groups. This was originally added + in osc_lib downstream.