From b3fe4cadc1abac6dc4c523f0d9b2b191cbb8fd3f Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Thu, 8 Aug 2019 10:25:04 +0100 Subject: _loader: Detect and reject duplicated dependencies When loading an element, if it has duplicated dependencies of any kind then we reject the element with a LoadError(DUPLICATE_DEPENDENCY). This means that an element `foo.bst` can only appear once in any given dependency kind, allowing it to be both `runtime` and `build`, but not either of those twice, nor either plus `all`, nor `all` twice. Signed-off-by: Daniel Silverstone --- src/buildstream/_loader/types.pyx | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/buildstream/_loader/types.pyx b/src/buildstream/_loader/types.pyx index db5004f20..0a223f9a9 100644 --- a/src/buildstream/_loader/types.pyx +++ b/src/buildstream/_loader/types.pyx @@ -133,13 +133,31 @@ cdef class Dependency: # key (str): the key on the Node corresponding to the dependency type # default_dep_type (str): type to give to the dependency # acc (list): a list in which to add the loaded dependencies +# rundeps (dict): a dictionary mapping dependency (junction, name) to dependency for runtime deps +# builddeps (dict): a dictionary mapping dependency (junction, name) to dependency for build deps # -cdef void _extract_depends_from_node(Node node, str key, str default_dep_type, list acc) except *: +cdef void _extract_depends_from_node(Node node, str key, str default_dep_type, list acc, dict rundeps, dict builddeps) except *: cdef SequenceNode depends = node.get_sequence(key, []) cdef Node dep_node + cdef tuple deptup for dep_node in depends: dependency = Dependency(dep_node, default_dep_type=default_dep_type) + deptup = (dependency.junction, dependency.name) + if dependency.dep_type in [Symbol.BUILD, None]: + if deptup in builddeps: + raise LoadError("{}: Duplicate build dependency found at {}." + .format(dependency.provenance, builddeps[deptup].provenance), + LoadErrorReason.DUPLICATE_DEPENDENCY) + else: + builddeps[deptup] = dependency + if dependency.dep_type in [Symbol.RUNTIME, None]: + if deptup in rundeps: + raise LoadError("{}: Duplicate runtime dependency found at {}." + .format(dependency.provenance, rundeps[deptup].provenance), + LoadErrorReason.DUPLICATE_DEPENDENCY) + else: + rundeps[deptup] = dependency acc.append(dependency) # Now delete the field, we dont want it anymore @@ -162,7 +180,9 @@ cdef void _extract_depends_from_node(Node node, str key, str default_dep_type, l # def extract_depends_from_node(Node node): cdef list acc = [] - _extract_depends_from_node(node, Symbol.BUILD_DEPENDS, Symbol.BUILD, acc) - _extract_depends_from_node(node, Symbol.RUNTIME_DEPENDS, Symbol.RUNTIME, acc) - _extract_depends_from_node(node, Symbol.DEPENDS, None, acc) + cdef dict rundeps = {} + cdef dict builddeps = {} + _extract_depends_from_node(node, Symbol.BUILD_DEPENDS, Symbol.BUILD, acc, rundeps, builddeps) + _extract_depends_from_node(node, Symbol.RUNTIME_DEPENDS, Symbol.RUNTIME, acc, rundeps, builddeps) + _extract_depends_from_node(node, Symbol.DEPENDS, None, acc, rundeps, builddeps) return acc -- cgit v1.2.1