summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/_emerge/__init__.py78
-rw-r--r--pym/portage/const.py1
2 files changed, 57 insertions, 22 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index e89f75ff6..c788263c5 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -3489,18 +3489,42 @@ class depgraph(object):
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(
@@ -3584,7 +3608,8 @@ class depgraph(object):
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.
@@ -3679,20 +3704,26 @@ class depgraph(object):
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"]:
@@ -3700,7 +3731,10 @@ class depgraph(object):
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
diff --git a/pym/portage/const.py b/pym/portage/const.py
index 733029fa4..bc949fb91 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -24,6 +24,7 @@ GLOBAL_CONFIG_PATH = "/usr/share/portage/config"
PORTAGE_BASE_PATH = os.path.join(os.sep, os.sep.join(__file__.split(os.sep)[:-3]))
PORTAGE_BIN_PATH = PORTAGE_BASE_PATH+"/bin"
PORTAGE_PYM_PATH = PORTAGE_BASE_PATH+"/pym"
+PORTAGE_PACKAGE_ATOM = "sys-apps/portage"
NEWS_LIB_PATH = "/var/lib/gentoo"
PROFILE_PATH = "/etc/make.profile"
LOCALE_DATA_PATH = PORTAGE_BASE_PATH+"/locale"