Expanding parser actions to allow for multiple key-value pairs
KeyValueAction previously allowed only one key=>value pair to be supplied in the CLI per argument. While the operator could supply multiple key=>value pairs by repeatedly using the same argument it was unnecessarily verbose and tedious approach. Similar behavior is implemented in the tripleoclient validator CLI by the resulution to the rhbz#1959492 [0]. Tests were adjusted. [0]https://bugzilla.redhat.com/show_bug.cgi?id=1959492: Signed-off-by: Jiri Podivin <jpodivin@redhat.com> Change-Id: I28c40bb8156d73dd95af9641acaab3cce721be2d
This commit is contained in:
parent
9047bbb317
commit
5cad282b80
@ -16,6 +16,8 @@
|
||||
|
||||
import argparse
|
||||
|
||||
from validations_libs.utils import LOG
|
||||
|
||||
|
||||
class CommaListAction(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
@ -33,16 +35,29 @@ class KeyValueAction(argparse.Action):
|
||||
setattr(namespace, self.dest, {})
|
||||
|
||||
# Add value if an assignment else remove it
|
||||
if values.count('=') == 1:
|
||||
values_list = values.split('=', 1)
|
||||
if '' == values_list[0]:
|
||||
msg = (
|
||||
"Property key must be specified: {}"
|
||||
).format(str(values))
|
||||
if values.count('=') >= 1:
|
||||
for key_value in values.split(','):
|
||||
key, value = key_value.split('=', 1)
|
||||
if '' == key:
|
||||
msg = (
|
||||
"Property key must be specified: {}"
|
||||
).format(str(values))
|
||||
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
else:
|
||||
getattr(namespace, self.dest, {}).update([values_list])
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
elif value.count('=') > 0:
|
||||
msg = (
|
||||
"Only a single '=' sign is allowed: {}"
|
||||
).format(str(values))
|
||||
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
else:
|
||||
if key in getattr(namespace, self.dest, {}):
|
||||
LOG.warning((
|
||||
"Duplicate key '%s' provided."
|
||||
"Value '%s' Overriding previous value. '%s'"
|
||||
) % (
|
||||
key, getattr(namespace, self.dest)[key], value))
|
||||
getattr(namespace, self.dest, {}).update({key: value})
|
||||
else:
|
||||
msg = (
|
||||
"Expected 'key=value' type, but got: {}"
|
||||
|
@ -58,5 +58,5 @@ KEYVALUEACTION_VALUES = {
|
||||
'invalid_noeq': 'foo>bar',
|
||||
'invalid_multieq': 'foo===bar',
|
||||
'invalid_nokey': '=bar',
|
||||
'invalid_multikey': 'foo=bar,fizz=buzz'
|
||||
'invalid_multikey': 'foo=bar,baz=,fizz=buzz,baz'
|
||||
}
|
||||
|
@ -88,17 +88,3 @@ class TestParserActions(TestCase):
|
||||
self.assertIn('fizz', dir(self.mock_namespace))
|
||||
self.assertDictEqual({}, self.mock_namespace.fizz)
|
||||
self.tearDown()
|
||||
|
||||
def test_keyvalueaction_invalid_invalid_multikey(self):
|
||||
|
||||
self.assertRaises(
|
||||
argparse.ArgumentTypeError,
|
||||
self.action,
|
||||
self.mock_parser,
|
||||
self.mock_namespace,
|
||||
self.test_values['invalid_multikey']
|
||||
)
|
||||
|
||||
self.assertIn('fizz', dir(self.mock_namespace))
|
||||
self.assertDictEqual({}, self.mock_namespace.fizz)
|
||||
self.tearDown()
|
||||
|
@ -365,15 +365,6 @@ class TestRun(BaseCommand):
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
def test_run_command_exclusive_wrong_extra_vars(self):
|
||||
arglist = ['--validation', 'foo',
|
||||
'--extra-vars', 'key=value1,key=value2']
|
||||
verifylist = [('validation_name', ['foo']),
|
||||
('extra_vars', {'key': 'value2'})]
|
||||
|
||||
self.assertRaises(Exception, self.check_parser, self.cmd,
|
||||
arglist, verifylist)
|
||||
|
||||
@mock.patch('validations_libs.utils.find_config_file',
|
||||
return_value="/etc/validations_foo.cfg")
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
|
Loading…
Reference in New Issue
Block a user