| Index: parallel_emerge
|
| diff --git a/parallel_emerge b/parallel_emerge
|
| index 77e8f09b50aa4642bffbcedae570f12121680d41..00b1fcea9628c440affaf1a1321df0aebe95b88d 100755
|
| --- a/parallel_emerge
|
| +++ b/parallel_emerge
|
| @@ -646,22 +646,22 @@ class DepGraphGenerator(object):
|
| to a list of the cycles the package is involved in.
|
| """
|
|
|
| - def FindCyclesAtNode(pkg, cycles, unresolved, resolved):
|
| + def FindCyclesAtNode(pkg, cycles, unresolved):
|
| """Find cycles in cyclic dependencies starting at specified package.
|
|
|
| Args:
|
| pkg: Package identifier.
|
| cycles: Set of cycles so far.
|
| unresolved: Nodes that have been visited but are not fully processed.
|
| - resolved: Nodes that have been visited and are fully processed.
|
| - Returns:
|
| - Whether a cycle was found.
|
| """
|
| - if pkg in resolved:
|
| - return
|
| unresolved.append(pkg)
|
| + mycycles = cycles.get(pkg)
|
| + if mycycles:
|
| + mycycles = mycycles.get("pkgs")
|
| for dep in deps_map[pkg]["needs"]:
|
| - if dep in unresolved:
|
| + if mycycles and dep in mycycles:
|
| + continue
|
| + elif dep in unresolved:
|
| idx = unresolved.index(dep)
|
| mycycle = unresolved[idx:] + [dep]
|
| for cycle_pkg in mycycle:
|
| @@ -669,13 +669,12 @@ class DepGraphGenerator(object):
|
| info.setdefault("pkgs", set()).update(mycycle)
|
| info.setdefault("cycles", []).append(mycycle)
|
| else:
|
| - FindCyclesAtNode(dep, cycles, unresolved, resolved)
|
| + FindCyclesAtNode(dep, cycles, unresolved)
|
| unresolved.pop()
|
| - resolved.add(pkg)
|
|
|
| - cycles, unresolved, resolved = {}, [], set()
|
| + cycles, unresolved = {}, []
|
| for pkg in deps_map:
|
| - FindCyclesAtNode(pkg, cycles, unresolved, resolved)
|
| + FindCyclesAtNode(pkg, cycles, unresolved)
|
| return cycles
|
|
|
| def RemoveInstalledPackages():
|
| @@ -753,20 +752,25 @@ class DepGraphGenerator(object):
|
| package to a list of the cycles the package is involved in. Produced
|
| by FindCycles().
|
| """
|
| - for basedep in set(cycles).intersection(deps_map):
|
| - this_pkg = deps_map[basedep]
|
| - for dep in this_pkg["provides"].intersection(cycles[basedep]["pkgs"]):
|
| - if deps_info[basedep]["idx"] >= deps_info[dep]["idx"]:
|
| - for mycycle in cycles[basedep]["cycles"]:
|
| - if dep in mycycle:
|
| - print "Breaking %s -> %s in cycle:" % (dep, basedep)
|
| - for i in range(len(mycycle) - 1):
|
| - needs = deps_map[mycycle[i]]["needs"]
|
| - deptype = needs.get(mycycle[i+1], "deleted")
|
| - print " %s -> %s (%s)" % (mycycle[i], mycycle[i+1], deptype)
|
| - del deps_map[dep]["needs"][basedep]
|
| - this_pkg["provides"].remove(dep)
|
| - break
|
| + for basedep, cycle_info in cycles.iteritems():
|
| + for mycycle in cycle_info["cycles"]:
|
| + info = []
|
| + broken = False
|
| + for i in range(len(mycycle) - 1):
|
| + pkg1, pkg2 = mycycle[i], mycycle[i+1]
|
| + needs = deps_map[pkg1]["needs"]
|
| + depinfo = needs.get(pkg2, "deleted")
|
| + bad = False
|
| + if (deps_info[pkg1]["idx"] >= deps_info[pkg2]["idx"] and
|
| + depinfo != "deleted"):
|
| + depinfo = depinfo + ", deleting"
|
| + broken = True
|
| + del deps_map[pkg1]["needs"][pkg2]
|
| + deps_map[pkg2]["provides"].remove(pkg1)
|
| + info.append(" %s -> %s (%s)" % (pkg1, pkg2, depinfo))
|
| + if broken:
|
| + print "Breaking cycle:"
|
| + print "\n".join(info)
|
|
|
| def AddSecretDeps():
|
| """Find these tagged packages and add extra dependencies.
|
| @@ -1069,15 +1073,23 @@ class DepGraphGenerator(object):
|
| plan.add(item)
|
| install_plan.append(self.package_db[item])
|
|
|
| + for pkg in plan:
|
| + del deps_map[pkg]
|
| +
|
| + if deps_map:
|
| + print "Cyclic dependencies:", " ".join(deps_map)
|
| + PrintDepsMap(deps_map)
|
| + sys.exit(1)
|
| +
|
| self.emerge.depgraph.display(install_plan)
|
|
|
|
|
| def PrintDepsMap(deps_map):
|
| """Print dependency graph, for each package list it's prerequisites."""
|
| - for i in deps_map:
|
| + for i in sorted(deps_map):
|
| print "%s: (%s) needs" % (i, deps_map[i]["action"])
|
| needs = deps_map[i]["needs"]
|
| - for j in needs:
|
| + for j in sorted(needs):
|
| print " %s" % (j)
|
| if not needs:
|
| print " no dependencies"
|
|
|