summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-08-17 01:51:57 +0000
committerZac Medico <zmedico@gentoo.org>2006-08-17 01:51:57 +0000
commit1ebb48b78fc30e0506c67a6e8181b916f9e1f276 (patch)
treeba91f34d1ba63af4bc5b6be9c15c46ca346bd991
parent7f2b985c716788fa223ad1c838adb36872d2dea1 (diff)
downloadportage-1ebb48b78fc30e0506c67a6e8181b916f9e1f276.tar.gz
portage-1ebb48b78fc30e0506c67a6e8181b916f9e1f276.tar.bz2
portage-1ebb48b78fc30e0506c67a6e8181b916f9e1f276.zip
This is a new dep_zapdeps implementation. Thanks to jstubbs for this patch from bug #143908.
svn path=/main/trunk/; revision=4271
-rw-r--r--pym/portage.py104
1 files changed, 61 insertions, 43 deletions
diff --git a/pym/portage.py b/pym/portage.py
index 80f14b8f8..64ea13ccb 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -3323,67 +3323,85 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
unresolved.append(dep)
return unresolved
- # We're at a ( || atom ... ) type level
+ # We're at a ( || atom ... ) type level and need to make a choice
deps = unreduced[1:]
satisfieds = reduced[1:]
- target = None
+ # Our preference order is for an the first item that:
+ # a) contains all unmasked packages with the same key as installed packages
+ # b) contains all unmasked packages
+ # c) contains masked installed packages
+ # d) is the first item
+
+ preferred = []
+ other = []
+
+ # Alias the trees we'll be checking availability against
+ vardb = trees[myroot]["vartree"].dbapi
+ if use_binaries:
+ mydbapi = trees[myroot]["bintree"].dbapi
+ else:
+ mydbapi = trees[myroot]["porttree"].dbapi
+
+ # Sort the deps into preferred (installed) and other
+ # with values of [[required_atom], availablility]
for (dep, satisfied) in zip(deps, satisfieds):
if isinstance(dep, list):
atoms = dep_zapdeps(dep, satisfied, myroot,
use_binaries=use_binaries, trees=trees)
else:
atoms = [dep]
- missing_atoms = [atom for atom in atoms if not trees[myroot]["vartree"].dbapi.match(atom)]
- if not missing_atoms:
- if isinstance(dep, list):
- return atoms # Sorted out by the recursed dep_zapdeps call
- else:
- target = dep_getkey(dep) # An installed package that's not yet in the graph
+ all_installed = True
+ for atom in atoms:
+ if not vardb.match(atom):
+ all_installed = False
break
- if not target:
- if use_binaries:
- missing_atoms = [atom for atom in atoms if not trees[myroot]["bintree"].dbapi.match(atom)]
- else:
- missing_atoms = [atom for atom in atoms if not trees[myroot]["porttree"].dbapi.xmatch("match-visible", atom)]
- if not missing_atoms:
- target = (dep, satisfied)
+ all_available = True
+ for atom in atoms:
+ if not mydbapi.match(atom):
+ all_available = False
+ break
- if not target:
- if isinstance(deps[0], list):
- return dep_zapdeps(deps[0], satisfieds[0], myroot,
- use_binaries=use_binaries, trees=trees)
- else:
- return [deps[0]]
+ # Check if the set of atoms will result in a downgrade of
+ # an installed package. If they will then don't prefer them
+ # over other atoms.
+ if all_installed and all_available:
+ for atom in atoms:
+ inst_pkgs = vardb.match(dep_getkey(atom))
+ avail_pkg = best(mydbapi.match(atom))
+ avail_slot = mydbapi.aux_get(avail_pkg, ["SLOT"])[0]
+ avail_split = catpkgsplit(avail_pkg)[1:]
+ is_okay = False
+ for pkg in inst_pkgs:
+ if avail_slot != vardb.aux_get(pkg, ["SLOT"])[0]:
+ continue
+ if pkgcmp(avail_split, catpkgsplit(pkg)[1:]) >= 0:
+ is_okay = True
+ break
+ if not is_okay:
+ all_installed = False
+ break
- if isinstance(target, tuple): # Nothing matching installed
- if isinstance(target[0], list): # ... and the first available was a sublist
- return dep_zapdeps(target[0], target[1], myroot,
- use_binaries=use_binaries, trees=trees)
- else: # ... and the first available was a single atom
- target = dep_getkey(target[0])
+ if all_installed:
+ preferred.append((atoms, all_available))
+ else:
+ other.append((atoms, all_available))
- relevant_atoms = [dep for dep in deps if not isinstance(dep, list) and dep_getkey(dep) == target]
+ # preferred now contains a) and c) from the order above with
+ # the masked flag differentiating the two. other contains b)
+ # and d) so adding other to preferred will give us a suitable
+ # list to iterate over.
+ preferred.extend(other)
- available_pkgs = {}
- for atom in relevant_atoms:
- if use_binaries:
- pkg_list = trees[myroot]["bintree"].dbapi.match(atom)
- else:
- pkg_list = trees[myroot]["porttree"].dbapi.xmatch("match-visible", atom)
- if not pkg_list:
- continue
- pkg = best(pkg_list)
- available_pkgs[pkg] = atom
+ for allow_masked in (False, True):
+ for atoms, all_available in preferred:
+ if all_available or allow_masked:
+ return atoms
- if not available_pkgs:
- return [relevant_atoms[0]] # All masked
+ assert(False) # This point should not be reachable
- target_pkg = best(available_pkgs.keys())
- suitable_atom = available_pkgs[target_pkg]
- return [suitable_atom]
def dep_expand(mydep, mydb=None, use_cache=1, settings=None):
if not len(mydep):