[autotest] Improved atest attribute matching.
Commas in values no longer need to be escaped. Multiple attributes are
now passed by repeating the argument ie: -i foo=bar -i baz=zip,bang
BUG=chromium:627284
TEST=Added unit test.
Change-Id: I9c975dc451fba19536804b853fcb25fd00b8f716
Reviewed-on: https://chromium-review.googlesource.com/359953
Commit-Ready: Justin Giorgi <jgiorgi@google.com>
Tested-by: Justin Giorgi <jgiorgi@google.com>
Reviewed-by: Simran Basi <sbasi@chromium.org>
diff --git a/cli/host.py b/cli/host.py
index e91c8ce..c7a960d 100644
--- a/cli/host.py
+++ b/cli/host.py
@@ -314,8 +314,8 @@
'status'])
class BaseHostModCreate(host):
- attribute_regex = r'^(?P<attribute>\w+)=(?P<value>.+)?'
- attr_split_regex = r'[^\\],' # Matches , not preceeded by \
+ # Matches one attribute=value pair
+ attribute_regex = r'(?P<attribute>\w+)=(?P<value>.+)?'
def __init__(self):
"""Add the options shared between host mod and host create actions."""
@@ -337,11 +337,14 @@
', '.join('"%s"' % p
for p in self.protections)),
choices=self.protections)
- self.parser.add_option('--attributes', '-i', default='',
- help=('Host attributes to add or change. Format '
- 'is <attribute>=<value>. Comma delimited '
- 'for multiple attributes. Use \\\\ (two '
- 'backslashes) to escape delimitter.'))
+ self._attributes = []
+ self.parser.add_option('--attribute', '-i',
+ help=('Host attribute to add or change. Format '
+ 'is <attribute>=<value>. Multiple '
+ 'attributes can be set by passing the '
+ 'argument multiple times. Attributes can '
+ 'be unset by providing an empty value.'),
+ action='append')
self.parser.add_option('-b', '--labels',
help='Comma separated list of labels')
self.parser.add_option('-B', '--blist',
@@ -358,20 +361,6 @@
help='Sets the platform label')
- def _scrub(self, raw_attribute):
- """
- Helper method to scrub out backslashes.
-
- The host attributes can use backslashes to escape the comma delimitter.
- We want to scrub them out though.
-
- @param raw_attribute: String to be scrubbed.
-
- @returns String that has been removed of the backslashes.
- """
- return raw_attribute.replace('\\,', ',')
-
-
def parse(self):
"""Consume the options common to host create and host mod.
"""
@@ -393,34 +382,16 @@
self.messages.append('Protection set to "%s"' % options.protection)
self.attributes = {}
- if options.attributes:
- # Extract pairs of attributes
- last_end = 0
- groups = []
- for m in re.finditer(self.attr_split_regex, options.attributes):
- # The first char of the match must be included because it is
- # the char before the delimitter
- groups.append(
- self._scrub(options.attributes[last_end:m.start()+1]))
- last_end = m.end()
- if options.attributes[last_end:]:
- groups.append(
- self._scrub(options.attributes[last_end:]))
-
- # Process pairs of attributes
- for group in groups:
- match = re.match(self.attribute_regex, group)
- if not match:
- self.invalid_syntax('Attributes must be in '
- '<attribute>=<value> syntax!')
-
- attribute = match.group('attribute')
- value = match.group('value')
-
- if attribute in self.attributes:
+ if options.attribute:
+ for pair in options.attribute:
+ m = re.match(self.attribute_regex, pair)
+ if not m:
+ raise topic_common.CliError('Attribute must be in key=value '
+ 'syntax.')
+ elif m.group('attribute') in self.attributes:
raise topic_common.CliError('Multiple values provided for '
'attribute %s.' % attribute)
- self.attributes[attribute] = value
+ self.attributes[m.group('attribute')] = m.group('value')
self.platform = options.platform
return (options, leftover)
@@ -511,7 +482,6 @@
--attributes <attr>=<value>;<attr>=<value>
--mlist <mach_file>] <hosts>"""
usage_action = 'mod'
- attribute_regex = r'^(?P<attribute>\w+)=(?P<value>.+)?'
def __init__(self):
"""Add the options specific to the mod action"""