os.environ["PORTAGE_LEGACY_GLOBALS"] = "false"
import portage
del os.environ["PORTAGE_LEGACY_GLOBALS"]
+from portage import digraph
import emergehelp, xpak, commands, errno, re, socket, string, time, types
from output import blue, bold, colorize, darkblue, darkgreen, darkred, green, \
self.args_keys = []
def create(self, mybigkey, myparent=None, addme=1, myuse=None,
- soft_dep=False, rev_dep=False, arg=None):
+ priority=digraph.HARD, rev_dep=False, arg=None):
"""
Fills the digraph with nodes comprised of packages to merge.
mybigkey is the package spec of the package to merge.
# Refuse to make a node depend on itself so that the we don't
# don't create a bogus circular dependency in self.altlist().
if rev_dep and myparent:
- self.digraph.addnode(myparent, jbigkey, soft_dep=soft_dep)
+ self.digraph.addnode(myparent, jbigkey, priority=priority)
else:
- self.digraph.addnode(jbigkey, myparent, soft_dep=soft_dep)
+ self.digraph.addnode(jbigkey, myparent, priority=priority)
return 1
jbigkey = " ".join(mybigkey) + " nomerge"
if self.digraph.hasnode(jbigkey):
requested as a command line argument. This can be solved by
checking all args prior to marking packages as nomerge"""
if rev_dep and myparent:
- self.digraph.addnode(myparent, jbigkey, soft_dep=soft_dep)
+ self.digraph.addnode(myparent, jbigkey, priority=priority)
else:
- self.digraph.addnode(jbigkey, myparent, soft_dep=soft_dep)
+ self.digraph.addnode(jbigkey, myparent, priority=priority)
return 1
self.spinner.update()
if addme and "--buildpkgonly" not in self.myopts and myparent:
mybigkey[1] = myparent.split()[1]
self.digraph.addnode(" ".join(mybigkey), myparent,
- soft_dep=soft_dep)
+ priority=priority)
return 1
if not arg:
arg = portage.best_match_to_list(mykey, self.args_keys)
add the package to the depgraph; so we do that here. """
if rev_dep and myparent:
self.digraph.addnode(myparent, " ".join(mybigkey),
- soft_dep=soft_dep)
+ priority=priority)
else:
self.digraph.addnode(" ".join(mybigkey), myparent,
- soft_dep=soft_dep)
+ priority=priority)
""" This section determines whether we go deeper into dependencies or not.
We want to go deeper on a few occasions:
dependencies not being installed yet.
"""
if not self.select_dep(myroot,edepend["RDEPEND"], myparent=mp,
- myuse=myuse, soft_deps=False, parent_arg=arg):
+ myuse=myuse, priority=digraph.MEDIUM, parent_arg=arg):
return 0
if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
# Post Depend -- Add to the list without a parent, as it depends
# on a package being present AND must be built after that package.
if not self.select_dep(myroot, edepend["PDEPEND"], myparent=mp,
- myuse=myuse, soft_deps=True, rev_deps=True, parent_arg=arg):
+ myuse=myuse, priority=digraph.SOFT, rev_deps=True, parent_arg=arg):
return 0
except ValueError, e:
pkgs = e.args[0]
return match
def select_dep(self, myroot, depstring, myparent=None, arg=None,
- myuse=None, raise_on_missing=False, soft_deps=False, rev_deps=False,
+ myuse=None, raise_on_missing=False, priority=digraph.HARD, rev_deps=False,
parent_arg=None):
""" Given a depstring, create the depgraph such that all dependencies are satisfied.
myroot = $ROOT from environment, where {R,P}DEPENDs are merged to.
print "Depstring:",depstring
if rev_deps:
print "Reverse:", rev_deps
- if soft_deps:
- print "Soft:", soft_deps
+ print "Priority:", priority
#processing dependencies
""" Call portage.dep_check to evaluate the use? conditionals and make sure all
if myparent:
#we are a dependency, so we want to be unconditionally added
- soft_dep = bool(soft_deps or vardb.match(x))
+ mypriority = priority
+ if mypriority > digraph.SOFT and vardb.match(x):
+ mypriority = digraph.SOFT
if not self.create(selected_pkg[0:3], myparent,
- myuse=selected_pkg[-1], soft_dep=soft_dep,
+ myuse=selected_pkg[-1], priority=mypriority,
rev_dep=rev_deps, arg=arg):
return 0
else:
if reversed:
nodes = mygraph.root_nodes()
if not nodes:
- nodes = mygraph.root_nodes(ignore_soft_deps=True)
- if nodes:
- next_node = nodes[-1]
- else:
- next_node = None
+ nodes = mygraph.root_nodes(ignore_priority=digraph.SOFT)
+ if not nodes:
+ nodes = mygraph.root_nodes(ignore_priority=digraph.MEDIUM)
else:
nodes = mygraph.leaf_nodes()
if not nodes:
- nodes = mygraph.leaf_nodes(ignore_soft_deps=True)
- if nodes:
- next_node = nodes[0]
- else:
- next_node = None
- if not next_node:
+ nodes = mygraph.leaf_nodes(ignore_priority=digraph.SOFT)
+ if not nodes:
+ nodes = mygraph.leaf_nodes(ignore_priority=digraph.MEDIUM)
+ if not nodes:
print "!!! Error: circular dependencies:"
print
mygraph.debug_print()
sys.exit(1)
- retlist.append(next_node.split())
- mygraph.remove(next_node)
+ for node in nodes:
+ retlist.append(node.split())
+ mygraph.remove(node)
return retlist
def xcreate(self,mode="system"):
mydepgraph.altlist(reversed=("--tree" in myopts)))
else:
if ("--buildpkgonly" in myopts):
- if not mydepgraph.digraph.hasallzeros(ignore_soft_deps=True):
+ if not mydepgraph.digraph.hasallzeros(ignore_priority=digraph.MEDIUM):
print "\n!!! --buildpkgonly requires all dependencies to be merged."
print "!!! Cannot merge requested packages. Merge deps and try again.\n"
sys.exit(1)
#beautiful directed graph object
class digraph:
+ SOFT = 0
+ MEDIUM = 1
+ HARD = 2
def __init__(self):
"""Create an empty digraph"""
- # { node : ( { child : soft_dep } , { parent : soft_dep } ) }
+ # { node : ( { child : priority } , { parent : priority } ) }
self.nodes = {}
self.order = []
- def add(self, node, parent, soft_dep=False):
+ def add(self, node, parent, priority=2):
"""Adds the specified node with the specified parent.
If the dep is a soft-dep and the node already has a hard
self.order.append(parent)
if parent in self.nodes[node][1]:
- if not soft_dep:
- self.nodes[node][1][parent] = False
+ if priority > self.SOFT:
+ self.nodes[node][1][parent] = priority
else:
- self.nodes[node][1][parent] = soft_dep
+ self.nodes[node][1][parent] = priority
if node in self.nodes[parent][0]:
- if not soft_dep:
- self.nodes[parent][0][node] = False
+ if priority > self.SOFT:
+ self.nodes[parent][0][node] = priority
else:
- self.nodes[parent][0][node] = soft_dep
+ self.nodes[parent][0][node] = priority
def remove(self, node):
"""Removes the specified node from the digraph, also removing
"""Return all parents of the specified node"""
return self.nodes[node][1].keys()
- def leaf_nodes(self, ignore_soft_deps=False):
+ def leaf_nodes(self, ignore_priority=-1):
"""Return all nodes that have no children
If ignore_soft_deps is True, soft deps are not counted as
for node in self.order:
is_leaf_node = True
for child in self.nodes[node][0]:
- if not (ignore_soft_deps and self.nodes[node][0][child]):
+ if self.nodes[node][0][child] > ignore_priority:
is_leaf_node = False
break
if is_leaf_node:
leaf_nodes.append(node)
return leaf_nodes
- def root_nodes(self, ignore_soft_deps=False):
+ def root_nodes(self, ignore_priority=-1):
"""Return all nodes that have no parents.
If ignore_soft_deps is True, soft deps are not counted as
for node in self.order:
is_root_node = True
for parent in self.nodes[node][1]:
- if not (ignore_soft_deps and self.nodes[node][1][parent]):
+ if self.nodes[node][1][parent] > ignore_priority:
is_root_node = False
break
if is_root_node:
return leaf_nodes[0]
return None
- def hasallzeros(self, ignore_soft_deps=False):
- return len(self.leaf_nodes(ignore_soft_deps=ignore_soft_deps)) == \
+ def hasallzeros(self, ignore_priority=-1):
+ return len(self.leaf_nodes(ignore_priority=ignore_priority)) == \
len(self.order)
def debug_print(self):
print "(no children)"
for child in self.nodes[node][0]:
print " ",child,
- if self.nodes[node][0][child]:
- print "(soft)"
- else:
+ if self.nodes[node][0][child] == self.HARD:
print "(hard)"
+ elif self.nodes[node][0][child] == self.MEDIUM:
+ print "(medium)"
+ else:
+ print "(soft)"