1 |
commit: dd794a5e94fa846975b440824534aeffd629f60b |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun May 1 23:27:48 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 1 23:27:48 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=dd794a5e |
7 |
|
8 |
trigger_rebuilds: handle circular deps |
9 |
|
10 |
--- |
11 |
pym/_emerge/depgraph.py | 28 +++++++++++++++++++++++++++- |
12 |
1 files changed, 27 insertions(+), 1 deletions(-) |
13 |
|
14 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
15 |
index 4753bd2..5c39497 100644 |
16 |
--- a/pym/_emerge/depgraph.py |
17 |
+++ b/pym/_emerge/depgraph.py |
18 |
@@ -235,16 +235,42 @@ class _rebuild_config(object): |
19 |
runtime_deps = {} |
20 |
leaf_nodes = deque(graph.leaf_nodes()) |
21 |
|
22 |
+ def ignore_non_runtime(priority): |
23 |
+ return not priority.runtime |
24 |
+ |
25 |
+ def ignore_non_buildtime(priority): |
26 |
+ return not priority.buildtime |
27 |
+ |
28 |
# Trigger rebuilds bottom-up (starting with the leaves) so that parents |
29 |
# will always know which children are being rebuilt. |
30 |
- while leaf_nodes: |
31 |
+ while not graph.empty(): |
32 |
+ if not leaf_nodes: |
33 |
+ # We're interested in intersection of buildtime and runtime, |
34 |
+ # so ignore edges that do not contain both. |
35 |
+ leaf_nodes.extend(graph.leaf_nodes( |
36 |
+ ignore_priority=ignore_non_runtime)) |
37 |
+ if not leaf_nodes: |
38 |
+ leaf_nodes.extend(graph.leaf_nodes( |
39 |
+ ignore_priority=ignore_non_buildtime)) |
40 |
+ if not leaf_nodes: |
41 |
+ # We'll have to drop an edge that is both |
42 |
+ # buildtime and runtime. This should be |
43 |
+ # quite rare. |
44 |
+ leaf_nodes.append(graph.order[-1]) |
45 |
+ |
46 |
node = leaf_nodes.popleft() |
47 |
+ if node not in graph: |
48 |
+ # This can be triggered by circular dependencies. |
49 |
+ continue |
50 |
slot_atom = node.slot_atom |
51 |
|
52 |
# Remove our leaf node from the graph, keeping track of deps. |
53 |
parents = graph.nodes[node][1].items() |
54 |
graph.remove(node) |
55 |
for parent, priorities in parents: |
56 |
+ if parent == node: |
57 |
+ # Ignore a direct cycle. |
58 |
+ continue |
59 |
for priority in priorities: |
60 |
if priority.buildtime: |
61 |
build_deps.setdefault(parent, {})[slot_atom] = node |