Gentoo Logo
Gentoo Spaceship




Note: Due to technical difficulties, the Archives are currently not up to date. GMANE provides an alternative service for most mailing lists.
c.f. bug 424647
List Archive: gentoo-commits
Navigation:
Lists: gentoo-commits: < Prev By Thread Next > < Prev By Date Next >
Headers:
To: gentoo-commits@g.o
From: "Fabian Groffen (grobian)" <grobian@g.o>
Subject: portage r9374 - in main/branches/prefix: bin pym/_emerge pym/portage/dbapi pym/portage/sets
Date: Sat, 23 Feb 2008 23:37:51 +0000
Author: grobian
Date: 2008-02-23 23:37:49 +0000 (Sat, 23 Feb 2008)
New Revision: 9374

Modified:
   main/branches/prefix/bin/repoman
   main/branches/prefix/pym/_emerge/__init__.py
   main/branches/prefix/pym/portage/dbapi/vartree.py
   main/branches/prefix/pym/portage/sets/dbapi.py
Log:
   Merged from trunk 9335:9351

   | 9336    | Fix package selection logic in order to prevent downgrade in |
   | zmedico | cases when selective is True and the currently installed     |
   |         | version does not have a matching ebuild in the tree. For     |
   |         | example, this type of situation is likely to occur if the    |
   |         | user somehow obtains a binary package that has a newer       |
   |         | version than any of the ebuilds in the portage tree. If      |
   |         | package maintainers want to encourage a downgrade in a case  |
   |         | like this then they should use package.mask so that the user |
   |         | receives a warning about the installed package being masked. |
   
   | 9337    | Fix --newuse reinstall logic broken by the previous commit.  |
   | zmedico |                                                              |
   
   | 9338    | Update the DepPriority documentation so that the table shows |
   | zmedico | all the currently supported priorities and categories.       |
   
   | 9339    | Bug #201045 - Use a topological sort to create an unmerge    |
   | zmedico | order such that each package is unmerged before it's         |
   |         | dependencies. This is necessary to avoid breaking things     |
   |         | that may need to run during pkg_prerm or pkg_postrm phases.  |
   
   | 9340    | Make depclean code filter out blocker atoms where            |
   | zmedico | appropriate.                                                 |
   
   | 9341    | Fix depclean breakage so that it doesn't clean some packages |
   | zmedico | that shouldn't be cleaned.                                   |
   
   | 9342    | Add missing % x (bug #208946, comment #2).                   |
   | zmedico |                                                              |
   
   | 9343    | Fix reversed order of parent/child parameders to             |
   | zmedico | digraph.add().                                               |
   
   | 9344    | Remove IUSE.invalid from qawarnings since there's no reason  |
   | zmedico | for it not to be fatal. Thanks to Betelgeuse.                |
   
   | 9345    | In the action_depclean() topological sort, only add packages |
   | zmedico | to the graph if they are being removed.                      |
   
   | 9346    | Bug #201045 - Make unmerge() preserve the unmerge order of   |
   | zmedico | packages given to it by the user or depclean.                |
   
   | 9347    | Make sure all packages to be pruned or depcleaned are added  |
   | zmedico | to the graph, even when they don't have any dependencies.    |
   
   | 9348    | Now that unmerge() preserves the order that it's given, if   |
   | zmedico | two different slots of the same package are being unmerged   |
   |         | then they are not necessarily unmerged consecutively. To     |
   |         | make the display less confusing, never display packages as   |
   |         | "protected" or "omitted" when they actually belong to the    |
   |         | overall set of "selected" packages to be unmerged.           |
   
   | 9349    | Fix unmerge() breakage from due to pkgmap being changed from |
   | zmedico | a dict to a list.                                            |
   
   | 9350    | Fix the --depclean/--prune code to use visible() for         |
   | zmedico | visibility checks instead of the old portdbapi hack.         |
   
   | 9351    | Make LibraryConsumerSet.mapPathsToAtoms() produce slot atoms |
   | zmedico | so that atoms aren't restricted to the currently installed   |
   |         | version, making upgrades possible.                           |


Modified: main/branches/prefix/bin/repoman
===================================================================
--- main/branches/prefix/bin/repoman	2008-02-23 23:33:46 UTC (rev 9373)
+++ main/branches/prefix/bin/repoman	2008-02-23 23:37:49 UTC (rev 9374)
@@ -320,7 +320,6 @@
 "DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
 "DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
 "DESCRIPTION.toolong",
-"IUSE.invalid",
 "KEYWORDS.stupid",
 "KEYWORDS.missing",
 "RESTRICT.invalid",

Modified: main/branches/prefix/pym/_emerge/__init__.py
===================================================================
--- main/branches/prefix/pym/_emerge/__init__.py	2008-02-23 23:33:46 UTC (rev 9373)
+++ main/branches/prefix/pym/_emerge/__init__.py	2008-02-23 23:37:49 UTC (rev 9374)
@@ -840,7 +840,38 @@
 		else:
 			yield flag
 
-class DepPriority(object):
+class AbstractDepPriority(object):
+	__slots__ = ("__weakref__", "buildtime", "runtime", "runtime_post")
+	def __init__(self, **kwargs):
+		for myattr in chain(self.__slots__, AbstractDepPriority.__slots__):
+			if myattr == "__weakref__":
+				continue
+			myvalue = kwargs.get(myattr, False)
+			setattr(self, myattr, myvalue)
+
+	def __lt__(self, other):
+		return self.__int__() < other
+
+	def __le__(self, other):
+		return self.__int__() <= other
+
+	def __eq__(self, other):
+		return self.__int__() == other
+
+	def __ne__(self, other):
+		return self.__int__() != other
+
+	def __gt__(self, other):
+		return self.__int__() > other
+
+	def __ge__(self, other):
+		return self.__int__() >= other
+
+	def copy(self):
+		import copy
+		return copy.copy(self)
+
+class DepPriority(AbstractDepPriority):
 	"""
 		This class generates an integer priority level based of various
 		attributes of the dependency relationship.  Attributes can be assigned
@@ -851,13 +882,16 @@
 		"buildtime", "runtime", and "system".  Various combinations of
 		attributes lead to the following priority levels:
 
-		Combination of properties    Priority level
+		Combination of properties           Priority  Category
 
-		not satisfied and buildtime     0
-		not satisfied and runtime      -1
-		satisfied and buildtime        -2
-		satisfied and runtime          -3
-		(none of the above)            -4
+		not satisfied and buildtime            0       HARD
+		not satisfied and runtime             -1       MEDIUM
+		not satisfied and runtime_post        -2       MEDIUM_SOFT
+		satisfied and buildtime and rebuild   -3       SOFT
+		satisfied and buildtime               -4       SOFT
+		satisfied and runtime                 -5       SOFT
+		satisfied and runtime_post            -6       SOFT
+		(none of the above)                   -6       SOFT
 
 		Several integer constants are defined for categorization of priority
 		levels:
@@ -867,17 +901,12 @@
 		SOFT     The upper boundary for soft dependencies.
 		MIN      The lower boundary for soft dependencies.
 	"""
-	__slots__ = ("__weakref__", "satisfied", "buildtime", "runtime", "runtime_post", "rebuild")
+	__slots__ = ("satisfied", "rebuild")
 	MEDIUM = -1
 	MEDIUM_SOFT = -2
 	SOFT   = -3
 	MIN    = -6
-	def __init__(self, **kwargs):
-		for myattr in self.__slots__:
-			if myattr == "__weakref__":
-				continue
-			myvalue = kwargs.get(myattr, False)
-			setattr(self, myattr, myvalue)
+
 	def __int__(self):
 		if not self.satisfied:
 			if self.buildtime:
@@ -895,21 +924,7 @@
 		if self.runtime_post:
 			return -6
 		return -6
-	def __lt__(self, other):
-		return self.__int__() < other
-	def __le__(self, other):
-		return self.__int__() <= other
-	def __eq__(self, other):
-		return self.__int__() == other
-	def __ne__(self, other):
-		return self.__int__() != other
-	def __gt__(self, other):
-		return self.__int__() > other
-	def __ge__(self, other):
-		return self.__int__() >= other
-	def copy(self):
-		import copy
-		return copy.copy(self)
+
 	def __str__(self):
 		myvalue = self.__int__()
 		if myvalue > self.MEDIUM:
@@ -920,6 +935,35 @@
 			return "medium-soft"
 		return "soft"
 
+class UnmergeDepPriority(AbstractDepPriority):
+	"""
+	Combination of properties           Priority  Category
+
+	runtime                                0       HARD
+	runtime_post                          -1       HARD
+	buildtime                             -2       SOFT
+	(none of the above)                   -2       SOFT
+	"""
+
+	MAX    =  0
+	SOFT   = -2
+	MIN    = -2
+
+	def __int__(self):
+		if self.runtime:
+			return 0
+		if self.runtime_post:
+			return -1
+		if self.buildtime:
+			return -2
+		return -2
+
+	def __str__(self):
+		myvalue = self.__int__()
+		if myvalue > self.SOFT:
+			return "hard"
+		return "soft"
+
 class FakeVartree(portage.vartree):
 	"""This is implements an in-memory copy of a vartree instance that provides
 	all the interfaces required for use by the depgraph.  The vardb is locked
@@ -2527,6 +2571,7 @@
 		usepkgonly = "--usepkgonly" in self.myopts
 		empty = "empty" in self.myparams
 		selective = "selective" in self.myparams
+		reinstall = False
 		# Behavior of the "selective" parameter depends on
 		# whether or not a package matches an argument atom.
 		# If an installed package provides an old-style
@@ -2546,9 +2591,12 @@
 				if existing_node:
 					break
 				if installed and not find_existing_node and \
+					(reinstall or not selective) and \
 					(matched_packages or empty):
-					# We only need to select an installed package here
-					# if there is no other choice.
+					# We only need to select an installed package in the
+					# following cases:
+					#   1) there is no other choice
+					#   2) selective is True
 					continue
 				if hasattr(db, "xmatch"):
 					cpv_list = db.xmatch("match-all", atom)
@@ -2656,6 +2704,8 @@
 							self._reinstall_for_flags(
 							forced_flags, old_use, old_iuse,
 							cur_use, cur_iuse)
+						if reinstall_for_flags:
+							reinstall = True
 					if not installed:
 						must_reinstall = empty or \
 							(myarg and not selective)
@@ -4944,7 +4994,7 @@
 			print darkgreen(newline+\
 				">>> These are the packages that would be unmerged:")
 	
-		pkgmap={}
+		pkgmap = []
 		numselected=0
 		for x in candidate_catpkgs:
 			# cycle through all our candidate deps and determine
@@ -4970,11 +5020,8 @@
 				portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \
 					(x, unmerge_action), noiselevel=-1)
 				continue
-			mykey = portage.key_expand(
-				portage.dep_getkey(
-					mymatch[0]), mydb=vartree.dbapi, settings=settings)
-			if not pkgmap.has_key(mykey):
-				pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
+			pkgmap.append({"protected":[], "selected":[], "omitted":[] })
+			mykey = len(pkgmap) - 1
 			if unmerge_action=="unmerge":
 					for y in mymatch:
 						if y not in pkgmap[mykey]["selected"]:
@@ -5044,25 +5091,38 @@
 	finally:
 		if vdb_lock:
 			portage.locks.unlockdir(vdb_lock)
+	all_selected = set()
 	for x in pkgmap:
-		for y in localtree.dep_match(x):
+		all_selected.update(x["selected"])
+	for x in xrange(len(pkgmap)):
+		selected = pkgmap[x]["selected"]
+		if not selected:
+			continue
+		for mytype, mylist in pkgmap[x].iteritems():
+			if mytype == "selected":
+				continue
+			pkgmap[x][mytype] = \
+				[cpv for cpv in mylist if cpv not in all_selected]
+		cp = portage.cpv_getkey(selected[0])
+		for y in localtree.dep_match(cp):
 			if y not in pkgmap[x]["omitted"] and \
 			   y not in pkgmap[x]["selected"] and \
-			   y not in pkgmap[x]["protected"]:
+			   y not in pkgmap[x]["protected"] and \
+			   y not in all_selected:
 				pkgmap[x]["omitted"].append(y)
 		if global_unmerge and not pkgmap[x]["selected"]:
 			#avoid cluttering the preview printout with stuff that isn't getting unmerged
 			continue
-		if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
-			print colorize("BAD","\a\n\n!!! '%s' is part of your system profile." % x)
+		if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist:
+			print colorize("BAD","\a\n\n!!! '%s' is part of your system profile." % cp)
 			print colorize("WARN","\a!!! Unmerging it may be damaging to your system.\n")
 			if "--pretend" not in myopts and "--ask" not in myopts:
 				countdown(int(settings["EMERGE_WARNING_DELAY"]),
 					colorize("UNMERGE_WARN", "Press Ctrl-C to Stop"))
 		if "--quiet" not in myopts:
-			print "\n "+white(x)
+			print "\n "+bold(cp)
 		else:
-			print white(x)+": ",
+			print bold(cp)+": ",
 		for mytype in ["selected","protected","omitted"]:
 			if "--quiet" not in myopts:
 				portage.writemsg_stdout((mytype + ": ").rjust(14), noiselevel=-1)
@@ -5109,7 +5169,7 @@
 	if not autoclean:
 		countdown(int(settings["CLEAN_DELAY"]), ">>> Unmerging")
 
-	for x in pkgmap:
+	for x in xrange(len(pkgmap)):
 		for y in pkgmap[x]["selected"]:
 			print ">>> Unmerging "+y+"..."
 			emergelog(xterm_titles, "=== Unmerging... ("+y+")")
@@ -6413,23 +6473,32 @@
 	if "--quiet" not in myopts:
 		print "\nCalculating dependencies  ",
 
-	soft = 0
-	hard = 1
+	runtime = UnmergeDepPriority(runtime=True)
+	runtime_post = UnmergeDepPriority(runtime_post=True)
+	buildtime = UnmergeDepPriority(buildtime=True)
+
+	priority_map = {
+		"RDEPEND": runtime,
+		"PDEPEND": runtime_post,
+		"DEPEND": buildtime,
+	}
+
 	remaining_atoms = []
 	if action == "depclean":
 		for atom in worldlist:
 			if vardb.match(atom):
-				remaining_atoms.append((atom, 'world', hard))
+				remaining_atoms.append((atom, 'world', runtime))
 		for atom in syslist:
 			if vardb.match(atom):
-				remaining_atoms.append((atom, 'system', hard))
+				remaining_atoms.append((atom, 'system', runtime))
 	elif action == "prune":
 		for atom in syslist:
 			if vardb.match(atom):
-				remaining_atoms.append((atom, 'system', hard))
+				remaining_atoms.append((atom, 'system', runtime))
 		# Pull in everything that's installed since we don't want to prune a
 		# package if something depends on it.
-		remaining_atoms.extend((atom, 'world', hard) for atom in vardb.cp_all())
+		remaining_atoms.extend(
+			(atom, 'world', runtime) for atom in vardb.cp_all())
 		if not myfiles:
 			# Try to prune everything that's slotted.
 			for cp in vardb.cp_all():
@@ -6438,14 +6507,15 @@
 
 	unresolveable = {}
 	aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
-	metadata_keys = ["PROVIDE", "SLOT", "USE"]
+	metadata_keys = depgraph._mydbapi_keys
 	graph = digraph()
+	with_bdeps = myopts.get("--with-bdeps", "y") == "y"
 
 	while remaining_atoms:
 		atom, parent, priority = remaining_atoms.pop()
 		pkgs = vardb.match(atom)
 		if not pkgs:
-			if not atom.startswith("!") and priority == hard:
+			if priority > UnmergeDepPriority.SOFT:
 				unresolveable.setdefault(atom, []).append(parent)
 			continue
 		if action == "depclean" and parent == "world" and myfiles:
@@ -6470,44 +6540,42 @@
 					filtered_pkgs.append(pkg)
 			pkgs = filtered_pkgs
 		if len(pkgs) > 1:
-			# Prune all but the best matching slot, since that's all that a
-			# deep world update would pull in.  Don't prune if this atom comes
-			# directly from world though, since world atoms are greedy when
-			# they don't specify a slot.
-			visible_in_portdb = [cpv for cpv in pkgs if portdb.match("="+cpv)]
-			if visible_in_portdb:
-				# For consistency with the update algorithm, keep the highest
-				# visible version and prune any versions that are either masked
-				# or no longer exist in the portage tree.
-				pkgs = visible_in_portdb
-			pkgs = [portage.best(pkgs)]
+			# For consistency with the update algorithm, keep the highest
+			# visible version and prune any versions that are old or masked.
+			for cpv in reversed(pkgs):
+				metadata = dict(izip(metadata_keys,
+					vardb.aux_get(cpv, metadata_keys)))
+				if visible(settings, cpv, metadata,
+					built=True, installed=True):
+					pkgs = [cpv]
+					break
+			if len(pkgs) > 1:
+				# They're all masked, so just keep the highest version.
+				pkgs = [pkgs[-1]]
 		for pkg in pkgs:
-			graph.add(pkg, parent)
+			graph.add(pkg, parent, priority=priority)
 			if fakedb.cpv_exists(pkg):
 				continue
 			spinner.update()
 			fakedb.cpv_inject(pkg)
 			myaux = dict(izip(aux_keys, vardb.aux_get(pkg, aux_keys)))
 			mydeps = []
-			if myopts.get("--with-bdeps", "y") == "y":
-				mydeps.append((myaux["DEPEND"], soft))
-			del myaux["DEPEND"]
-			mydeps.append((" ".join(myaux.values()), hard))
+
 			usedef = vardb.aux_get(pkg, ["USE"])[0].split()
-			for depstr, priority in mydeps:
+			for dep_type, depstr in myaux.iteritems():
 
 				if not depstr:
 					continue
 
+				if not with_bdeps and dep_type == "DEPEND":
+					continue
+
+				priority = priority_map[dep_type]
 				if "--debug" in myopts:
 					print
 					print "Parent:   ", pkg
 					print "Depstring:", depstr
-					print "Priority:",
-					if priority == soft:
-						print "soft"
-					else:
-						print "hard"
+					print "Priority:", priority
 
 				try:
 					portage.dep._dep_check_strict = False
@@ -6525,6 +6593,8 @@
 					print "Candidates:", atoms
 
 				for atom in atoms:
+					if atom.startswith("!"):
+						continue
 					remaining_atoms.append((atom, pkg, priority))
 
 	if "--quiet" not in myopts:
@@ -6612,6 +6682,75 @@
 					good("--nodeps"))
 
 	if len(cleanlist):
+		# Use a topological sort to create an unmerge order such that
+		# each package is unmerged before it's dependencies. This is
+		# necessary to avoid breaking things that may need to run
+		# during pkg_prerm or pkg_postrm phases.
+
+		# Create a new graph to account for dependencies between the
+		# packages being unmerged.
+		graph = digraph()
+		clean_set = set(cleanlist)
+		del cleanlist[:]
+		for node in clean_set:
+			graph.add(node, None)
+			myaux = dict(izip(aux_keys, vardb.aux_get(node, aux_keys)))
+			mydeps = []
+			usedef = vardb.aux_get(pkg, ["USE"])[0].split()
+			for dep_type, depstr in myaux.iteritems():
+				if not depstr:
+					continue
+				try:
+					portage.dep._dep_check_strict = False
+					success, atoms = portage.dep_check(depstr, None, settings,
+						myuse=usedef, trees=dep_check_trees, myroot=myroot)
+				finally:
+					portage.dep._dep_check_strict = True
+				if not success:
+					show_invalid_depstring_notice(
+						("installed", myroot, node, "nomerge"),
+						depstr, atoms)
+					return
+
+				priority = priority_map[dep_type]
+				for atom in atoms:
+					if atom.startswith("!"):
+						continue
+					matches = vardb.match(atom)
+					if not matches:
+						continue
+					for cpv in matches:
+						if cpv in clean_set:
+							graph.add(cpv, node, priority=priority)
+
+		# Order nodes from lowest to highest overall reference count for
+		# optimal root node selection.
+		node_refcounts = {}
+		for node in graph.order:
+			node_refcounts[node] = len(graph.parent_nodes(node))
+		def cmp_reference_count(node1, node2):
+			return node_refcounts[node1] - node_refcounts[node2]
+		graph.order.sort(cmp_reference_count)
+
+		ignore_priority_range = [None]
+		ignore_priority_range.extend(
+			xrange(UnmergeDepPriority.MIN, UnmergeDepPriority.MAX + 1))
+		while not graph.empty():
+			for ignore_priority in ignore_priority_range:
+				nodes = graph.root_nodes(ignore_priority=ignore_priority)
+				if nodes:
+					break
+			if not nodes:
+				raise AssertionError("no root nodes")
+			if ignore_priority is not None:
+				# Some deps have been dropped due to circular dependencies,
+				# so only pop one node in order do minimize the number that
+				# are dropped.
+				del nodes[1:]
+			for node in nodes:
+				graph.remove(node)
+				cleanlist.append(node)
+
 		unmerge(root_config, myopts,
 			"unmerge", cleanlist, ldpath_mtimes)
 

Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
===================================================================
--- main/branches/prefix/pym/portage/dbapi/vartree.py	2008-02-23 23:33:46 UTC (rev 9373)
+++ main/branches/prefix/pym/portage/dbapi/vartree.py	2008-02-23 23:37:49 UTC (rev 9374)
@@ -1601,7 +1601,7 @@
 		for x in preserve_paths:
 			print "injecting %s into %s" % (x, srcroot)
 			if not os.path.exists(os.path.join(destroot, x.lstrip(os.sep))):
-				print "%s does not exist so can't be preserved"
+				print "%s does not exist so can't be preserved" % x
 				missing_paths.append(x)
 				continue
 			mydir = os.path.join(srcroot, os.path.dirname(x).lstrip(os.sep))

Modified: main/branches/prefix/pym/portage/sets/dbapi.py
===================================================================
--- main/branches/prefix/pym/portage/sets/dbapi.py	2008-02-23 23:33:46 UTC (rev 9373)
+++ main/branches/prefix/pym/portage/sets/dbapi.py	2008-02-23 23:37:49 UTC (rev 9374)
@@ -126,8 +126,10 @@
 			link = dblink(mysplit[0], mysplit[1], myroot=self.dbapi.root, \
 					mysettings=self.dbapi.settings, treetype='vartree', \
 					vartree=self.dbapi.vartree)
-			if paths.intersection(link.getcontents().keys()):
-				rValue.add("/".join(catpkgsplit(cpv)[:2]))
+			if paths.intersection(link.getcontents()):
+				cat, pn = catpkgsplit(cpv)[:2]
+				slot = self.dbapi.aux_get(cpv, ["SLOT"])[0]
+				rValue.add("%s/%s:%s" % (cat, pn, slot))
 		return rValue
 	
 

-- 
gentoo-commits@g.o mailing list


Navigation:
Lists: gentoo-commits: < Prev By Thread Next > < Prev By Date Next >
Previous by thread:
gentoo-x86 commit in dev-ml/camlp5: ChangeLog camlp5-5.08.ebuild
Next by thread:
gentoo-x86 commit in sys-kernel/xen-sources: ChangeLog xen-sources-2.6.22.ebuild
Previous by date:
gentoo-x86 commit in dev-ml/camlp5: ChangeLog camlp5-5.08.ebuild
Next by date:
gentoo-x86 commit in sys-kernel/xen-sources: ChangeLog xen-sources-2.6.22.ebuild


Updated Aug 28, 2011

Summary: Archive of the gentoo-commits mailing list.

Donate to support our development efforts.

Copyright 2001-2013 Gentoo Foundation, Inc. Questions, Comments? Contact us.