summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2019-08-08 10:25:04 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2019-08-08 15:47:48 +0100
commitb3fe4cadc1abac6dc4c523f0d9b2b191cbb8fd3f (patch)
tree076c6b3015d25184af9c66a37cae24fd4ea2d98f
parent65aae976f7eb53569c3456c58389721511af61ef (diff)
downloadbuildstream-b3fe4cadc1abac6dc4c523f0d9b2b191cbb8fd3f.tar.gz
_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 <daniel.silverstone@codethink.co.uk>
-rw-r--r--src/buildstream/_loader/types.pyx28
1 files 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, <str> Symbol.BUILD_DEPENDS, <str> Symbol.BUILD, acc)
- _extract_depends_from_node(node, <str> Symbol.RUNTIME_DEPENDS, <str> Symbol.RUNTIME, acc)
- _extract_depends_from_node(node, <str> Symbol.DEPENDS, None, acc)
+ cdef dict rundeps = {}
+ cdef dict builddeps = {}
+ _extract_depends_from_node(node, <str> Symbol.BUILD_DEPENDS, <str> Symbol.BUILD, acc, rundeps, builddeps)
+ _extract_depends_from_node(node, <str> Symbol.RUNTIME_DEPENDS, <str> Symbol.RUNTIME, acc, rundeps, builddeps)
+ _extract_depends_from_node(node, <str> Symbol.DEPENDS, None, acc, rundeps, builddeps)
return acc