1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
from pyroaring import BitMap
from .node cimport MappingNode, SequenceNode
from .types import Scope
from ._variables cimport Variables
# FIXME: we should make those as enums consumable from Cython
cdef SCOPE_ALL = Scope.ALL
cdef SCOPE_BUILD = Scope.BUILD
cdef SCOPE_RUN = Scope.RUN
def deps_visit_run(element, visited):
visited.add(element._unique_id)
for dep in element._Element__runtime_dependencies:
if dep._unique_id not in visited:
yield from deps_visit_run(dep, visited)
yield element
def deps_visit_build(element, visited_build, visited_run):
visited_build.add(element._unique_id)
for dep in element._Element__build_dependencies:
if dep._unique_id not in visited_run:
yield from deps_visit_run(dep, visited_run)
def deps_visit_all(element, visited):
visited.add(element._unique_id)
for dep in element._Element__build_dependencies:
if dep._unique_id not in visited:
yield from deps_visit_all(dep, visited)
for dep in element._Element__runtime_dependencies:
if dep._unique_id not in visited:
yield from deps_visit_all(dep, visited)
yield element
def dependencies(element, scope, *, recurse=True):
# The format of visited is (BitMap(), BitMap()), with the first BitMap
# containing element that have been visited for the `Scope.BUILD` case
# and the second one relating to the `Scope.RUN` case.
if not recurse:
if scope in (SCOPE_BUILD, SCOPE_ALL):
yield from element._Element__build_dependencies
if scope in (SCOPE_RUN, SCOPE_ALL):
yield from element._Element__runtime_dependencies
else:
if scope == SCOPE_ALL:
yield from deps_visit_all(element, BitMap())
elif scope == SCOPE_BUILD:
yield from deps_visit_build(element, BitMap(), BitMap())
elif scope == SCOPE_RUN:
yield from deps_visit_run(element, BitMap())
else:
yield element
def dependencies_for_targets(elements, scope):
if scope == SCOPE_ALL:
visited = BitMap()
for element in elements:
if element._unique_id not in visited:
yield from deps_visit_all(element, visited)
elif scope == SCOPE_BUILD:
visited_build = BitMap()
visited_run = BitMap()
for element in elements:
if element._unique_id not in visited_build:
yield from deps_visit_build(element, visited_build, visited_run)
elif scope == SCOPE_RUN:
visited = BitMap()
for element in elements:
if element._unique_id not in visited:
yield from deps_visit_run(element, visited)
else:
yield from elements
def expand_splits(Variables variables, MappingNode element_public):
cdef MappingNode element_bst = element_public.get_mapping('bst', default={})
cdef MappingNode element_splits = element_bst.get_mapping('split-rules', default={})
cdef str domain
cdef SequenceNode split_nodes
cdef list splits
# Resolve any variables in the public split rules directly
for domain, split_nodes in element_splits.items():
splits = [
variables.subst((<str> split).strip())
for split in split_nodes.as_str_list()
]
element_splits[domain] = splits
return element_public
|