Commit c00ac8de authored by Edward Lemur's avatar Edward Lemur Committed by LUCI CQ

gclient: Don't allow duplicate entries on deps

Bug: 809671
Change-Id: I74103304651417e6b6889cb713fe494c95279d69
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2088422Reviewed-by: 's avatarAnthony Polito <apolito@google.com>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
parent 777660f3
......@@ -26,8 +26,8 @@ else:
class _NodeDict(collections_abc.MutableMapping):
"""Dict-like type that also stores information on AST nodes and tokens."""
def __init__(self, data, tokens=None):
self.data = collections.OrderedDict(data)
def __init__(self, data=None, tokens=None):
self.data = collections.OrderedDict(data or [])
self.tokens = tokens
def __str__(self):
......@@ -250,8 +250,15 @@ def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
elif isinstance(node, ast.List):
return list(map(_convert, node.elts))
elif isinstance(node, ast.Dict):
return _NodeDict((_convert(k), (_convert(v), v))
for k, v in zip(node.keys, node.values))
node_dict = _NodeDict()
for key_node, value_node in zip(node.keys, node.values):
key = _convert(key_node)
if key in node_dict:
raise ValueError(
'duplicate key in dictionary: %s (file %r, line %s)' % (
key, filename, getattr(key_node, 'lineno', '<unknown>')))
node_dict.SetNode(key, _convert(value_node), value_node)
return node_dict
elif isinstance(node, ast.Name):
if node.id not in _allowed_names:
raise ValueError(
......
......@@ -173,6 +173,22 @@ class ExecTest(unittest.TestCase):
self.assertIn('baz was used as a variable, but was not declared',
str(cm.exception))
def test_doesnt_allow_duplicate_deps(self):
with self.assertRaises(ValueError) as cm:
gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": {',
' "url": "a_url@a_rev",',
' "condition": "foo",',
' },',
' "a_dep": {',
' "url": "a_url@another_rev",',
' "condition": "not foo",',
' }',
'}',
]), '<unknown>')
self.assertIn('duplicate key in dictionary: a_dep', str(cm.exception))
class UpdateConditionTest(unittest.TestCase):
def test_both_present(self):
......@@ -1052,7 +1068,6 @@ class ParseTest(unittest.TestCase):
}, local_scope)
if __name__ == '__main__':
level = logging.DEBUG if '-v' in sys.argv else logging.FATAL
logging.basicConfig(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment