Fix help message in case of microversions

novaclient should display help message of the proper versioned method
(based on api_version value).

Closes-Bug: #1523649
Closes-Bug: #1523651

Change-Id: I67f7fc2befde9d312400e9a1569e590bd763156e
This commit is contained in:
Andrey Kurilin 2015-12-07 20:05:49 +02:00
parent 06af0bf79b
commit 8aaf0a9080
4 changed files with 45 additions and 18 deletions

View File

@ -343,7 +343,7 @@ def get_substitutions(func_name, api_version=None):
if api_version and not api_version.is_null():
return [m for m in substitutions
if api_version.matches(m.start_version, m.end_version)]
return substitutions
return sorted(substitutions, key=lambda m: m.start_version)
def wraps(start_version, end_version=None):
@ -368,9 +368,7 @@ def wraps(start_version, end_version=None):
raise exceptions.VersionNotFoundForAPIMethod(
obj.api_version.get_string(), name)
method = max(methods, key=lambda f: f.start_version)
return method.func(obj, *args, **kwargs)
return methods[-1].func(obj, *args, **kwargs)
if hasattr(func, 'arguments'):
for cli_args, cli_kwargs in func.arguments:

View File

@ -59,6 +59,9 @@ DEFAULT_OS_COMPUTE_API_VERSION = '2.latest'
DEFAULT_NOVA_ENDPOINT_TYPE = 'publicURL'
DEFAULT_NOVA_SERVICE_TYPE = "compute"
HINT_HELP_MSG = (" [hint: use '--os-compute-api-version' flag to show help "
"message for proper version]")
logger = logging.getLogger(__name__)
@ -466,19 +469,26 @@ class OpenStackComputeShell(object):
callback = getattr(actions_module, attr)
desc = callback.__doc__ or ''
if hasattr(callback, "versioned"):
additional_msg = ""
subs = api_versions.get_substitutions(
utils.get_function_name(callback))
if do_help:
desc += msg % {'start': subs[0].start_version.get_string(),
'end': subs[-1].end_version.get_string()}
else:
for versioned_method in subs:
additional_msg = msg % {
'start': subs[0].start_version.get_string(),
'end': subs[-1].end_version.get_string()}
if version.is_latest():
additional_msg += HINT_HELP_MSG
subs = [versioned_method for versioned_method in subs
if version.matches(versioned_method.start_version,
versioned_method.end_version):
callback = versioned_method.func
break
else:
continue
versioned_method.end_version)]
if subs:
# use the "latest" substitution
callback = subs[-1].func
else:
# there is no proper versioned method
continue
desc = callback.__doc__ or desc
desc += additional_msg
action_help = desc.strip()
arguments = getattr(callback, 'arguments', [])

View File

@ -27,6 +27,11 @@ def do_fake_action():
return 2
@api_versions.wraps("2.0")
def do_another_fake_action():
return 0
@cliutils.arg(
'--foo',
start_version='2.1',

View File

@ -582,12 +582,27 @@ class TestLoadVersionedActions(utils.TestCase):
shell = novaclient.shell.OpenStackComputeShell()
shell.subcommands = {}
shell._find_actions(subparsers, fake_actions_module,
api_versions.APIVersion("2.10000"), True)
api_versions.APIVersion("2.15"), True)
self.assertIn('fake-action', shell.subcommands.keys())
expected_desc = ("(Supported by API versions '%(start)s' - "
expected_desc = (" (Supported by API versions '%(start)s' - "
"'%(end)s')") % {'start': '2.10', 'end': '2.30'}
self.assertIn(expected_desc,
shell.subcommands['fake-action'].description)
self.assertEqual(expected_desc,
shell.subcommands['fake-action'].description)
def test_load_versioned_actions_with_help_on_latest(self):
parser = novaclient.shell.NovaClientArgumentParser()
subparsers = parser.add_subparsers(metavar='<subcommand>')
shell = novaclient.shell.OpenStackComputeShell()
shell.subcommands = {}
shell._find_actions(subparsers, fake_actions_module,
api_versions.APIVersion("2.latest"), True)
self.assertIn('another-fake-action', shell.subcommands.keys())
expected_desc = (" (Supported by API versions '%(start)s' - "
"'%(end)s')%(hint)s") % {
'start': '2.0', 'end': '2.latest',
'hint': novaclient.shell.HINT_HELP_MSG}
self.assertEqual(expected_desc,
shell.subcommands['another-fake-action'].description)
@mock.patch.object(novaclient.shell.NovaClientArgumentParser,
'add_argument')
@ -641,7 +656,6 @@ class TestLoadVersionedActions(utils.TestCase):
shell._find_actions(subparsers, fake_actions_module,
api_versions.APIVersion("2.4"), True)
mock_add_arg.assert_has_calls([
mock.call('-h', '--help', action='help', help='==SUPPRESS=='),
mock.call('-h', '--help', action='help', help='==SUPPRESS=='),
mock.call('--foo',
help=" (Supported by API versions '2.1' - '2.2')"),