Merge "Implement Parameter Deprecation"
This commit is contained in:
commit
91bac9bd79
@ -35,6 +35,12 @@ from six import moves
|
||||
from magnumclient.i18n import _
|
||||
|
||||
|
||||
def deprecation_message(preamble, new_name):
|
||||
msg = ('%s This parameter is deprecated and will be removed in a future '
|
||||
'release. Use --%s instead.' % (preamble, new_name))
|
||||
return msg
|
||||
|
||||
|
||||
class MissingArgs(Exception):
|
||||
"""Supplied arguments are not sufficient for calling a function."""
|
||||
def __init__(self, missing):
|
||||
@ -77,14 +83,14 @@ def validate_args(fn, *args, **kwargs):
|
||||
|
||||
|
||||
def deprecated(message):
|
||||
'''Decorator for marking a call as deprecated by printing a given message.
|
||||
"""Decorator for marking a call as deprecated by printing a given message.
|
||||
|
||||
Example:
|
||||
>>> @deprecated("Bay functions are deprecated and should be replaced by "
|
||||
... "calls to cluster")
|
||||
... def bay_create(args):
|
||||
... pass
|
||||
'''
|
||||
"""
|
||||
@decorator.decorator
|
||||
def wrapper(func, *args, **kwargs):
|
||||
print(message)
|
||||
@ -92,6 +98,57 @@ def deprecated(message):
|
||||
return wrapper
|
||||
|
||||
|
||||
def deprecation_map(dep_map):
|
||||
"""Decorator for applying a map of deprecating arguments to a function.
|
||||
|
||||
The map connects deprecating arguments and their replacements. The
|
||||
shell.py script uses this map to create mutually exclusive argument groups
|
||||
in argparse and also prints a deprecation warning telling the user to
|
||||
switch to the updated argument.
|
||||
|
||||
NOTE: This decorator MUST be the outermost in the chain of argument
|
||||
decorators to work correctly.
|
||||
|
||||
Example usage:
|
||||
>>> @deprecation_map({ "old-argument": "new-argument" })
|
||||
... @args("old-argument", required=True)
|
||||
... @args("new-argument", required=True)
|
||||
... def do_command_line_stuff():
|
||||
... pass
|
||||
"""
|
||||
def _decorator(func):
|
||||
if not hasattr(func, 'arguments'):
|
||||
return func
|
||||
|
||||
func.deprecated_groups = []
|
||||
for old_param, new_param in dep_map.items():
|
||||
old_info, new_info = None, None
|
||||
required = False
|
||||
for (args, kwargs) in func.arguments:
|
||||
if old_param in args:
|
||||
old_info = (args, kwargs)
|
||||
# Old arguments shouldn't be required if they were not
|
||||
# previously, so prioritize old requirement
|
||||
if 'required' in kwargs:
|
||||
required = kwargs['required']
|
||||
# Set to false so argparse doesn't get angry
|
||||
kwargs['required'] = False
|
||||
elif new_param in args:
|
||||
new_info = (args, kwargs)
|
||||
kwargs['required'] = False
|
||||
if old_info and new_info:
|
||||
break
|
||||
# Add a tuple of (old, new, required), which in turn is:
|
||||
# ((old_args, old_kwargs), (new_args, new_kwargs), required)
|
||||
func.deprecated_groups.append((old_info, new_info, required))
|
||||
# Remove arguments that would be duplicated by the groups we made
|
||||
func.arguments.remove(old_info)
|
||||
func.arguments.remove(new_info)
|
||||
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def arg(*args, **kwargs):
|
||||
"""Decorator for CLI args.
|
||||
|
||||
|
@ -459,6 +459,7 @@ class OpenStackMagnumShell(object):
|
||||
desc = callback.__doc__ or ''
|
||||
action_help = desc.strip()
|
||||
arguments = getattr(callback, 'arguments', [])
|
||||
group_args = getattr(callback, 'deprecated_groups', [])
|
||||
|
||||
subparser = (
|
||||
subparsers.add_parser(command,
|
||||
@ -471,6 +472,12 @@ class OpenStackMagnumShell(object):
|
||||
action='help',
|
||||
help=argparse.SUPPRESS,)
|
||||
self.subcommands[command] = subparser
|
||||
|
||||
for (old_info, new_info, req) in group_args:
|
||||
group = subparser.add_mutually_exclusive_group(required=req)
|
||||
group.add_argument(*old_info[0], **old_info[1])
|
||||
group.add_argument(*new_info[0], **new_info[1])
|
||||
|
||||
for (args, kwargs) in arguments:
|
||||
subparser.add_argument(*args, **kwargs)
|
||||
subparser.set_defaults(func=callback)
|
||||
@ -630,8 +637,31 @@ class OpenStackMagnumShell(object):
|
||||
api_version=args.magnum_api_version,
|
||||
)
|
||||
|
||||
self._check_deprecation(args.func, argv)
|
||||
args.func(self.cs, args)
|
||||
|
||||
def _check_deprecation(self, func, argv):
|
||||
if not hasattr(func, 'deprecated_groups'):
|
||||
return
|
||||
|
||||
for (old_info, new_info, required) in func.deprecated_groups:
|
||||
old_param = old_info[0][0]
|
||||
new_param = new_info[0][0]
|
||||
old_value, new_value = None, None
|
||||
for i in range(len(argv)):
|
||||
cur_arg = argv[i]
|
||||
if cur_arg == old_param:
|
||||
old_value = argv[i + 1]
|
||||
elif cur_arg == new_param[0]:
|
||||
new_value = argv[i + 1]
|
||||
|
||||
if old_value and not new_value:
|
||||
print(
|
||||
'WARNING: The %s parameter is deprecated and will be '
|
||||
'removed in a future release. Use the %s parameter to '
|
||||
'avoid seeing this message.'
|
||||
% (old_param, new_param))
|
||||
|
||||
def _dump_timings(self, timings):
|
||||
class Tyme(object):
|
||||
def __init__(self, url, seconds):
|
||||
|
Loading…
x
Reference in New Issue
Block a user