Allow finding command by partial name
This small improvement helps to decrease the amount of typing. $ openstack resource provider list ... ^ too long? $ alias os=openstack $ os r p l ... ^ much better! Change-Id: I713eab2bd9f949da01c03b65ff16a01de92e3e62
This commit is contained in:
@@ -22,6 +22,18 @@ import pkg_resources
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_commands_by_partial_name(args, commands):
|
||||
n = len(args)
|
||||
candidates = []
|
||||
for command_name in commands:
|
||||
command_parts = command_name.split()
|
||||
if len(command_parts) != n:
|
||||
continue
|
||||
if all(command_parts[i].startswith(args[i]) for i in range(n)):
|
||||
candidates.append(command_name)
|
||||
return candidates
|
||||
|
||||
|
||||
class EntryPointWrapper(object):
|
||||
"""Wrap up a command class already imported to make it look like a plugin.
|
||||
"""
|
||||
@@ -96,8 +108,17 @@ class CommandManager(object):
|
||||
# Convert the legacy command name to its new name.
|
||||
if name in self._legacy:
|
||||
name = self._legacy[name]
|
||||
|
||||
found = None
|
||||
if name in self.commands:
|
||||
cmd_ep = self.commands[name]
|
||||
found = name
|
||||
else:
|
||||
candidates = _get_commands_by_partial_name(
|
||||
argv[:i], self.commands)
|
||||
if len(candidates) == 1:
|
||||
found = candidates[0]
|
||||
if found:
|
||||
cmd_ep = self.commands[found]
|
||||
if hasattr(cmd_ep, 'resolve'):
|
||||
cmd_factory = cmd_ep.resolve()
|
||||
else:
|
||||
|
||||
@@ -199,3 +199,57 @@ class TestLegacyCommand(base.TestBase):
|
||||
mgr.find_command,
|
||||
['cmd2'],
|
||||
)
|
||||
|
||||
|
||||
class TestLookupAndFindPartialName(base.TestBase):
|
||||
|
||||
scenarios = [
|
||||
('one-word', {'argv': ['o']}),
|
||||
('two-words', {'argv': ['t', 'w']}),
|
||||
('three-words', {'argv': ['t', 'w', 'c']}),
|
||||
]
|
||||
|
||||
def test(self):
|
||||
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
|
||||
cmd, name, remaining = mgr.find_command(self.argv)
|
||||
self.assertTrue(cmd)
|
||||
self.assertEqual(' '.join(self.argv), name)
|
||||
self.assertFalse(remaining)
|
||||
|
||||
|
||||
class TestGetByPartialName(base.TestBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetByPartialName, self).setUp()
|
||||
self.commands = {
|
||||
'resource provider list': 1,
|
||||
'resource class list': 2,
|
||||
'server list': 3,
|
||||
'service list': 4}
|
||||
|
||||
def test_no_candidates(self):
|
||||
self.assertEqual(
|
||||
[], commandmanager._get_commands_by_partial_name(
|
||||
['r', 'p'], self.commands))
|
||||
self.assertEqual(
|
||||
[], commandmanager._get_commands_by_partial_name(
|
||||
['r', 'p', 'c'], self.commands))
|
||||
|
||||
def test_multiple_candidates(self):
|
||||
self.assertEqual(
|
||||
2, len(commandmanager._get_commands_by_partial_name(
|
||||
['se', 'li'], self.commands)))
|
||||
|
||||
def test_one_candidate(self):
|
||||
self.assertEqual(
|
||||
['resource provider list'],
|
||||
commandmanager._get_commands_by_partial_name(
|
||||
['r', 'p', 'l'], self.commands))
|
||||
self.assertEqual(
|
||||
['resource provider list'],
|
||||
commandmanager._get_commands_by_partial_name(
|
||||
['resource', 'provider', 'list'], self.commands))
|
||||
self.assertEqual(
|
||||
['server list'],
|
||||
commandmanager._get_commands_by_partial_name(
|
||||
['serve', 'l'], self.commands))
|
||||
|
||||
Reference in New Issue
Block a user