summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/emerge105
-rw-r--r--pym/portage.py23
2 files changed, 97 insertions, 31 deletions
diff --git a/bin/emerge b/bin/emerge
index a3277b239..e249face2 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -629,6 +629,76 @@ def filter_iuse_defaults(iuse):
else:
yield flag
+class DepPriority(object):
+ """
+ This class generates an integer priority level based of various
+ attributes of the dependency relationship. Attributes can be assigned
+ at any time and the new integer value will be generated on calls to the
+ __int__() method. Rich comparison operators are supported.
+
+ The boolean attributes that affect the integer value are "satisfied",
+ "buildtime", "runtime", and "system". Various combinations of
+ attributes lead to the following priority levels:
+
+ Combination of properties Priority level
+
+ not satisfied and buildtime 0
+ not satisfied and runtime -1
+ satisfied and buildtime -2
+ satisfied and runtime -3
+ (none of the above) -4
+
+ Several integer constants are defined for categorization of priority
+ levels:
+
+ MEDIUM The upper boundary for medium dependencies.
+ SOFT The upper boundary for soft dependencies.
+ MIN The lower boundary for soft dependencies.
+ """
+ __slots__ = ["satisfied", "buildtime", "runtime", "system"]
+ MEDIUM = -1
+ SOFT = -2
+ MIN = -4
+ def __init__(self, **kwargs):
+ for myattr in self.__slots__:
+ myvalue = kwargs.get(myattr, False)
+ setattr(self, myattr, myvalue)
+ def __int__(self):
+ if not self.satisfied:
+ if self.buildtime:
+ return 0
+ if self.runtime:
+ return -1
+ if self.buildtime:
+ return -2
+ if self.runtime:
+ return -3
+ if self.system:
+ return -4
+ return -5
+ def __lt__(self, other):
+ return int(self) < other
+ def __le__(self, other):
+ return int(self) <= other
+ def __eq__(self, other):
+ return int(self) == other
+ def __ne__(self, other):
+ return int(self) != other
+ def __gt__(self, other):
+ return int(self) > other
+ def __ge__(self, other):
+ return int(self) >= other
+ def copy(self):
+ import copy
+ return copy.copy(self)
+ def __str__(self):
+ myvalue = int(self)
+ if myvalue > self.MEDIUM:
+ return "hard"
+ if myvalue > self.SOFT:
+ return "medium"
+ return "soft"
+
class depgraph:
pkg_tree_map = {
@@ -691,7 +761,7 @@ class depgraph:
self.blocker_parents = {}
def create(self, mybigkey, myparent=None, addme=1, myuse=None,
- priority=digraph.HARD, rev_dep=False, arg=None):
+ priority=DepPriority(), 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.
@@ -734,7 +804,7 @@ class depgraph:
if addme and "--buildpkgonly" not in self.myopts and myparent:
mybigkey[1] = myparent.split()[1]
self.digraph.addnode(" ".join(mybigkey), myparent,
- priority=digraph.SOFT)
+ priority=DepPriority())
return 1
if not arg:
arg = portage.best_match_to_list(mykey, self.args_keys)
@@ -845,7 +915,8 @@ class depgraph:
try:
if not self.select_dep("/", edepend["DEPEND"], myparent=mp,
- myuse=myuse, parent_arg=arg):
+ myuse=myuse, priority=DepPriority(buildtime=True),
+ parent_arg=arg):
return 0
"""RDEPEND is soft by definition. However, in order to ensure
correct merge order, we make it a hard dependency. Otherwise, a
@@ -853,13 +924,15 @@ class depgraph:
dependencies not being installed yet.
"""
if not self.select_dep(myroot,edepend["RDEPEND"], myparent=mp,
- myuse=myuse, priority=digraph.MEDIUM, parent_arg=arg):
+ myuse=myuse, priority=DepPriority(runtime=True),
+ 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, priority=digraph.SOFT, rev_deps=True, parent_arg=arg):
+ myuse=myuse, priority=DepPriority(), rev_deps=True,
+ parent_arg=arg):
return 0
except ValueError, e:
pkgs = e.args[0]
@@ -1055,8 +1128,8 @@ class depgraph:
return match
def select_dep(self, myroot, depstring, myparent=None, arg=None,
- myuse=None, raise_on_missing=False, priority=digraph.HARD, rev_deps=False,
- parent_arg=None):
+ myuse=None, raise_on_missing=False, priority=DepPriority(),
+ 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.
myparent = the node whose depstring is being passed in
@@ -1301,9 +1374,9 @@ class depgraph:
if myparent:
#we are a dependency, so we want to be unconditionally added
- mypriority = priority
- if mypriority > digraph.SOFT and vardb.match(x):
- mypriority = digraph.SOFT
+ mypriority = priority.copy()
+ if vardb.match(x):
+ mypriority.satisfied = True
if not self.create(selected_pkg[0:3], myparent,
myuse=selected_pkg[-1], priority=mypriority,
rev_dep=rev_deps, arg=arg):
@@ -1398,15 +1471,17 @@ class depgraph:
get_nodes = mygraph.root_nodes
else:
get_nodes = mygraph.leaf_nodes
+ ignore_priority_range = [None]
+ ignore_priority_range.extend(
+ xrange(DepPriority.MIN, DepPriority.MEDIUM))
while not mygraph.empty():
- for ignore_priority in \
- (digraph.NONE, digraph.SOFT, digraph.MEDIUM):
+ for ignore_priority in ignore_priority_range:
nodes = get_nodes(ignore_priority=ignore_priority)
if nodes:
break
selected_nodes = None
if nodes:
- if ignore_priority <= digraph.SOFT:
+ if ignore_priority <= DepPriority.SOFT:
selected_nodes = [nodes[0]]
else:
"""Recursively gather a group of nodes that RDEPEND on
@@ -1419,7 +1494,7 @@ class depgraph:
return False
selected_nodes.add(node)
for child in mygraph.child_nodes(node,
- ignore_priority=digraph.SOFT):
+ ignore_priority=DepPriority.SOFT):
if not gather_deps(
mergeable_nodes, selected_nodes, child):
return False
@@ -1476,7 +1551,7 @@ class depgraph:
for node in myblockers.root_nodes():
retlist.append(node.split())
for parent in self.blocker_parents[node]:
- self.digraph.add(node, parent, priority=digraph.SOFT)
+ self.digraph.add(node, parent, priority=DepPriority())
return retlist
diff --git a/pym/portage.py b/pym/portage.py
index aecbda293..4d6c86a04 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -312,10 +312,6 @@ def flatten(mytokens):
#beautiful directed graph object
class digraph:
- NONE = -1
- SOFT = 0
- MEDIUM = 1
- HARD = 2
def __init__(self):
"""Create an empty digraph"""
@@ -323,7 +319,7 @@ class digraph:
self.nodes = {}
self.order = []
- def add(self, node, parent, priority=2):
+ def add(self, node, parent, priority=0):
"""Adds the specified node with the specified parent.
If the dep is a soft-dep and the node already has a hard
@@ -376,9 +372,9 @@ class digraph:
"""Return a list of all nodes in the graph"""
return self.order[:]
- def child_nodes(self, node, ignore_priority=-1):
+ def child_nodes(self, node, ignore_priority=None):
"""Return all children of the specified node"""
- if ignore_priority == -1:
+ if ignore_priority is None:
return self.nodes[node][0].keys()
children = []
for child, priority in self.nodes[node][0].iteritems():
@@ -390,7 +386,7 @@ class digraph:
"""Return all parents of the specified node"""
return self.nodes[node][1].keys()
- def leaf_nodes(self, ignore_priority=-1):
+ def leaf_nodes(self, ignore_priority=None):
"""Return all nodes that have no children
If ignore_soft_deps is True, soft deps are not counted as
@@ -407,7 +403,7 @@ class digraph:
leaf_nodes.append(node)
return leaf_nodes
- def root_nodes(self, ignore_priority=-1):
+ def root_nodes(self, ignore_priority=None):
"""Return all nodes that have no parents.
If ignore_soft_deps is True, soft deps are not counted as
@@ -454,7 +450,7 @@ class digraph:
return leaf_nodes[0]
return None
- def hasallzeros(self, ignore_priority=-1):
+ def hasallzeros(self, ignore_priority=None):
return len(self.leaf_nodes(ignore_priority=ignore_priority)) == \
len(self.order)
@@ -467,12 +463,7 @@ class digraph:
print "(no children)"
for child in self.nodes[node][0]:
print " ",child,
- if self.nodes[node][0][child] == self.HARD:
- print "(hard)"
- elif self.nodes[node][0][child] == self.MEDIUM:
- print "(medium)"
- else:
- print "(soft)"
+ print "(%s)" % self.nodes[node][0][child]