summaryrefslogtreecommitdiff
path: root/src/buildstream/_loader/loadelement.pyx
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildstream/_loader/loadelement.pyx')
-rw-r--r--src/buildstream/_loader/loadelement.pyx73
1 files changed, 47 insertions, 26 deletions
diff --git a/src/buildstream/_loader/loadelement.pyx b/src/buildstream/_loader/loadelement.pyx
index 01334d124..31c54ced4 100644
--- a/src/buildstream/_loader/loadelement.pyx
+++ b/src/buildstream/_loader/loadelement.pyx
@@ -23,7 +23,6 @@ from pyroaring import BitMap, FrozenBitMap # pylint: disable=no-name-in-module
from .._exceptions import LoadError
from ..exceptions import LoadErrorReason
-from ..element import Element
from ..node cimport MappingNode, Node, ProvenanceInformation, ScalarNode, SequenceNode
from .types import Symbol
@@ -37,6 +36,22 @@ cdef int _next_synthetic_counter():
return _counter
+# DependencyType
+#
+# A bitfield to represent dependency types
+#
+cpdef enum DependencyType:
+
+ # A build dependency
+ BUILD = 0x001
+
+ # A runtime dependency
+ RUNTIME = 0x002
+
+ # Both build and runtime dependencies
+ ALL = 0x003
+
+
# Dependency():
#
# Early stage data model for dependencies objects, the LoadElement has
@@ -50,17 +65,17 @@ cdef int _next_synthetic_counter():
#
# Args:
# element (LoadElement): a LoadElement on which there is a dependency
-# dep_type (str): the type of dependency this dependency link is
+# dep_type (DependencyType): the type of dependency this dependency link is
#
cdef class Dependency:
cdef readonly LoadElement element # The resolved LoadElement
- cdef readonly str dep_type # The dependency type (runtime or build or both)
+ cdef readonly int dep_type # The dependency type (runtime or build or both)
cdef readonly str name # The project local dependency name
cdef readonly str junction # The junction path of the dependency name, if any
cdef readonly bint strict # Whether this is a strict dependency
cdef Node _node # The original node of the dependency
- def __cinit__(self, element=None, dep_type=None):
+ def __cinit__(self, LoadElement element = None, int dep_type = DependencyType.ALL):
self.element = element
self.dep_type = dep_type
self.name = None
@@ -98,38 +113,41 @@ cdef class Dependency:
#
# Args:
# dep (Node): A node to load the dependency from
- # default_dep_type (str): The default dependency type
+ # default_dep_type (DependencyType): The default dependency type
#
- cdef load(self, Node dep, str default_dep_type):
- cdef str dep_type
+ cdef load(self, Node dep, int default_dep_type):
+ cdef str parsed_type
self._node = dep
self.element = None
if type(dep) is ScalarNode:
self.name = dep.as_str()
- self.dep_type = default_dep_type
+ self.dep_type = default_dep_type or DependencyType.ALL
self.junction = None
self.strict = False
elif type(dep) is MappingNode:
if default_dep_type:
(<MappingNode> dep).validate_keys(['filename', 'junction', 'strict'])
- dep_type = default_dep_type
+ self.dep_type = default_dep_type
else:
(<MappingNode> dep).validate_keys(['filename', 'type', 'junction', 'strict'])
- # Make type optional, for this we set it to None
- dep_type = (<MappingNode> dep).get_str(<str> Symbol.TYPE, None)
- if dep_type is None or dep_type == <str> Symbol.ALL:
- dep_type = None
- elif dep_type not in [Symbol.BUILD, Symbol.RUNTIME]:
+ # Resolve the DependencyType
+ parsed_type = (<MappingNode> dep).get_str(<str> Symbol.TYPE, None)
+ if parsed_type is None or parsed_type == <str> Symbol.ALL:
+ self.dep_type = DependencyType.ALL
+ elif parsed_type == <str> Symbol.BUILD:
+ self.dep_type = DependencyType.BUILD
+ elif parsed_type == <str> Symbol.RUNTIME:
+ self.dep_type = DependencyType.RUNTIME
+ else:
provenance = dep.get_scalar(Symbol.TYPE).get_provenance()
raise LoadError("{}: Dependency type '{}' is not 'build', 'runtime' or 'all'"
- .format(provenance, dep_type), LoadErrorReason.INVALID_DATA)
+ .format(provenance, parsed_type), LoadErrorReason.INVALID_DATA)
self.name = (<MappingNode> dep).get_str(<str> Symbol.FILENAME)
- self.dep_type = dep_type
self.junction = (<MappingNode> dep).get_str(<str> Symbol.JUNCTION, None)
self.strict = (<MappingNode> dep).get_bool(<str> Symbol.STRICT, False)
@@ -152,7 +170,7 @@ cdef class Dependency:
# Only build dependencies are allowed to be strict
#
- if self.strict and self.dep_type == Symbol.RUNTIME:
+ if self.strict and self.dep_type == DependencyType.RUNTIME:
raise LoadError("{}: Runtime dependency {} specified as `strict`.".format(self.provenance, self.name),
LoadErrorReason.INVALID_DATA,
detail="Only dependencies required at build time may be declared `strict`.")
@@ -242,6 +260,9 @@ cdef class LoadElement:
# store the link target and provenance
#
if self.kind == 'link':
+ # Avoid cyclic import here
+ from ..element import Element
+
element = Element._new_from_load_element(self)
element._initialize_state()
@@ -345,9 +366,9 @@ def _dependency_cmp(Dependency dep_a, Dependency dep_b):
# If there are no inter element dependencies, place
# runtime only dependencies last
if dep_a.dep_type != dep_b.dep_type:
- if dep_a.dep_type == Symbol.RUNTIME:
+ if dep_a.dep_type == DependencyType.RUNTIME:
return 1
- elif dep_b.dep_type == Symbol.RUNTIME:
+ elif dep_b.dep_type == DependencyType.RUNTIME:
return -1
# All things being equal, string comparison.
@@ -424,12 +445,12 @@ def sort_dependencies(LoadElement element, set visited):
# Args:
# node (Node): A YAML loaded dictionary
# key (str): the key on the Node corresponding to the dependency type
-# default_dep_type (str): type to give to the dependency
+# default_dep_type (DependencyType): 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, dict rundeps, dict builddeps) except *:
+cdef void _extract_depends_from_node(Node node, str key, int default_dep_type, list acc, dict rundeps, dict builddeps) except *:
cdef SequenceNode depends = node.get_sequence(key, [])
cdef Node dep_node
cdef tuple deptup
@@ -438,14 +459,14 @@ cdef void _extract_depends_from_node(Node node, str key, str default_dep_type, l
dependency = Dependency()
dependency.load(dep_node, default_dep_type)
deptup = (dependency.junction, dependency.name)
- if dependency.dep_type in [Symbol.BUILD, None]:
+ if dependency.dep_type & DependencyType.BUILD:
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 dependency.dep_type & DependencyType.RUNTIME:
if deptup in rundeps:
raise LoadError("{}: Duplicate runtime dependency found at {}."
.format(dependency.provenance, rundeps[deptup].provenance),
@@ -476,7 +497,7 @@ def extract_depends_from_node(Node node):
cdef list 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)
+ _extract_depends_from_node(node, <str> Symbol.BUILD_DEPENDS, <int> DependencyType.BUILD, acc, rundeps, builddeps)
+ _extract_depends_from_node(node, <str> Symbol.RUNTIME_DEPENDS, <int> DependencyType.RUNTIME, acc, rundeps, builddeps)
+ _extract_depends_from_node(node, <str> Symbol.DEPENDS, <int> 0, acc, rundeps, builddeps)
return acc