public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-05-02 19:12 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-05-02 19:12 UTC (permalink / raw
  To: gentoo-commits

commit:     c522bc7e2c2c116a061eca24a1697841947bc433
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon May  2 19:12:13 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon May  2 19:12:13 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=c522bc7e

emerge: rename --no*-atoms to --*-exclude

---
 man/emerge.1                               |    4 ++--
 pym/_emerge/depgraph.py                    |   16 ++++++++--------
 pym/_emerge/help.py                        |    4 ++--
 pym/_emerge/main.py                        |   16 ++++++++--------
 pym/portage/tests/resolver/test_rebuild.py |    2 +-
 5 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index 3dcd20c..f7b6043 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -485,11 +485,11 @@ may have changed.
 Disables the spinner for the session.  The spinner is active when the
 terminal device is determined to be a TTY.  This flag disables it regardless.
 .TP
-.BR "\-\-nousepkg\-atoms " ATOMS
+.BR "\-\-usepkg\-exclude " ATOMS
 A space separated list of package names or slot atoms. Emerge will ignore
 matching binary packages.
 .TP
-.BR "\-\-norebuild\-atoms " ATOMS
+.BR "\-\-rebuild\-exclude " ATOMS
 A space separated list of package names or slot atoms. Emerge will not rebuild
 matching packages due to \fB\-\-rebuild\fR.
 .TP

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index 80d701c..5183b27 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -124,12 +124,12 @@ class _frozen_depgraph_config(object):
 		self.excluded_pkgs = _wildcard_set(atoms)
 		atoms = ' '.join(myopts.get("--reinstall-atoms", [])).split()
 		self.reinstall_atoms = _wildcard_set(atoms)
-		atoms = ' '.join(myopts.get("--nousepkg-atoms", [])).split()
-		self.nousepkg_atoms = _wildcard_set(atoms)
+		atoms = ' '.join(myopts.get("--usepkg-exclude", [])).split()
+		self.usepkg_exclude = _wildcard_set(atoms)
 		atoms = ' '.join(myopts.get("--useoldpkg-atoms", [])).split()
 		self.useoldpkg_atoms = _wildcard_set(atoms)
-		atoms = ' '.join(myopts.get("--norebuild-atoms", [])).split()
-		self.norebuild_atoms = _wildcard_set(atoms)
+		atoms = ' '.join(myopts.get("--rebuild-exclude", [])).split()
+		self.rebuild_exclude = _wildcard_set(atoms)
 
 		self.rebuild = "--rebuild" in myopts
 
@@ -155,11 +155,11 @@ class _rebuild_config(object):
 	def add(self, dep_pkg, dep):
 		parent = dep.collapsed_parent
 		priority = dep.collapsed_priority
-		norebuild_atoms = self._frozen_config.norebuild_atoms
+		rebuild_exclude = self._frozen_config.rebuild_exclude
 		if (self._frozen_config.rebuild and isinstance(parent, Package) and
 			parent.built and (priority.buildtime or priority.runtime) and
 			isinstance(dep_pkg, Package) and
-			not norebuild_atoms.findAtomForPackage(parent)):
+			not rebuild_exclude.findAtomForPackage(parent)):
 			self._graph.add(dep_pkg, parent, priority)
 
 	def _trigger_rebuild(self, parent, build_deps, runtime_deps):
@@ -3406,7 +3406,7 @@ class depgraph(object):
 		use_ebuild_visibility = self._frozen_config.myopts.get(
 			'--use-ebuild-visibility', 'n') != 'n'
 		reinstall_atoms = self._frozen_config.reinstall_atoms
-		nousepkg_atoms = self._frozen_config.nousepkg_atoms
+		usepkg_exclude = self._frozen_config.usepkg_exclude
 		useoldpkg_atoms = self._frozen_config.useoldpkg_atoms
 		matched_oldpkg = []
 		# Behavior of the "selective" parameter depends on
@@ -3454,7 +3454,7 @@ class depgraph(object):
 							modified_use=self._pkg_use_enabled(pkg)):
 						continue
 
-					if built and not installed and nousepkg_atoms.findAtomForPackage(pkg, \
+					if built and not installed and usepkg_exclude.findAtomForPackage(pkg, \
 						modified_use=self._pkg_use_enabled(pkg)):
 						break
 

diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index bf2437d..85026ac 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -559,13 +559,13 @@ def help(myopts, havecolor=1):
 		print("       "+green("--nospinner"))
 		print("              Disables the spinner regardless of terminal type.")
 		print()
-		print("       " + green("--nousepkg-atoms") + " " + turquoise("ATOMS"))
+		print("       " + green("--usepkg-exclude") + " " + turquoise("ATOMS"))
 		desc = "A space separated list of package names or slot atoms." + \
 			" Emerge will ignore matching binary packages."
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
-		print("       " + green("--norebuild-atoms") + " " + turquoise("ATOMS"))
+		print("       " + green("--rebuild-exclude") + " " + turquoise("ATOMS"))
 		desc = "A space separated list of package names or slot atoms." + \
 			" Emerge will not rebuild matching packages due to --rebuild."
 		for line in wrap(desc, desc_width):

diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 434fd5a..552ea20 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -735,14 +735,14 @@ def parse_opts(tmpcmdline, silent=False):
 			"choices"  : true_y_or_n
 		},
 
