summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-09-21 12:32:19 -0700
committerZac Medico <zmedico@gentoo.org>2011-09-21 12:32:19 -0700
commit2733ea17d8e25db8dd369e8890337ddb553e2509 (patch)
tree8017996740d2d9bc780eeed5592a77513c02a041
parentf127d25373a42f3200a331b7f2641a1cf0e90b50 (diff)
downloadportage-2733ea17d8e25db8dd369e8890337ddb553e2509.tar.gz
portage-2733ea17d8e25db8dd369e8890337ddb553e2509.tar.bz2
portage-2733ea17d8e25db8dd369e8890337ddb553e2509.zip
emerge: add --complete-graph-if-new-ver < y | n >
Trigger the --complete-graph behavior if an installed package version will change (upgrade or downgrade). This option is enabled by default.
-rw-r--r--man/emerge.14
-rw-r--r--pym/_emerge/create_depgraph_params.py6
-rw-r--r--pym/_emerge/depgraph.py22
-rw-r--r--pym/_emerge/main.py7
-rw-r--r--pym/portage/tests/resolver/test_complete_graph.py66
5 files changed, 93 insertions, 12 deletions
diff --git a/man/emerge.1 b/man/emerge.1
index 6d9ce4c44..4ec025127 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -376,6 +376,10 @@ be updated than would have otherwise been updated with the option disabled.
Using \fB\-\-with\-bdeps=y\fR together with \fB\-\-complete\-graph\fR makes
the graph as complete as possible.
.TP
+.BR "\-\-complete\-graph\-if\-new\-ver < y | n >"
+Trigger the \fB\-\-complete\-graph\fR behavior if an installed package
+version will change (upgrade or downgrade). This option is enabled by default.
+.TP
.BR \-\-config\-root=DIR
Set the \fBPORTAGE_CONFIGROOT\fR environment variable.
.TP
diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py
index 44dceda37..221c440ef 100644
--- a/pym/_emerge/create_depgraph_params.py
+++ b/pym/_emerge/create_depgraph_params.py
@@ -37,6 +37,12 @@ def create_depgraph_params(myopts, myaction):
deep = myopts.get("--deep")
if deep is not None and deep != 0:
myparams["deep"] = deep
+
+ complete_if_new_ver = \
+ myopts.get("--complete-graph-if-new-ver")
+ if complete_if_new_ver is not None:
+ myparams["complete_if_new_ver"] = complete_if_new_ver
+
if ("--complete-graph" in myopts or "--rebuild-if-new-rev" in myopts or
"--rebuild-if-new-ver" in myopts or "--rebuild-if-unbuilt" in myopts):
myparams["complete"] = True
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index ffa7e167e..8121f68bc 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -4145,11 +4145,10 @@ class depgraph(object):
"recurse" not in self._dynamic_config.myparams:
return 1
- if "complete" not in self._dynamic_config.myparams:
- # Automatically enable complete mode if there are any
- # downgrades, since they often break dependencies
- # (like in bug #353613).
- have_downgrade = False
+ if "complete" not in self._dynamic_config.myparams and \
+ self._dynamic_config.myparams.get("complete_if_new_ver", "y") == "y":
+ # Enable complete mode if an installed package version will change.
+ version_change = False
for node in self._dynamic_config.digraph:
if not isinstance(node, Package) or \
node.operation != "merge":
@@ -4157,16 +4156,15 @@ class depgraph(object):
vardb = self._frozen_config.roots[
node.root].trees["vartree"].dbapi
inst_pkg = vardb.match_pkgs(node.slot_atom)
- if inst_pkg and inst_pkg[0] > node:
- have_downgrade = True
+ if inst_pkg and (inst_pkg[0] > node or inst_pkg[0] < node):
+ version_change = True
break
- if have_downgrade:
+ if version_change:
self._dynamic_config.myparams["complete"] = True
- else:
- # Skip complete graph mode, in order to avoid consuming
- # enough time to disturb users.
- return 1
+
+ if "complete" not in self._dynamic_config.myparams:
+ return 1
self._load_vdb()
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 96a6cfadb..d2fc0ac5f 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -588,6 +588,7 @@ def parse_opts(tmpcmdline, silent=False):
])
longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"}
+ y_or_n = ("y", "n")
true_y_or_n = ("True", "y", "n")
true_y = ("True", "y")
argument_options = {
@@ -659,6 +660,12 @@ def parse_opts(tmpcmdline, silent=False):
"choices" : true_y_or_n
},
+ "--complete-graph-if-new-ver": {
+ "help" : "trigger --complete-graph behavior if an installed package version will change (upgrade or downgrade)",
+ "type" : "choice",
+ "choices" : y_or_n
+ },
+
"--deep": {
"shortopt" : "-D",
diff --git a/pym/portage/tests/resolver/test_complete_graph.py b/pym/portage/tests/resolver/test_complete_graph.py
new file mode 100644
index 000000000..07206430e
--- /dev/null
+++ b/pym/portage/tests/resolver/test_complete_graph.py
@@ -0,0 +1,66 @@
+# Copyright 2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import (ResolverPlayground,
+ ResolverPlaygroundTestCase)
+
+class CompleteGraphTestCase(TestCase):
+
+ def testCompleteGraphVersionChange(self):
+ """
+ Prevent reverse dependency breakage triggered by version changes.
+ """
+
+ ebuilds = {
+ "sys-libs/x-0.1": {},
+ "sys-libs/x-1": {},
+ "sys-libs/x-2": {},
+ "sys-apps/a-1": {"RDEPEND" : ">=sys-libs/x-1 <sys-libs/x-2"},
+ }
+
+ installed = {
+ "sys-libs/x-1": {},
+ "sys-apps/a-1": {"RDEPEND" : ">=sys-libs/x-1 <sys-libs/x-2"},
+ }
+
+ world = ["sys-apps/a"]
+
+ test_cases = (
+ ResolverPlaygroundTestCase(
+ [">=sys-libs/x-2"],
+ options = {"--complete-graph-if-new-ver" : "n"},
+ mergelist = ["sys-libs/x-2"],
+ success = True,
+ ),
+ ResolverPlaygroundTestCase(
+ [">=sys-libs/x-2"],
+ options = {"--complete-graph-if-new-ver" : "y"},
+ mergelist = ["sys-libs/x-2"],
+ slot_collision_solutions = [],
+ success = False,
+ ),
+ ResolverPlaygroundTestCase(
+ ["<sys-libs/x-1"],
+ options = {"--complete-graph-if-new-ver" : "n"},
+ mergelist = ["sys-libs/x-0.1"],
+ success = True,
+ ),
+ ResolverPlaygroundTestCase(
+ ["<sys-libs/x-1"],
+ options = {"--complete-graph-if-new-ver" : "y"},
+ mergelist = ["sys-libs/x-0.1"],
+ slot_collision_solutions = [],
+ success = False,
+ ),
+ )
+
+ playground = ResolverPlayground(ebuilds=ebuilds,
+ installed=installed, world=world, debug=False)
+
+ try:
+ for test_case in test_cases:
+ playground.run_TestCase(test_case)
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg)
+ finally:
+ playground.cleanup()