node.operation != "uninstall"]
# sys-apps/portage needs special treatment if ROOT="/"
- portage_python_dep = ">=dev-lang/python-2.4"
- portage_unslotted_deps = frozenset(
- ["app-shells/bash", "sys-apps/portage"])
- portage_node = self.mydbapi["/"].match_pkgs("sys-apps/portage")
- if portage_node:
- portage_node = portage_node[0]
+ running_root = "/"
+ from portage.const import PORTAGE_PACKAGE_ATOM
+ runtime_deps = InternalPackageSet(
+ initial_atoms=[PORTAGE_PACKAGE_ATOM])
+ running_portage = self.trees[running_root]["vartree"].dbapi.match_pkgs(
+ PORTAGE_PACKAGE_ATOM)
+ replacement_portage = self.mydbapi[running_root].match_pkgs(
+ PORTAGE_PACKAGE_ATOM)
+
+ if running_portage:
+ running_portage = running_portage[0]
else:
- portage_node = None
- if portage_node is not None and \
- (not mygraph.contains(portage_node) or \
- portage_node.operation == "nomerge"):
- portage_node = None
+ running_portage = None
+
+ if replacement_portage:
+ replacement_portage = replacement_portage[0]
+ else:
+ replacement_portage = None
+
+ if replacement_portage == running_portage:
+ replacement_portage = None
+
+ if running_portage is not None:
+ try:
+ portage_rdepend = self._select_atoms_highest_available(
+ running_root, running_portage.metadata["RDEPEND"],
+ myuse=running_portage.metadata["USE"].split(),
+ parent=running_portage, strict=False)
+ except portage.exception.InvalidDependString, e:
+ portage.writemsg("!!! Invalid RDEPEND in " + \
+ "'%svar/db/pkg/%s/RDEPEND': %s\n" % \
+ (running_root, running_portage.cpv, e), noiselevel=-1)
+ del e
+ portage_rdepend = []
+ runtime_deps.update(atom for atom in portage_rdepend \
+ if not atom.startswith("!"))
ignore_priority_soft_range = [None]
ignore_priority_soft_range.extend(
return True
if node not in mergeable_nodes:
return False
- if node == portage_node and mygraph.child_nodes(node,
+ if node == replacement_portage and \
+ mygraph.child_nodes(node,
ignore_priority=DepPriority.MEDIUM_SOFT):
# Make sure that portage always has all of it's
# RDEPENDs installed first.
if self.digraph.contains(inst_pkg):
continue
- if "/" == task.root:
+ if running_root == task.root:
# Never uninstall sys-apps/portage or it's essential
# dependencies, except through replacement.
- if task.cp in portage_unslotted_deps:
+ try:
+ runtime_dep_atoms = \
+ list(runtime_deps.iterAtomsForPackage(task))
+ except portage.exception.InvalidDependString, e:
+ portage.writemsg("!!! Invalid PROVIDE in " + \
+ "'%svar/db/pkg/%s/PROVIDE': %s\n" % \
+ (task.root, task.cpv, e), noiselevel=-1)
+ del e
continue
- # Don't uninstall python if it appears to be
- # the only suitable one installed.
- if task.cp == "dev-lang/python" and \
- portage.match_from_list(
- portage_python_dep, [task.cpv_slot]):
- vardb = root_config.trees["vartree"].dbapi
+ # Don't uninstall a runtime dep if it appears
+ # to be the only suitable one installed.
+ skip = False
+ vardb = root_config.trees["vartree"].dbapi
+ for atom in runtime_dep_atoms:
other_version = None
- for pkg in vardb.match_pkgs(portage_python_dep):
+ for pkg in vardb.match_pkgs(atom):
if pkg.cpv == task.cpv and \
pkg.metadata["COUNTER"] == \
task.metadata["COUNTER"]:
other_version = pkg
break
if other_version is None:
- continue
+ skip = True
+ break
+ if skip:
+ continue
# For packages in the system set, don't take
# any chances. If the conflict can't be resolved