summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2019-10-02 19:36:48 +0000
committerGerrit Code Review <review@openstack.org>2019-10-02 19:36:48 +0000
commit9c561ef6c3e8f1de6b1ff8ce11fd660573f631c9 (patch)
tree229aea849354429dc5233798b06620e948eabf9d
parent5fb86ef7b4629f7682c6938823d719e133068b0d (diff)
parent8bcd068e876ddd48ae61c1803449d666f5e28ba0 (diff)
downloadcliff-9c561ef6c3e8f1de6b1ff8ce11fd660573f631c9.tar.gz
Merge "Allow finding command by partial name"
-rw-r--r--cliff/commandmanager.py23
-rw-r--r--cliff/tests/test_commandmanager.py54
2 files changed, 76 insertions, 1 deletions
diff --git a/cliff/commandmanager.py b/cliff/commandmanager.py
index 20cf17f..7350e32 100644
--- a/cliff/commandmanager.py
+++ b/cliff/commandmanager.py
@@ -23,6 +23,18 @@ from . import utils
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.
"""
@@ -97,8 +109,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:
diff --git a/cliff/tests/test_commandmanager.py b/cliff/tests/test_commandmanager.py
index 5a3f928..fae9d0a 100644
--- a/cliff/tests/test_commandmanager.py
+++ b/cliff/tests/test_commandmanager.py
@@ -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))