-		"--nousepkg-atoms": {
+		"--usepkg-exclude": {
 			"help"   :"A space separated list of package names or slot atoms. " + \
 				"Emerge will ignore matching binary packages. ",
 
 			"action" : "append",
 		},
 
-		"--norebuild-atoms": {
+		"--rebuild-exclude": {
 			"help"   :"A space separated list of package names or slot atoms. " + \
 				"Emerge will not rebuild these packages due to the " + \
 				"--rebuild flag. ",
@@ -926,16 +926,16 @@ def parse_opts(tmpcmdline, silent=False):
 			parser.error("Invalid Atom(s) in --reinstall-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
 				(",".join(bad_atoms),))
 
-	if myoptions.norebuild_atoms:
-		bad_atoms = _find_bad_atoms(myoptions.norebuild_atoms)
+	if myoptions.rebuild_exclude:
+		bad_atoms = _find_bad_atoms(myoptions.rebuild_exclude)
 		if bad_atoms and not silent:
-			parser.error("Invalid Atom(s) in --norebuild-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
+			parser.error("Invalid Atom(s) in --rebuild-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
 				(",".join(bad_atoms),))
 
-	if myoptions.nousepkg_atoms:
-		bad_atoms = _find_bad_atoms(myoptions.nousepkg_atoms)
+	if myoptions.usepkg_exclude:
+		bad_atoms = _find_bad_atoms(myoptions.usepkg_exclude)
 		if bad_atoms and not silent:
-			parser.error("Invalid Atom(s) in --nousepkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
+			parser.error("Invalid Atom(s) in --usepkg-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
 				(",".join(bad_atoms),))
 
 	if myoptions.useoldpkg_atoms:

diff --git a/pym/portage/tests/resolver/test_rebuild.py b/pym/portage/tests/resolver/test_rebuild.py
index 9a9e2ee..809dbed 100644
--- a/pym/portage/tests/resolver/test_rebuild.py
+++ b/pym/portage/tests/resolver/test_rebuild.py
@@ -45,7 +45,7 @@ class RebuildTestCase(TestCase):
 				ResolverPlaygroundTestCase(
 					["sys-libs/x"],
 					options = {"--rebuild" : True,
-						"--norebuild-atoms" : ["sys-apps/b"]},
+						"--rebuild-exclude" : ["sys-apps/b"]},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/e-2'],
 					ignore_mergelist_order = True,
 					success = True),



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-05-03 22:59 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-05-03 22:59 UTC (permalink / raw
  To: gentoo-commits

commit:     9a3a1c4b2d182bef0579166589475df93247a009
Author:     David James <davidjames <AT> chromium <DOT> org>
AuthorDate: Tue May  3 20:51:30 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue May  3 22:51:20 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=9a3a1c4b

Add --rebuild-ignore flag.

A space separated list of package names or slot atoms. Emerge will not rebuild
packages that depend on matching packages due to \fB\-\-rebuild\fR.

Change-Id: Ia58fe632ed06c97a22413da0341d7f8da2d65ba8

Review URL: http://gerrit.chromium.org/gerrit/209

---
 man/emerge.1                               |    4 ++++
 pym/_emerge/depgraph.py                    |    6 +++++-
 pym/_emerge/help.py                        |    7 +++++++
 pym/_emerge/main.py                        |   14 ++++++++++++++
 pym/portage/tests/resolver/test_rebuild.py |   18 ++++++++++++++++++
 5 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index f7b6043..2e27e48 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -493,6 +493,10 @@ matching binary packages.
 A space separated list of package names or slot atoms. Emerge will not rebuild
 matching packages due to \fB\-\-rebuild\fR.
 .TP
+.BR "\-\-rebuild\-ignore " ATOMS
+A space separated list of package names or slot atoms. Emerge will not rebuild
+packages that depend on matching packages due to \fB\-\-rebuild\fR.
+.TP
 .BR "\-\-oneshot " (\fB\-1\fR)
 Emerge as normal, but do not add the packages to the world file
 for later updating.

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index 0de443b..b0b4b07 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -130,6 +130,8 @@ class _frozen_depgraph_config(object):
 		self.useoldpkg_atoms = _wildcard_set(atoms)
 		atoms = ' '.join(myopts.get("--rebuild-exclude", [])).split()
 		self.rebuild_exclude = _wildcard_set(atoms)
+		atoms = ' '.join(myopts.get("--rebuild-ignore", [])).split()
+		self.rebuild_ignore = _wildcard_set(atoms)
 
 		self.rebuild = "--rebuild" in myopts
 
@@ -156,10 +158,12 @@ class _rebuild_config(object):
 		parent = dep.collapsed_parent
 		priority = dep.collapsed_priority
 		rebuild_exclude = self._frozen_config.rebuild_exclude
+		rebuild_ignore = self._frozen_config.rebuild_ignore
 		if (self._frozen_config.rebuild and isinstance(parent, Package) and
 			parent.built and (priority.buildtime or priority.runtime) and
 			isinstance(dep_pkg, Package) and
-			not rebuild_exclude.findAtomForPackage(parent)):
+			not rebuild_exclude.findAtomForPackage(parent) and
+			not rebuild_ignore.findAtomForPackage(dep_pkg)):
 			self._graph.add(dep_pkg, parent, priority)
 
 	def _trigger_rebuild(self, parent, build_deps, runtime_deps):

diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index 85026ac..35008c4 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -571,6 +571,13 @@ def help(myopts, havecolor=1):
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
+		print("       " + green("--rebuild-ignore") + " " + turquoise("ATOMS"))
+		desc = "A space separated list of package names or slot atoms." + \
+			" Emerge will not rebuild packages that depend on matching " + \
+			" packages due to --rebuild."
+		for line in wrap(desc, desc_width):
+			print(desc_indent + line)
+		print()
 		print("       "+green("--oneshot")+" ("+green("-1")+" short option)")
 		print("              Emerge as normal, but don't add packages to the world profile.")
 		print("              This package will only be updated if it is depended upon by")

diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 552ea20..1e06ec1 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -750,6 +750,14 @@ def parse_opts(tmpcmdline, silent=False):
 			"action" : "append",
 		},
 
+		"--rebuild-ignore": {
+			"help"   :"A space separated list of package names or slot atoms. " + \
+				"Emerge will not rebuild packages that depend on matching " + \
+				"packages due to the --rebuild flag. ",
+
+			"action" : "append",
+		},
+
 		"--package-moves": {
 			"help"     : "perform package moves when necessary",
 			"type"     : "choice",
@@ -932,6 +940,12 @@ def parse_opts(tmpcmdline, silent=False):
 			parser.error("Invalid Atom(s) in --rebuild-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
 				(",".join(bad_atoms),))
 
+	if myoptions.rebuild_ignore:
+		bad_atoms = _find_bad_atoms(myoptions.rebuild_ignore)
+		if bad_atoms and not silent:
+			parser.error("Invalid Atom(s) in --rebuild-ignore parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
+				(",".join(bad_atoms),))
+
 	if myoptions.usepkg_exclude:
 		bad_atoms = _find_bad_atoms(myoptions.usepkg_exclude)
 		if bad_atoms and not silent:

diff --git a/pym/portage/tests/resolver/test_rebuild.py b/pym/portage/tests/resolver/test_rebuild.py
index fda289c..da2888c 100644
--- a/pym/portage/tests/resolver/test_rebuild.py
+++ b/pym/portage/tests/resolver/test_rebuild.py
@@ -61,6 +61,24 @@ class RebuildTestCase(TestCase):
 						'sys-apps/e-2', 'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
+
+				ResolverPlaygroundTestCase(
+					["sys-libs/x"],
+					options = {"--rebuild" : True,
+						"--rebuild-ignore" : ["sys-libs/x"]},
+					mergelist = ['sys-libs/x-2'],
+					ignore_mergelist_order = True,
+					success = True),
+
+				ResolverPlaygroundTestCase(
+					["sys-libs/x"],
+					options = {"--rebuild" : True,
+						"--rebuild-ignore" : ["sys-apps/b"]},
+					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
+						'sys-apps/e-2'],
+					ignore_mergelist_order = True,
+					success = True),
+
 			)
 
 		playground = ResolverPlayground(ebuilds=ebuilds,



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-05-04 17:06 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-05-04 17:06 UTC (permalink / raw
  To: gentoo-commits

commit:     e4297ca1075342ec89e089802cd25ae0817f3d5b
Author:     David James <davidjames <AT> chromium <DOT> org>
AuthorDate: Wed May  4 06:32:05 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed May  4 17:02:14 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=e4297ca1

emerge: replace --rebuild with finer grained opts

Replace --rebuild option with --rebuild-if-* options.

--rebuild-if-new-rev [ y | n ]
  Rebuild packages when dependencies that are used at both build-time and
  run-time are built, if the dependency is not already installed with the
  same version and revision.

--rebuild-if-new-ver [ y | n ]
  Rebuild packages when dependencies that are used at both build-time and
  run-time are built, if the dependency is not already installed with the
  same version. Revision numbers are ignored.

--rebuild-if-unbuilt [ y | n ]
  Rebuild packages when dependencies that are used at both build-time and
  run-time are built.

Change-Id: Ia50c1702bfe1b98a8d1891740e7bbb045921a905

Review URL: http://gerrit.chromium.org/gerrit/280

---
 man/emerge.1                               |   14 ++++++-
 pym/_emerge/create_depgraph_params.py      |    3 +-
 pym/_emerge/depgraph.py                    |   54 ++++++++++++++++++++++++----
 pym/_emerge/help.py                        |   24 +++++++++++--
 pym/_emerge/main.py                        |   47 ++++++++++++++++++++----
 pym/portage/tests/resolver/test_rebuild.py |   39 ++++++++++++++++++--
 6 files changed, 157 insertions(+), 24 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index 2e27e48..907bb4f 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -546,9 +546,19 @@ Disable the warning message that's shown prior to
 to be set in the \fBmake.conf\fR(5)
 \fBEMERGE_DEFAULT_OPTS\fR variable.
 .TP
-.BR "\-\-rebuild [ y | n ]"
+.BR "\-\-rebuild\-if\-new\-rev [ y | n ]"
 Rebuild packages when dependencies that are used at both build\-time and
-run\-time are upgraded.
+run\-time are built, if the dependency is not already installed with the
+same version and revision.
+.TP
+.BR "\-\-rebuild\-if\-new\-ver [ y | n ]"
+Rebuild packages when dependencies that are used at both build\-time and
+run\-time are built, if the dependency is not already installed with the
+same version. Revision numbers are ignored.
+.TP
+.BR "\-\-rebuild\-if\-unbuilt [ y | n ]"
+Rebuild packages when dependencies that are used at both build\-time and
+run\-time are built.
 .TP
 .BR "\-\-rebuilt\-binaries [ y | n ]"
 Replace installed packages with binary packages that have

diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py
index ae7a8ae..44dceda 100644
--- a/pym/_emerge/create_depgraph_params.py
+++ b/pym/_emerge/create_depgraph_params.py
@@ -37,7 +37,8 @@ def create_depgraph_params(myopts, myaction):
 	deep = myopts.get("--deep")
 	if deep is not None and deep != 0:
 		myparams["deep"] = deep
-	if "--complete-graph" in myopts or "--rebuild" in myopts:
+	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
 	if "--emptytree" in myopts:
 		myparams["empty"] = True

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index b0b4b07..ebfbdd4 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -30,6 +30,7 @@ from portage._sets.base import InternalPackageSet
 from portage.util import cmp_sort_key, writemsg, writemsg_stdout
 from portage.util import writemsg_level
 from portage.util.digraph import digraph
+from portage.versions import catpkgsplit
 
 from _emerge.AtomArg import AtomArg
 from _emerge.Blocker import Blocker
@@ -133,7 +134,9 @@ class _frozen_depgraph_config(object):
 		atoms = ' '.join(myopts.get("--rebuild-ignore", [])).split()
 		self.rebuild_ignore = _wildcard_set(atoms)
 
-		self.rebuild = "--rebuild" in myopts
+		self.rebuild_if_new_rev = "--rebuild-if-new-rev" in myopts
+		self.rebuild_if_new_ver = "--rebuild-if-new-ver" in myopts
+		self.rebuild_if_unbuilt = "--rebuild-if-unbuilt" in myopts
 
 class _depgraph_sets(object):
 	def __init__(self):
@@ -153,19 +156,53 @@ class _rebuild_config(object):
 		self.rebuild_list = backtrack_parameters.rebuild_list.copy()
 		self.orig_rebuild_list = self.rebuild_list.copy()
 		self.reinstall_list = backtrack_parameters.reinstall_list.copy()
+		self.rebuild_if_new_rev = frozen_config.rebuild_if_new_rev
+		self.rebuild_if_new_ver = frozen_config.rebuild_if_new_ver
+		self.rebuild_if_unbuilt = frozen_config.rebuild_if_unbuilt
+		self.rebuild = (self.rebuild_if_new_rev or self.rebuild_if_new_ver or
+			self.rebuild_if_unbuilt)
 
 	def add(self, dep_pkg, dep):
 		parent = dep.collapsed_parent
 		priority = dep.collapsed_priority
 		rebuild_exclude = self._frozen_config.rebuild_exclude
 		rebuild_ignore = self._frozen_config.rebuild_ignore
-		if (self._frozen_config.rebuild and isinstance(parent, Package) and
+		if (self.rebuild and isinstance(parent, Package) and
 			parent.built and (priority.buildtime or priority.runtime) and
 			isinstance(dep_pkg, Package) and
 			not rebuild_exclude.findAtomForPackage(parent) and
 			not rebuild_ignore.findAtomForPackage(dep_pkg)):
 			self._graph.add(dep_pkg, parent, priority)
 
+	def _needs_rebuild(self, dep_pkg):
+		"""Check whether packages that depend on dep_pkg need to be rebuilt."""
+		dep_root_slot = (dep_pkg.root, dep_pkg.slot_atom)
+		if dep_pkg.built or dep_root_slot in self.orig_rebuild_list:
+			return False
+
+		if self.rebuild_if_unbuilt:
+			# dep_pkg is being installed from source, so binary
+			# packages for parents are invalid. Force rebuild
+			return True
+
+		trees = self._frozen_config.trees
+		vardb = trees[dep_pkg.root]["vartree"].dbapi
+		if self.rebuild_if_new_rev:
+			# Parent packages are valid if a package with the same
+			# cpv is already installed.
+			return dep_pkg.cpv not in vardb.match(dep_pkg.slot_atom)
+
+		# Otherwise, parent packages are valid if a package with the same
+		# version (excluding revision) is already installed.
+		assert self.rebuild_if_new_ver
+		cpv_norev = catpkgsplit(dep_pkg.cpv)[:-1]
+		for inst_cpv in vardb.match(dep_pkg.slot_atom):
+			inst_cpv_norev = catpkgsplit(inst_cpv)[:-1]
+			if inst_cpv_norev == cpv_norev:
+				return False
+
+		return True
+
 	def _trigger_rebuild(self, parent, build_deps, runtime_deps):
 		root_slot = (parent.root, parent.slot_atom)
 		if root_slot in self.rebuild_list:
@@ -177,10 +214,7 @@ class _rebuild_config(object):
 			kids = set([build_deps[slot_atom], runtime_deps[slot_atom]])
 			for dep_pkg in kids:
 				dep_root_slot = (dep_pkg.root, slot_atom)
-				if (not dep_pkg.built and
-					dep_root_slot not in self.orig_rebuild_list):
-					# There's no binary package for dep_pkg, so any binary
-					# package for this parent would be invalid. Force rebuild.
+				if self._needs_rebuild(dep_pkg):
 					self.rebuild_list.add(root_slot)
 					return True
 				elif ("--usepkg" in self._frozen_config.myopts and
@@ -205,7 +239,13 @@ class _rebuild_config(object):
 					uri = bintree.get_pkgindex_uri(parent.cpv)
 					dep_uri = bintree.get_pkgindex_uri(dep_pkg.cpv)
 					bindb = bintree.dbapi
-
+					if self.rebuild_if_new_ver and uri and uri != dep_uri:
+						cpv_norev = catpkgsplit(dep_pkg.cpv)[:-1]
+						for cpv in bindb.match(dep_pkg.slot_atom):
+							if cpv_norev == catpkgsplit(cpv)[:-1]:
+								dep_uri = bintree.get_pkgindex_uri(cpv)
+								if uri == dep_uri:
+									break
 					if uri and uri != dep_uri:
 						# 1) Remote binary package is invalid because it was
 						#    built without dep_pkg. Force rebuild.

diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index 35008c4..de50b75 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -629,10 +629,28 @@ def help(myopts, havecolor=1):
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
-		print("       " + green("--rebuild") + " [ %s | %s ]" % \
+		print("       " + green("--rebuild-if-new-rev") + " [ %s | %s ]" % \
 			(turquoise("y"), turquoise("n")))
-		desc = "Rebuild packages when dependencies that are used " + \
-			"at both build-time and run-time are upgraded."
+		desc = "Rebuild packages when dependencies that are " + \
+			"used at both build-time and run-time are built, " + \
+			"if the dependency is not already installed with the " + \
+			"same version and revision."
+		for line in wrap(desc, desc_width):
+			print(desc_indent + line)
+		print()
+		print("       " + green("--rebuild-if-new-ver") + " [ %s | %s ]" % \
+			(turquoise("y"), turquoise("n")))
+		desc = "Rebuild packages when dependencies that are " + \
+			"used at both build-time and run-time are built, " + \
+			"if the dependency is not already installed with the " + \
+			"same version. Revision numbers are ignored."
+		for line in wrap(desc, desc_width):
+			print(desc_indent + line)
+		print()
+		print("       " + green("--rebuild-if-unbuilt") + " [ %s | %s ]" % \
+			(turquoise("y"), turquoise("n")))
+		desc = "Rebuild packages when dependencies that are " + \
+			"used at both build-time and run-time are built."
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()

diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 1e06ec1..92db36e 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -440,7 +440,9 @@ def insert_optional_args(args):
 		'--package-moves'        : y_or_n,
 		'--quiet'                : y_or_n,
 		'--quiet-build'          : y_or_n,
-		'--rebuild'              : y_or_n,
+		'--rebuild-if-new-rev'   : y_or_n,
+		'--rebuild-if-new-ver'   : y_or_n,
+		'--rebuild-if-unbuilt'   : y_or_n,
 		'--rebuilt-binaries'     : y_or_n,
 		'--root-deps'  : ('rdeps',),
 		'--select'               : y_or_n,
@@ -777,9 +779,27 @@ def parse_opts(tmpcmdline, silent=False):
 			"choices"  : true_y_or_n
 		},
 
-		"--rebuild": {
+		"--rebuild-if-new-rev": {
 			"help"     : "Rebuild packages when dependencies that are " + \
-				"used at both build-time and run-time are upgraded.",
+				"used at both build-time and run-time are built, " + \
+				"if the dependency is not already installed with the " + \
+				"same version and revision.",
+			"type"     : "choice",
+			"choices"  : true_y_or_n
+		},
+
+		"--rebuild-if-new-ver": {
+			"help"     : "Rebuild packages when dependencies that are " + \
+				"used at both build-time and run-time are built, " + \
+				"if the dependency is not already installed with the " + \
+				"same version. Revision numbers are ignored.",
+			"type"     : "choice",
+			"choices"  : true_y_or_n
+		},
+
+		"--rebuild-if-unbuilt": {
+			"help"     : "Rebuild packages when dependencies that are " + \
+				"used at both build-time and run-time are built.",
 			"type"     : "choice",
 			"choices"  : true_y_or_n
 		},
@@ -913,7 +933,7 @@ def parse_opts(tmpcmdline, silent=False):
 	else:
 		myoptions.binpkg_respect_use = None
 
-	if myoptions.complete_graph in true_y or myoptions.rebuild in true_y:
+	if myoptions.complete_graph in true_y:
 		myoptions.complete_graph = True
 	else:
 		myoptions.complete_graph = None
@@ -989,10 +1009,23 @@ def parse_opts(tmpcmdline, silent=False):
 	else:
 		myoptions.quiet_build = None
 
-	if myoptions.rebuild in true_y:
-		myoptions.rebuild = True
+	if myoptions.rebuild_if_new_ver in true_y:
+		myoptions.rebuild_if_new_ver = True
+	else:
+		myoptions.rebuild_if_new_ver = None
+
+	if myoptions.rebuild_if_new_rev in true_y:
+		myoptions.rebuild_if_new_rev = True
+		myoptions.rebuild_if_new_ver = None
+	else:
+		myoptions.rebuild_if_new_rev = None
+
+	if myoptions.rebuild_if_unbuilt in true_y:
+		myoptions.rebuild_if_unbuilt = True
+		myoptions.rebuild_if_new_rev = None
+		myoptions.rebuild_if_new_ver = None
 	else:
-		myoptions.rebuild = None
+		myoptions.rebuild_if_unbuilt = None
 
 	if myoptions.rebuilt_binaries in true_y:
 		myoptions.rebuilt_binaries = True

diff --git a/pym/portage/tests/resolver/test_rebuild.py b/pym/portage/tests/resolver/test_rebuild.py
index da2888c..1f4b6ae 100644
--- a/pym/portage/tests/resolver/test_rebuild.py
+++ b/pym/portage/tests/resolver/test_rebuild.py
@@ -15,6 +15,7 @@ class RebuildTestCase(TestCase):
 
 		ebuilds = {
 			"sys-libs/x-1": { },
+			"sys-libs/x-1-r1": { },
 			"sys-libs/x-2": { },
 			"sys-apps/a-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
 			"sys-apps/a-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
@@ -48,7 +49,7 @@ class RebuildTestCase(TestCase):
 		test_cases = (
 				ResolverPlaygroundTestCase(
 					["sys-libs/x"],
-					options = {"--rebuild" : True,
+					options = {"--rebuild-if-unbuilt" : True,
 						"--rebuild-exclude" : ["sys-apps/b"]},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/e-2'],
 					ignore_mergelist_order = True,
@@ -56,7 +57,7 @@ class RebuildTestCase(TestCase):
 
 				ResolverPlaygroundTestCase(
 					["sys-libs/x"],
-					options = {"--rebuild" : True},
+					options = {"--rebuild-if-unbuilt" : True},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
 						'sys-apps/e-2', 'sys-apps/g-2'],
 					ignore_mergelist_order = True,
@@ -64,7 +65,7 @@ class RebuildTestCase(TestCase):
 
 				ResolverPlaygroundTestCase(
 					["sys-libs/x"],
-					options = {"--rebuild" : True,
+					options = {"--rebuild-if-unbuilt" : True,
 						"--rebuild-ignore" : ["sys-libs/x"]},
 					mergelist = ['sys-libs/x-2'],
 					ignore_mergelist_order = True,
@@ -72,13 +73,43 @@ class RebuildTestCase(TestCase):
 
 				ResolverPlaygroundTestCase(
 					["sys-libs/x"],
-					options = {"--rebuild" : True,
+					options = {"--rebuild-if-unbuilt" : True,
 						"--rebuild-ignore" : ["sys-apps/b"]},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
 						'sys-apps/e-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
+				ResolverPlaygroundTestCase(
+					["=sys-libs/x-1-r1"],
+					options = {"--rebuild-if-unbuilt" : True},
+					mergelist = ['sys-libs/x-1-r1', 'sys-apps/a-2',
+						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+					ignore_mergelist_order = True,
+					success = True),
+
+				ResolverPlaygroundTestCase(
+					["=sys-libs/x-1-r1"],
+					options = {"--rebuild-if-new-rev" : True},
+					mergelist = ['sys-libs/x-1-r1', 'sys-apps/a-2',
+						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+					ignore_mergelist_order = True,
+					success = True),
+
+				ResolverPlaygroundTestCase(
+					["=sys-libs/x-1-r1"],
+					options = {"--rebuild-if-new-ver" : True},
+					mergelist = ['sys-libs/x-1-r1'],
+					ignore_mergelist_order = True,
+					success = True),
+
+				ResolverPlaygroundTestCase(
+					["sys-libs/x"],
+					options = {"--rebuild-if-new-ver" : True},
+					mergelist = ['sys-libs/x-2', 'sys-apps/a-2',
+						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+					ignore_mergelist_order = True,
+					success = True),
 			)
 
 		playground = ResolverPlayground(ebuilds=ebuilds,



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-08-26 18:10 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-08-26 18:10 UTC (permalink / raw
  To: gentoo-commits

commit:     2f253bcc364bd75c9b103133a17ea9887a3de15d
Author:     David James <davidjames <AT> chromium <DOT> org>
AuthorDate: Mon Aug 22 23:29:13 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Fri Aug 26 18:05:01 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=2f253bcc

Update --rebuild-if-* flags to rebuild when build dependencies are changed.

Right now, the --rebuild-if-* flags only rebuild packages that are used at
both run-time and build-time. This doesn't help for packages that are used
only at build-time (for example, static libaries).

Rebuilding packages whenever a build-time dependency is changed is easier to
understand and explain, and it handles all cases correctly.

BUG=chromium-os:15517
TEST=Run emerge test suite.

Change-Id: Iae8dab24e8acb6625bc1a0ce41862e90b232eb84

---
 man/emerge.1                               |   14 +--
 pym/_emerge/depgraph.py                    |  150 +++++++++++----------------
 pym/_emerge/help.py                        |   18 ++--
 pym/portage/tests/resolver/test_rebuild.py |   65 +++++++------
 4 files changed, 110 insertions(+), 137 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index 4a19bdb..f7ad3ed 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -556,18 +556,16 @@ to be set in the \fBmake.conf\fR(5)
 \fBEMERGE_DEFAULT_OPTS\fR variable.
 .TP
 .BR "\-\-rebuild\-if\-new\-rev [ y | n ]"
-Rebuild packages when dependencies that are used at both build\-time and
-run\-time are built, if the dependency is not already installed with the
-same version and revision.
+Rebuild packages when build\-time dependencies are built from source, if the
+dependency is not already installed with the same version and revision.
 .TP
 .BR "\-\-rebuild\-if\-new\-ver [ y | n ]"
-Rebuild packages when dependencies that are used at both build\-time and
-run\-time are built, if the dependency is not already installed with the
-same version. Revision numbers are ignored.
+Rebuild packages when build\-time dependencies are built from source, if the
+dependency is not already installed with the same version. Revision numbers
+are ignored.
 .TP
 .BR "\-\-rebuild\-if\-unbuilt [ y | n ]"
-Rebuild packages when dependencies that are used at both build\-time and
-run\-time are built.
+Rebuild packages when build\-time dependencies are built from source.
 .TP
 .BR "\-\-rebuilt\-binaries [ y | n ]"
 Replace installed packages with binary packages that have

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index 8b6125d..42cc659 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -174,7 +174,7 @@ class _rebuild_config(object):
 		rebuild_exclude = self._frozen_config.rebuild_exclude
 		rebuild_ignore = self._frozen_config.rebuild_ignore
 		if (self.rebuild and isinstance(parent, Package) and
-			parent.built and (priority.buildtime or priority.runtime) and
+			parent.built and priority.buildtime and
 			isinstance(dep_pkg, Package) and
 			not rebuild_exclude.findAtomForPackage(parent) and
 			not rebuild_ignore.findAtomForPackage(dep_pkg)):
@@ -209,66 +209,63 @@ class _rebuild_config(object):
 
 		return True
 
-	def _trigger_rebuild(self, parent, build_deps, runtime_deps):
+	def _trigger_rebuild(self, parent, build_deps):
 		root_slot = (parent.root, parent.slot_atom)
 		if root_slot in self.rebuild_list:
 			return False
 		trees = self._frozen_config.trees
-		children = set(build_deps).intersection(runtime_deps)
 		reinstall = False
-		for slot_atom in children:
-			kids = set([build_deps[slot_atom], runtime_deps[slot_atom]])
-			for dep_pkg in kids:
-				dep_root_slot = (dep_pkg.root, slot_atom)
-				if self._needs_rebuild(dep_pkg):
+		for slot_atom, dep_pkg in build_deps.items():
+			dep_root_slot = (dep_pkg.root, slot_atom)
+			if self._needs_rebuild(dep_pkg):
+				self.rebuild_list.add(root_slot)
+				return True
+			elif ("--usepkg" in self._frozen_config.myopts and
+				(dep_root_slot in self.reinstall_list or
+				dep_root_slot in self.rebuild_list or
+				not dep_pkg.installed)):
+
+				# A direct rebuild dependency is being installed. We
+				# should update the parent as well to the latest binary,
+				# if that binary is valid.
+				#
+				# To validate the binary, we check whether all of the
+				# rebuild dependencies are present on the same binhost.
+				#
+				# 1) If parent is present on the binhost, but one of its
+				#    rebuild dependencies is not, then the parent should
+				#    be rebuilt from source.
+				# 2) Otherwise, the parent binary is assumed to be valid,
+				#    because all of its rebuild dependencies are
+				#    consistent.
+				bintree = trees[parent.root]["bintree"]
+				uri = bintree.get_pkgindex_uri(parent.cpv)
+				dep_uri = bintree.get_pkgindex_uri(dep_pkg.cpv)
+				bindb = bintree.dbapi
+				if self.rebuild_if_new_ver and uri and uri != dep_uri:
+					cpv_norev = catpkgsplit(dep_pkg.cpv)[:-1]
+					for cpv in bindb.match(dep_pkg.slot_atom):
+						if cpv_norev == catpkgsplit(cpv)[:-1]:
+							dep_uri = bintree.get_pkgindex_uri(cpv)
+							if uri == dep_uri:
+								break
+				if uri and uri != dep_uri:
+					# 1) Remote binary package is invalid because it was
+					#    built without dep_pkg. Force rebuild.
 					self.rebuild_list.add(root_slot)
 					return True
-				elif ("--usepkg" in self._frozen_config.myopts and
-					(dep_root_slot in self.reinstall_list or
-					dep_root_slot in self.rebuild_list or
-					not dep_pkg.installed)):
-
-					# A direct rebuild dependency is being installed. We
-					# should update the parent as well to the latest binary,
-					# if that binary is valid.
-					#
-					# To validate the binary, we check whether all of the
-					# rebuild dependencies are present on the same binhost.
-					#
-					# 1) If parent is present on the binhost, but one of its
-					#    rebuild dependencies is not, then the parent should
-					#    be rebuilt from source.
-					# 2) Otherwise, the parent binary is assumed to be valid,
-					#    because all of its rebuild dependencies are
-					#    consistent.
-					bintree = trees[parent.root]["bintree"]
-					uri = bintree.get_pkgindex_uri(parent.cpv)
-					dep_uri = bintree.get_pkgindex_uri(dep_pkg.cpv)
-					bindb = bintree.dbapi
-					if self.rebuild_if_new_ver and uri and uri != dep_uri:
-						cpv_norev = catpkgsplit(dep_pkg.cpv)[:-1]
-						for cpv in bindb.match(dep_pkg.slot_atom):
-							if cpv_norev == catpkgsplit(cpv)[:-1]:
-								dep_uri = bintree.get_pkgindex_uri(cpv)
-								if uri == dep_uri:
-									break
-					if uri and uri != dep_uri:
-						# 1) Remote binary package is invalid because it was
-						#    built without dep_pkg. Force rebuild.
-						self.rebuild_list.add(root_slot)
-						return True
-					elif (parent.installed and
-						root_slot not in self.reinstall_list):
-						inst_build_time = parent.metadata.get("BUILD_TIME")
-						try:
-							bin_build_time, = bindb.aux_get(parent.cpv,
-								["BUILD_TIME"])
-						except KeyError:
-							continue
-						if bin_build_time != inst_build_time:
-							# 2) Remote binary package is valid, and local package
-							#    is not up to date. Force reinstall.
-							reinstall = True
+				elif (parent.installed and
+					root_slot not in self.reinstall_list):
+					inst_build_time = parent.metadata.get("BUILD_TIME")
+					try:
+						bin_build_time, = bindb.aux_get(parent.cpv,
+							["BUILD_TIME"])
+					except KeyError:
+						continue
+					if bin_build_time != inst_build_time:
+						# 2) Remote binary package is valid, and local package
+						#    is not up to date. Force reinstall.
+						reinstall = True
 		if reinstall:
 			self.reinstall_list.add(root_slot)
 		return reinstall
@@ -282,31 +279,15 @@ class _rebuild_config(object):
 		need_restart = False
 		graph = self._graph
 		build_deps = {}
-		runtime_deps = {}
-		leaf_nodes = deque(graph.leaf_nodes())
-
-		def ignore_non_runtime(priority):
-			return not priority.runtime
 
-		def ignore_non_buildtime(priority):
-			return not priority.buildtime
+		leaf_nodes = deque(graph.leaf_nodes())
 
 		# Trigger rebuilds bottom-up (starting with the leaves) so that parents
 		# will always know which children are being rebuilt.
 		while graph:
 			if not leaf_nodes:
-				# We're interested in intersection of buildtime and runtime,
-				# so ignore edges that do not contain both.
-				leaf_nodes.extend(graph.leaf_nodes(
-					ignore_priority=ignore_non_runtime))
-				if not leaf_nodes:
-					leaf_nodes.extend(graph.leaf_nodes(
-						ignore_priority=ignore_non_buildtime))
-					if not leaf_nodes:
-						# We'll have to drop an edge that is both
-						# buildtime and runtime. This should be
-						# quite rare.
-						leaf_nodes.append(graph.order[-1])
+				# We'll have to drop an edge. This should be quite rare.
+				leaf_nodes.append(graph.order[-1])
 
 			node = leaf_nodes.popleft()
 			if node not in graph:
@@ -315,32 +296,23 @@ class _rebuild_config(object):
 			slot_atom = node.slot_atom
 
 			# Remove our leaf node from the graph, keeping track of deps.
-			parents = graph.nodes[node][1].items()
+			parents = graph.parent_nodes(node)
 			graph.remove(node)
 			node_build_deps = build_deps.get(node, {})
-			node_runtime_deps = runtime_deps.get(node, {})
-			for parent, priorities in parents:
+			for parent in parents:
 				if parent == node:
 					# Ignore a direct cycle.
 					continue
 				parent_bdeps = build_deps.setdefault(parent, {})
-				parent_rdeps = runtime_deps.setdefault(parent, {})
-				for priority in priorities:
-					if priority.buildtime:
-						parent_bdeps[slot_atom] = node
-					if priority.runtime:
-						parent_rdeps[slot_atom] = node
-				if slot_atom in parent_bdeps and slot_atom in parent_rdeps:
-					parent_rdeps.update(node_runtime_deps)
+				parent_bdeps[slot_atom] = node
 				if not graph.child_nodes(parent):
 					leaf_nodes.append(parent)
 
 			# Trigger rebuilds for our leaf node. Because all of our children
-			# have been processed, build_deps and runtime_deps will be
-			# completely filled in, and self.rebuild_list / self.reinstall_list
-			# will tell us whether any of our children need to be rebuilt or
-			# reinstalled.
-			if self._trigger_rebuild(node, node_build_deps, node_runtime_deps):
+			# have been processed, the build_deps will be completely filled in,
+			# and self.rebuild_list / self.reinstall_list will tell us whether
+			# any of our children need to be rebuilt or reinstalled.
+			if self._trigger_rebuild(node, node_build_deps):
 				need_restart = True
 
 		return need_restart

diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index c978ce2..57b376d 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -641,26 +641,24 @@ def help(myopts, havecolor=1):
 		print()
 		print("       " + green("--rebuild-if-new-rev") + " [ %s | %s ]" % \
 			(turquoise("y"), turquoise("n")))
-		desc = "Rebuild packages when dependencies that are " + \
-			"used at both build-time and run-time are built, " + \
-			"if the dependency is not already installed with the " + \
-			"same version and revision."
+		desc = "Rebuild packages when build-time dependencies are built " + \
+			"from source, if the dependency is not already installed with " + \
+			"the same version and revision."
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
 		print("       " + green("--rebuild-if-new-ver") + " [ %s | %s ]" % \
 			(turquoise("y"), turquoise("n")))
-		desc = "Rebuild packages when dependencies that are " + \
-			"used at both build-time and run-time are built, " + \
-			"if the dependency is not already installed with the " + \
-			"same version. Revision numbers are ignored."
+		desc = "Rebuild packages when build-time dependencies are built " + \
+			"from source, if the dependency is not already installed with " + \
+			"the same version. Revision numbers are ignored."
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
 		print("       " + green("--rebuild-if-unbuilt") + " [ %s | %s ]" % \
 			(turquoise("y"), turquoise("n")))
-		desc = "Rebuild packages when dependencies that are " + \
-			"used at both build-time and run-time are built."
+		desc = "Rebuild packages when build-time dependencies are built " + \
+			"from source"
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()

diff --git a/pym/portage/tests/resolver/test_rebuild.py b/pym/portage/tests/resolver/test_rebuild.py
index b9c4d6d..6f1a783 100644
--- a/pym/portage/tests/resolver/test_rebuild.py
+++ b/pym/portage/tests/resolver/test_rebuild.py
@@ -9,57 +9,58 @@ class RebuildTestCase(TestCase):
 
 	def testRebuild(self):
 		"""
-		Rebuild packages when dependencies that are used at both build-time and
-		run-time are upgraded.
+		Rebuild packages when build-time dependencies are upgraded.
 		"""
 
 		ebuilds = {
 			"sys-libs/x-1": { },
 			"sys-libs/x-1-r1": { },
 			"sys-libs/x-2": { },
-			"sys-apps/a-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/a-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/b-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/b-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
+			"sys-apps/a-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/a-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/b-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/b-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
 			"sys-apps/c-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
 			"sys-apps/c-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
 			"sys-apps/d-1": { "RDEPEND" : "sys-libs/x"},
 			"sys-apps/d-2": { "RDEPEND" : "sys-libs/x"},
-			"sys-apps/e-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/f-2": { "DEPEND"  : "sys-apps/a", "RDEPEND" : "sys-apps/a"},
+			"sys-apps/e-2": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/f-2": { "DEPEND"  : "sys-apps/a", "RDEPEND" : ""},
 			"sys-apps/g-2": { "DEPEND"  : "sys-apps/b sys-libs/x",
-				"RDEPEND" : "sys-apps/b"},
+				"RDEPEND" : ""},
 			}
 
 		installed = {
 			"sys-libs/x-1": { },
-			"sys-apps/a-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/b-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
+			"sys-apps/a-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/b-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
 			"sys-apps/c-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
 			"sys-apps/d-1": { "RDEPEND" : "sys-libs/x"},
-			"sys-apps/e-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : "sys-libs/x"},
-			"sys-apps/f-1": { "DEPEND"  : "sys-apps/a", "RDEPEND" : "sys-apps/a"},
-			"sys-apps/g-1": { "DEPEND"  : "sys-apps/b sys-libs/x",
-				"RDEPEND" : "sys-apps/b"},
+			"sys-apps/e-1": { "DEPEND"  : "sys-libs/x", "RDEPEND" : ""},
+			"sys-apps/f-1": { "DEPEND"  : "sys-apps/a", "RDEPEND" : ""},
+			"sys-apps/g-1": { "DEPEND"  : "sys-apps/b",
+				"RDEPEND" : ""},
 			}
 
 		world = ["sys-apps/a", "sys-apps/b", "sys-apps/c", "sys-apps/d",
 			"sys-apps/e", "sys-apps/f", "sys-apps/g"]
 
+
 		test_cases = (
 				ResolverPlaygroundTestCase(
-					["sys-libs/x"],
+					["sys-libs/x", "sys-apps/b"],
 					options = {"--rebuild-if-unbuilt" : True,
-						"--rebuild-exclude" : ["sys-apps/b"]},
-					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/e-2'],
+						"--rebuild-exclude" : ["sys-apps/c"]},
+					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
+						'sys-apps/e-2', 'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["sys-libs/x"],
+					["sys-libs/x", "sys-apps/b"],
 					options = {"--rebuild-if-unbuilt" : True},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
-						'sys-apps/e-2', 'sys-apps/g-2'],
+						'sys-apps/c-2', 'sys-apps/e-2', 'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
@@ -72,27 +73,29 @@ class RebuildTestCase(TestCase):
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["sys-libs/x"],
+					["sys-libs/x", "sys-apps/b"],
 					options = {"--rebuild-if-unbuilt" : True,
 						"--rebuild-ignore" : ["sys-apps/b"]},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2', 'sys-apps/b-2',
-						'sys-apps/e-2'],
+						'sys-apps/c-2', 'sys-apps/e-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["=sys-libs/x-1-r1"],
+					["=sys-libs/x-1-r1", "sys-apps/b"],
 					options = {"--rebuild-if-unbuilt" : True},
 					mergelist = ['sys-libs/x-1-r1', 'sys-apps/a-2',
-						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+						'sys-apps/b-2', 'sys-apps/c-2', 'sys-apps/e-2',
+						'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["=sys-libs/x-1-r1"],
+					["=sys-libs/x-1-r1", "sys-apps/b"],
 					options = {"--rebuild-if-new-rev" : True},
 					mergelist = ['sys-libs/x-1-r1', 'sys-apps/a-2',
-						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+						'sys-apps/b-2', 'sys-apps/c-2', 'sys-apps/e-2',
+						'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
@@ -104,10 +107,11 @@ class RebuildTestCase(TestCase):
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["sys-libs/x"],
+					["sys-libs/x", "sys-apps/b"],
 					options = {"--rebuild-if-new-ver" : True},
 					mergelist = ['sys-libs/x-2', 'sys-apps/a-2',
-						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+						'sys-apps/b-2', 'sys-apps/c-2', 'sys-apps/e-2',
+						'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 
@@ -119,10 +123,11 @@ class RebuildTestCase(TestCase):
 					success = True),
 
 				ResolverPlaygroundTestCase(
-					["=sys-libs/x-1"],
+					["=sys-libs/x-1", "=sys-apps/b-1"],
 					options = {"--rebuild-if-unbuilt" : True},
 					mergelist = ['sys-libs/x-1', 'sys-apps/a-2',
-						'sys-apps/b-2', 'sys-apps/e-2', 'sys-apps/g-2'],
+						'sys-apps/b-1', 'sys-apps/c-2', 'sys-apps/e-2',
+						'sys-apps/g-2'],
 					ignore_mergelist_order = True,
 					success = True),
 			)



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-09-19 14:37 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-09-19 14:37 UTC (permalink / raw
  To: gentoo-commits

commit:     d36be695ea48025ba195deb82f51846aee2254ec
Author:     Sebastian Luther <SebastianLuther <AT> gmx <DOT> de>
AuthorDate: Mon Sep 19 14:32:08 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Sep 19 14:32:08 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=d36be695

autounmask: Add --autounmask-keep-masks option

Disables creation of p.unmask entries to allow users
to insist on their masks and hope for another conflict
resolution (i.e. missed update). This fixes bug 372485.

---
 man/emerge.1                                  |    5 +++
 pym/_emerge/depgraph.py                       |    4 ++-
 pym/_emerge/help.py                           |    8 +++++
 pym/_emerge/main.py                           |   10 ++++++
 pym/portage/tests/resolver/test_autounmask.py |   39 +++++++++++++++++++++++++
 5 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index d6d74e0..cf7b0e2 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -309,6 +309,11 @@ If \-\-autounmask is enabled, changes using the \'=\' operator
 will be written. With this option, \'>=\' operators will be used
 whenever possible.
 .TP
+.BR "\-\-autounmask\-keep\-masks [ y | n ]"
+If \-\-autounmask is enabled, no changes to package.unmask
+will be created. This leads to unsatisfied dependencies if
+no other solution exists.
+.TP
 .BR "\-\-autounmask\-write [ y | n ]"
 If \-\-autounmask is enabled, changes are written
 to config files, respecting \fBCONFIG_PROTECT\fR and \fB\-\-ask\fR.

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index a5015b8..52d4545 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -3411,6 +3411,8 @@ class depgraph(object):
 
 		default_selection = (pkg, existing)
 
+		autounmask_keep_masks = self._frozen_config.myopts.get("--autounmask-keep-masks", "n") != "n"
+
 		if self._dynamic_config._autounmask is True:
 			if pkg is not None and \
 				pkg.installed and \
@@ -3422,7 +3424,7 @@ class depgraph(object):
 					break
 
 				for allow_unmasks in (False, True):
-					if only_use_changes and allow_unmasks:
+					if allow_unmasks and (only_use_changes or autounmask_keep_masks):
 						continue
 
 					if pkg is not None:

diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index f5ff7a3..4334bcb 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -331,6 +331,14 @@ def help(myopts, havecolor=1):
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
+		print("       " + green("--autounmask-keep-masks") + " [ %s | %s ]" % \
+			(turquoise("y"), turquoise("n")))
+		desc = "If --autounmask is enabled, no changes to " + \
+			"package.unmask will be created. This leads to unsatisfied " + \
+			"dependencies if no other solution exists."
+		for line in wrap(desc, desc_width):
+			print(desc_indent + line)
+		print()
 		print("       " + green("--autounmask-write") + " [ %s | %s ]" % \
 			(turquoise("y"), turquoise("n")))
 		desc = "If --autounmask is enabled, changes are written " + \

diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 73d0795..3f47af7 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -431,6 +431,7 @@ def insert_optional_args(args):
 	default_arg_opts = {
 		'--ask'                  : y_or_n,
 		'--autounmask'           : y_or_n,
+		'--autounmask-keep-masks': y_or_n,
 		'--autounmask-unrestricted-atoms' : y_or_n,
 		'--autounmask-write'     : y_or_n,
 		'--buildpkg'             : y_or_n,
@@ -610,6 +611,12 @@ def parse_opts(tmpcmdline, silent=False):
 			"choices" : true_y_or_n
 		},
 
+		"--autounmask-keep-masks": {
+			"help"    : "don't add package.unmask entries",
+			"type"    : "choice",
+			"choices" : true_y_or_n
+		},
+
 		"--autounmask-write": {
 			"help"    : "write changes made by --autounmask to disk",
 			"type"    : "choice",
@@ -936,6 +943,9 @@ def parse_opts(tmpcmdline, silent=False):
 	if myoptions.autounmask_unrestricted_atoms in true_y:
 		myoptions.autounmask_unrestricted_atoms = True
 
+	if myoptions.autounmask_keep_masks in true_y:
+		myoptions.autounmask_keep_masks = True
+
 	if myoptions.autounmask_write in true_y:
 		myoptions.autounmask_write = True
 

diff --git a/pym/portage/tests/resolver/test_autounmask.py b/pym/portage/tests/resolver/test_autounmask.py
index ff13789..3da1c25 100644
--- a/pym/portage/tests/resolver/test_autounmask.py
+++ b/pym/portage/tests/resolver/test_autounmask.py
@@ -388,3 +388,42 @@ class AutounmaskTestCase(TestCase):
 				self.assertEqual(test_case.test_success, True, test_case.fail_msg)
 		finally:
 			playground.cleanup()
+
+
+	def testAutounmaskKeepMasks(self):
+
+		ebuilds = {
+			"app-text/A-1": {},
+			}
+
+		test_cases = (
+				#Test mask and keyword changes.
+				ResolverPlaygroundTestCase(
+					["app-text/A"],
+					options = {"--autounmask": True,
+								"--autounmask-keep-masks": "y"},
+					success = False),
+				ResolverPlaygroundTestCase(
+					["app-text/A"],
+					options = {"--autounmask": True,
+								"--autounmask-keep-masks": "n"},
+					success = False,
+					mergelist = ["app-text/A-1"],
+					needed_p_mask_changes = ["app-text/A-1"]),
+			)
+
+		profile = {
+			"package.mask":
+				(
+					"app-text/A",
+				),
+		}
+
+		playground = ResolverPlayground(ebuilds=ebuilds, profile=profile)
+
+		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()



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2011-09-21 19:34 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2011-09-21 19:34 UTC (permalink / raw
  To: gentoo-commits

commit:     2733ea17d8e25db8dd369e8890337ddb553e2509
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 21 19:32:19 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed Sep 21 19:32:19 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=2733ea17

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.

---
 man/emerge.1                                      |    4 +
 pym/_emerge/create_depgraph_params.py             |    6 ++
 pym/_emerge/depgraph.py                           |   22 +++----
 pym/_emerge/main.py                               |    7 ++
 pym/portage/tests/resolver/test_complete_graph.py |   66 +++++++++++++++++++++
 5 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index 6d9ce4c..4ec0251 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 44dceda..221c440 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 ffa7e16..8121f68 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 96a6cfa..d2fc0ac 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 0000000..0720643
--- /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()



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/
@ 2012-07-10 22:45 Zac Medico
  0 siblings, 0 replies; 7+ messages in thread
From: Zac Medico @ 2012-07-10 22:45 UTC (permalink / raw
  To: gentoo-commits

commit:     c42591b5d0484459837da28482f70fad9ff13824
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 10 22:45:12 2012 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue Jul 10 22:45:12 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=c42591b5

emerge: add --complete-graph-if-new-use < y | n >

Trigger the --complete-graph behavior if USE or IUSE will change for
an installed package. This option is enabled by default. This will fix
bug #425558.

---
 man/emerge.1                                      |    4 +
 pym/_emerge/create_depgraph_params.py             |    5 ++
 pym/_emerge/depgraph.py                           |   26 +++++++--
 pym/_emerge/main.py                               |    6 ++
 pym/portage/tests/resolver/test_complete_graph.py |   66 ++++++++++++++++++++-
 5 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/man/emerge.1 b/man/emerge.1
index b45e41b..7aa4622 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -396,6 +396,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\-use < y | n >"
+Trigger the \fB\-\-complete\-graph\fR behavior if USE or IUSE will
+change for an installed package. This option is enabled by default.
+.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.

diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py
index 33d413a..2838e93 100644
--- a/pym/_emerge/create_depgraph_params.py
+++ b/pym/_emerge/create_depgraph_params.py
@@ -56,6 +56,11 @@ def create_depgraph_params(myopts, myaction):
 	if deep is not None and deep != 0:
 		myparams["deep"] = deep
 
+	complete_if_new_use = \
+		myopts.get("--complete-graph-if-new-use")
+	if complete_if_new_use is not None:
+		myparams["complete_if_new_use"] = complete_if_new_use
+
 	complete_if_new_ver = \
 		myopts.get("--complete-graph-if-new-ver")
 	if complete_if_new_ver is not None:

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index f819aef..703720c 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -4643,6 +4643,8 @@ class depgraph(object):
 			"recurse" not in self._dynamic_config.myparams:
 			return 1
 
+		complete_if_new_use = self._dynamic_config.myparams.get(
+			"complete_if_new_use", "y") == "y"
 		complete_if_new_ver = self._dynamic_config.myparams.get(
 			"complete_if_new_ver", "y") == "y"
 		rebuild_if_new_slot_abi = self._dynamic_config.myparams.get(
@@ -4650,8 +4652,10 @@ class depgraph(object):
 		complete_if_new_slot = rebuild_if_new_slot_abi
 
 		if "complete" not in self._dynamic_config.myparams and \
-			(complete_if_new_ver or complete_if_new_slot):
-			# Enable complete mode if an installed package version will change.
+			(complete_if_new_use or
+			complete_if_new_ver or complete_if_new_slot):
+			# Enable complete mode if an installed package will change somehow.
+			use_change = False
 			version_change = False
 			for node in self._dynamic_config.digraph:
 				if not isinstance(node, Package) or \
@@ -4660,14 +4664,26 @@ class depgraph(object):
 				vardb = self._frozen_config.roots[
 					node.root].trees["vartree"].dbapi
 
-				if complete_if_new_ver:
+				if complete_if_new_use or complete_if_new_ver:
 					inst_pkg = vardb.match_pkgs(node.slot_atom)
 					if inst_pkg and inst_pkg[0].cp == node.cp:
 						inst_pkg = inst_pkg[0]
-						if inst_pkg < node or node < inst_pkg:
+						if complete_if_new_ver and \
+							(inst_pkg < node or node < inst_pkg):
 							version_change = True
 							break
 
+						# Intersect enabled USE with IUSE, in order to
+						# ignore forced USE from implicit IUSE flags, since
+						# they're probably irrelevant and they are sensitive
+						# to use.mask/force changes in the profile.
+						if complete_if_new_use and \
+							(node.iuse.all != inst_pkg.iuse.all or
+							node.use.enabled.intersection(node.iuse.all) !=
+							inst_pkg.use.enabled.intersection(inst_pkg.iuse.all)):
+							use_change = True
+							break
+
 				if complete_if_new_slot:
 					cp_list = vardb.match_pkgs(Atom(node.cp))
 					if (cp_list and cp_list[0].cp == node.cp and
@@ -4675,7 +4691,7 @@ class depgraph(object):
 						version_change = True
 						break
 
-			if version_change:
+			if use_change or version_change:
 				self._dynamic_config.myparams["complete"] = True
 
 		if "complete" not in self._dynamic_config.myparams:

diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 2a0e67f..640f320 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -703,6 +703,12 @@ def parse_opts(tmpcmdline, silent=False):
 			"choices" : true_y_or_n
 		},
 
+		"--complete-graph-if-new-use": {
+			"help"    : "trigger --complete-graph behavior if USE or IUSE will change for an installed package",
+			"type"    : "choice",
+			"choices" : 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",

diff --git a/pym/portage/tests/resolver/test_complete_graph.py b/pym/portage/tests/resolver/test_complete_graph.py
index 850b883..1b0342c 100644
--- a/pym/portage/tests/resolver/test_complete_graph.py
+++ b/pym/portage/tests/resolver/test_complete_graph.py
@@ -1,4 +1,4 @@
-# Copyright 2011 Gentoo Foundation
+# Copyright 2011-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from portage.tests import TestCase
@@ -7,6 +7,70 @@ from portage.tests.resolver.ResolverPlayground import (ResolverPlayground,
 
 class CompleteGraphTestCase(TestCase):
 
+	def testCompleteGraphUseChange(self):
+		"""
+		Prevent reverse dependency breakage triggered by USE changes.
+		"""
+
+		ebuilds = {
+			"dev-libs/libxml2-2.8.0": {
+				"EAPI": "2",
+				"IUSE": "+icu",
+				"SLOT": "2",
+			},
+			"x11-libs/qt-webkit-4.8.2": {
+				"EAPI": "2",
+				"IUSE": "icu",
+				"RDEPEND" : "dev-libs/libxml2:2[!icu?]",
+			},
+		}
+
+		installed = {
+			"dev-libs/libxml2-2.8.0": {
+				"EAPI": "2",
+				"IUSE": "+icu",
+				"USE": "",
+				"SLOT": "2",
+			},
+			"x11-libs/qt-webkit-4.8.2": {
+				"EAPI": "2",
+				"IUSE": "icu",
+				"RDEPEND" : "dev-libs/libxml2:2[-icu]",
+				"USE": "",
+			}
+		}
+
+		world = ["x11-libs/qt-webkit"]
+
+		test_cases = (
+
+			ResolverPlaygroundTestCase(
+				["dev-libs/libxml2"],
+				options = {"--complete-graph-if-new-use" : "y" },
+				mergelist = ["dev-libs/libxml2-2.8.0"],
+				slot_collision_solutions = [{'dev-libs/libxml2-2.8.0': {'icu': False}}],
+				success = False,
+			),
+
+			ResolverPlaygroundTestCase(
+				["dev-libs/libxml2"],
+				options = {"--complete-graph-if-new-use" : "n" },
+				mergelist = ["dev-libs/libxml2-2.8.0"],
+				success = True,
+			),
+
+		)
+
+		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()
+
 	def testCompleteGraphVersionChange(self):
 		"""
 		Prevent reverse dependency breakage triggered by version changes.



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-07-10 22:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-02 19:12 [gentoo-commits] proj/portage:master commit in: man/, pym/portage/tests/resolver/, pym/_emerge/ Zac Medico
  -- strict thread matches above, loose matches on Subject: below --
2011-05-03 22:59 Zac Medico
2011-05-04 17:06 Zac Medico
2011-08-26 18:10 Zac Medico
2011-09-19 14:37 Zac Medico
2011-09-21 19:34 Zac Medico
2012-07-10 22:45 Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox