View | Details | Raw Unified
Collapse All | Expand All

(-) portage.orig/bin/emerge (-43 / +41 lines)
 Lines 352-375    Link Here 
	# recurse:   go into the dependencies
	# recurse:   go into the dependencies
	# deep:      go into the dependencies of already merged packages
	# deep:      go into the dependencies of already merged packages
	# empty:     pretend nothing is merged
	# empty:     pretend nothing is merged
	myparams=["self","recurse"]
	myparams=["self","recurse","selective"]
	add=[]
	add=[]
	sub=[]
	sub=[]
	if "--update" in myopts or myaction in ("system", "world"):
	if "--update" in myopts or myaction in ("system", "world"):
		add.extend(["selective","empty"])
		add.extend(["empty"])
	if "--emptytree" in myopts:
	if "--emptytree" in myopts:
		add.extend(["empty"])
		add.extend(["empty"])
		sub.extend(["selective"])
		sub.extend(["selective"])
	if "--nodeps" in myopts:
	if "--nodeps" in myopts:
		sub.extend(["recurse"])
		sub.extend(["recurse"])
	if "--noreplace" in myopts:
		add.extend(["selective"])
	if "--deep" in myopts:
	if "--deep" in myopts:
		add.extend(["deep"])
		add.extend(["deep"])
	if "--selective" in myopts:
		add.extend(["selective"])
	if myaction in ["world","system"]:
		add.extend(["selective"])
	elif myaction in ["depclean"]:
	elif myaction in ["depclean"]:
		add.extend(["empty"])
		add.extend(["empty"])
		sub.extend(["selective"])
		sub.extend(["selective"])
 Lines 679-685    Link Here 
					"--getbinpkg" in self.myopts,
					"--getbinpkg" in self.myopts,
					"--getbinpkgonly" in self.myopts)
					"--getbinpkgonly" in self.myopts)
	def create(self,mybigkey,myparent=None,addme=1,myuse=None):
	def create(self,mybigkey,myparent=None,addme=1,myuse=None,soft_dep=False,arg=None):
		"""
		"""
		Fills the digraph with nodes comprised of packages to merge.
		Fills the digraph with nodes comprised of packages to merge.
		mybigkey is the package spec of the package to merge.
		mybigkey is the package spec of the package to merge.
 Lines 697-706    Link Here 
			if addme and jbigkey != myparent:
			if addme and jbigkey != myparent:
				# Refuse to make a node depend on itself so that the we don't
				# Refuse to make a node depend on itself so that the we don't
				# don't create a bogus circular dependency in self.altlist().
				# don't create a bogus circular dependency in self.altlist().
				self.digraph.addnode(jbigkey, myparent)
				self.digraph.addnode(jbigkey, myparent, soft_dep=soft_dep)
			return 1
			return 1
		jbigkey = " ".join(mybigkey) + " nomerge"
		jbigkey = " ".join(mybigkey) + " nomerge"
		if self.digraph.hasnode(jbigkey):
		if self.digraph.hasnode(jbigkey):
			self.digraph.addnode(jbigkey, myparent, soft_dep=soft_dep)
			return 1
			return 1
		
		
		self.spinner.update()
		self.spinner.update()
 Lines 723-729    Link Here 
				if self.mydbapi[parent_root].match(mykey) or \
				if self.mydbapi[parent_root].match(mykey) or \
					self.trees[parent_root]["vartree"].dbapi.match(mykey):
					self.trees[parent_root]["vartree"].dbapi.match(mykey):
					mybigkey.append(myparent.split()[2])
					mybigkey.append(myparent.split()[2])
					self.digraph.addnode(" ".join(mybigkey), myparent)
					self.digraph.addnode(" ".join(mybigkey), myparent, soft_dep=soft_dep)
			return 1
			return 1
		else:
		else:
			mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi
			mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi
 Lines 744-750    Link Here 
				    installed we skip merging it."""
				    installed we skip merging it."""
				if "self" not in self.myparams or \
				if "self" not in self.myparams or \
					("selective" in self.myparams and \
					("selective" in self.myparams and \
					vardbapi.cpv_exists(mykey)):
					not arg and vardbapi.cpv_exists(mykey)):
					merging=0
					merging=0
			elif "selective" in self.myparams and vardbapi.cpv_exists(mykey):
			elif "selective" in self.myparams and vardbapi.cpv_exists(mykey):
				merging=0
				merging=0
 Lines 782-788    Link Here 
		""" At this point, we have either hit a blocker and returned, found the package in the
		""" At this point, we have either hit a blocker and returned, found the package in the
		    depgraph already and returned, or we are here.  Whether we are merging or not; we must
		    depgraph already and returned, or we are here.  Whether we are merging or not; we must
		    add the package to the depgraph; so we do that here. """
		    add the package to the depgraph; so we do that here. """
		self.digraph.addnode(string.join(mybigkey),myparent)
		self.digraph.addnode(string.join(mybigkey),myparent,soft_dep=soft_dep)
		
		
		""" This section determines whether we go deeper into dependencies or not.
		""" This section determines whether we go deeper into dependencies or not.
		    We want to go deeper on a few occasions:
		    We want to go deeper on a few occasions:
 Lines 815-840    Link Here 
		""" We have retrieve the dependency information, now we need to recursively
		""" We have retrieve the dependency information, now we need to recursively
		    process them.  DEPEND gets processed for root = "/", {R,P}DEPEND in myroot. """
		    process them.  DEPEND gets processed for root = "/", {R,P}DEPEND in myroot. """
		
		
		mydep={}
		mp=string.join(mybigkey)
		mp=string.join(mybigkey)
		try:
		try:
			if myroot=="/":
			if not self.select_dep("/",edepend["DEPEND"],myparent=mp,myuse=myuse):
				mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
				return 0
				if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
			if not self.select_dep(myroot,edepend["RDEPEND"],myparent=mp,myuse=myuse,soft_deps=True):
					return 0
				return 0
			else:
				mydep["/"]=edepend["DEPEND"]
				mydep[myroot]=edepend["RDEPEND"]
				if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
					return 0
				if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
					return 0
	
			if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
			if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
				# Post Depend -- Add to the list without a parent, as it depends
				# Post Depend -- Add to the list without a parent, as it depends
				# on a package being present AND must be built after that package.
				# on a package being present AND must be built after that package.
				if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
				if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse,soft_deps=True):
					return 0
					return 0
		except ValueError, e:
		except ValueError, e:
			pkgs = e.args[0]
			pkgs = e.args[0]
 Lines 940-946    Link Here 
				sys.stderr.flush()
				sys.stderr.flush()
				try:
				try:
					self.mysd = self.select_dep(myroot, mykey, arg=x)
					if "--noreplace" in self.myopts:
						arg = None
					else:
						arg = x
					self.mysd = self.select_dep(myroot, mykey, arg=arg)
				except portage_exception.MissingSignature, e:
				except portage_exception.MissingSignature, e:
					portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
					portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
 Lines 969-975    Link Here 
		missing=0
		missing=0
		if "--usepkgonly" in self.myopts:
		if "--usepkgonly" in self.myopts:
			for x in self.digraph.dict.keys():
			for x in self.digraph.all_nodes():
				xs=string.split(x," ")
				xs=string.split(x," ")
				if (xs[0] != "binary") and (xs[3]=="merge"):
				if (xs[0] != "binary") and (xs[3]=="merge"):
					if missing == 0:
					if missing == 0:
 Lines 993-999    Link Here 
					if curslot == myslot:
					if curslot == myslot:
						return match
						return match
	def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
	def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False,soft_deps=False):
		""" Given a depstring, create the depgraph such that all dependencies are satisfied.
		""" Given a depstring, create the depgraph such that all dependencies are satisfied.
		    myroot = $ROOT from environment, where {R,P}DEPENDs are merged to.
		    myroot = $ROOT from environment, where {R,P}DEPENDs are merged to.
		    myparent = the node whose depstring is being passed in
		    myparent = the node whose depstring is being passed in
 Lines 1006-1011    Link Here 
		portdb = self.trees[myroot]["porttree"].dbapi
		portdb = self.trees[myroot]["porttree"].dbapi
		bindb  = self.trees[myroot]["bintree"].dbapi
		bindb  = self.trees[myroot]["bintree"].dbapi
		vardb  = self.trees[myroot]["vartree"].dbapi
		pkgsettings = self.pkgsettings[myroot]
		pkgsettings = self.pkgsettings[myroot]
		if "--debug" in self.myopts:
		if "--debug" in self.myopts:
 Lines 1020-1026    Link Here 
			mycheck = portage.dep_check(depstring, self.mydbapi[myroot],
			mycheck = portage.dep_check(depstring, self.mydbapi[myroot],
				pkgsettings, myuse=myuse,
				pkgsettings, myuse=myuse,
				use_binaries=("--usepkgonly" in self.myopts),
				use_binaries=("--usepkgonly" in self.myopts),
				myroot=myroot, trees=self.trees)
				myroot=myroot, trees=self.trees, return_all_deps=True)
			if not mycheck[0]:
			if not mycheck[0]:
				mymerge=[]
				mymerge=[]
 Lines 1056-1064    Link Here 
				self.pkgsettings[p_root].setinst(p_key,
				self.pkgsettings[p_root].setinst(p_key,
					self.trees[p_root][self.pkg_tree_map[p_type]].dbapi)
					self.trees[p_root][self.pkg_tree_map[p_type]].dbapi)
		if not mymerge:
			return 1
		if "--debug" in self.myopts:
		if "--debug" in self.myopts:
			print "Candidates:",mymerge
			print "Candidates:",mymerge
		for x in mymerge:
		for x in mymerge:
 Lines 1076-1081    Link Here 
				selected_pkg = ["blocks", myroot, x[1:], None]
				selected_pkg = ["blocks", myroot, x[1:], None]
			else:
			else:
				#We are not processing a blocker but a normal dependency
				#We are not processing a blocker but a normal dependency
				pkg_key = portage.dep_getkey(x)
				if pkg_key in pkgsettings.pprovideddict and \
					portage.match_from_list(
						x, pkgsettings.pprovideddict[pkg_key]):
						continue
				# List of acceptable packages, ordered by type preference.
				# List of acceptable packages, ordered by type preference.
				matched_packages = []
				matched_packages = []
				myeb_matches = portdb.xmatch("match-visible", x)
				myeb_matches = portdb.xmatch("match-visible", x)
 Lines 1178-1192    Link Here 
			if myparent:
			if myparent:
				#we are a dependency, so we want to be unconditionally added
				#we are a dependency, so we want to be unconditionally added
				soft_dep = soft_deps or vardb.match(x)
				if not self.create(selected_pkg[0:3], myparent,
				if not self.create(selected_pkg[0:3], myparent,
					myuse=selected_pkg[-1]):
					myuse=selected_pkg[-1], soft_dep=soft_dep, arg=arg):
					return 0
					return 0
			else:
			else:
				#if mysource is not set, then we are a command-line dependency and should not be added
				#if mysource is not set, then we are a command-line dependency and should not be added
				#if --onlydeps is specified.
				#if --onlydeps is specified.
				if not self.create(selected_pkg[0:3], myparent,
				if not self.create(selected_pkg[0:3], myparent,
					addme=("--onlydeps" not in self.myopts),
					addme=("--onlydeps" not in self.myopts),
					myuse=selected_pkg[-1]):
					myuse=selected_pkg[-1], arg=arg):
					return 0
					return 0
		if "--debug" in self.myopts:
		if "--debug" in self.myopts:
 Lines 1205-1217    Link Here 
		while (not mygraph.empty()):
		while (not mygraph.empty()):
			mycurkey=mygraph.firstzero()
			mycurkey=mygraph.firstzero()
			if not mycurkey:
			if not mycurkey:
				print "!!! Error: circular dependencies:"
				installables = mygraph.leaf_nodes(ignore_soft_deps=True)
				print
				if not installables:
				for x in mygraph.dict.keys():
					print "!!! Error: circular dependencies:"
					for y in mygraph.dict[x][1]:
					print
						print y,"depends on",x
					for x in mygraph.allnodes():
				print
						for y in mygraph.parent_nodes(x):
				sys.exit(1)
							print y,"depends on",x
						print
					sys.exit(1)
				mycurkey = installables[0]
			splitski=string.split(mycurkey)
			splitski=string.split(mycurkey)
			#I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
			#I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
			#These lines remove already-merged things from our alt-list
			#These lines remove already-merged things from our alt-list
(-) portage.orig/pym/portage.py (-87 / +159 lines)
 Lines 313-396    Link Here 
class digraph:
class digraph:
	def __init__(self):
	def __init__(self):
		self.dict={}
		"""Create an empty digraph"""
		#okeys = keys, in order they were added (to optimize firstzero() ordering)
		
		self.okeys=[]
		# { node : ( { child : soft_dep } , { parent : soft_dep } ) }
		self.nodes = {}
	def addnode(self,mykey,myparent):
		self.order = []
		if not self.dict.has_key(mykey):
			self.okeys.append(mykey)
			if myparent is None:
				self.dict[mykey]=[0,[]]
			else:
				self.dict[mykey]=[0,[myparent]]
				self.dict[myparent][0]=self.dict[myparent][0]+1
			return
		if myparent and (not myparent in self.dict[mykey][1]):
			self.dict[mykey][1].append(myparent)
			self.dict[myparent][0]=self.dict[myparent][0]+1
	def delnode(self,mykey):
	def add(self, node, parent, soft_dep=False):
		if not self.dict.has_key(mykey):
		"""Adds the specified node with the specified parent.
		
		If the dep is a soft-dep and the node already has a hard
		relationship to the parent, the relationship is left as hard."""
		
		if node not in self.nodes:
			self.nodes[node] = ({}, {})
			self.order.append(node)
		
		if not parent:
			return
			return
		for x in self.dict[mykey][1]:
		
			self.dict[x][0]=self.dict[x][0]-1
		if parent not in self.nodes:
		del self.dict[mykey]
			self.nodes[parent] = ({}, {})
		while 1:
			self.order.append(parent)
			try:
		
				self.okeys.remove(mykey)
		if parent in self.nodes[node][1]:
			except ValueError:
			if not soft_dep:
				break
				self.nodes[node][1][parent] = False
		else:
			self.nodes[node][1][parent] = soft_dep
		
		if node in self.nodes[parent][0]:
			if not soft_dep:
				self.nodes[parent][0][node] = False
		else:
			self.nodes[parent][0][node] = soft_dep
	def remove(self, node):
		"""Removes the specified node from the digraph, also removing
		and ties to other nodes in the digraph. Raises KeyError if the
		node doesn't exist."""
		
		if node not in self.nodes:
			raise KeyError(node)
		
		for parent in self.nodes[node][1]:
			del self.nodes[parent][0][node]
		for child in self.nodes[node][0]:
			del self.nodes[child][1][node]
		
		del self.nodes[node]
		self.order.remove(node)
	def contains(self, node):
		"""Checks if the digraph contains mynode"""
		return node in self.nodes
	def all_nodes(self):
		"""Return a list of all nodes in the graph"""
		return self.order[:]
	def child_nodes(self, node):
		"""Return all children of the specified node"""
		return self.nodes[node][0].keys()
	def parent_nodes(self, node):
		"""Return all parents of the specified node"""
		return self.nodes[node][1].keys()
	def leaf_nodes(self, ignore_soft_deps=False):
		"""Return all nodes that have no children
		
		If ignore_soft_deps is True, soft deps are not counted as
		children in calculations."""
		
		leaf_nodes = []
		for node in self.order:
			is_leaf_node = True
			for child in self.nodes[node][0]:
				if not (ignore_soft_deps and self.nodes[node][0][child]):
					is_leaf_node = False
					break
			if is_leaf_node:
				leaf_nodes.append(node)
		return leaf_nodes
	def is_empty(self):
		"""Checks if the digraph is empty"""
		return len(self.nodes) == 0
	def clone(self):
		clone = digraph()
		clone.nodes = copy.deepcopy(self.nodes)
		clone.order = self.order[:]
		return clone
	# Backward compatibility
	addnode = add
	allnodes = all_nodes
	allzeros = leaf_nodes
	hasnode = contains
	empty = is_empty
	copy = clone
	def allnodes(self):
	def delnode(self, node):
		"returns all nodes in the dictionary"
		try:
		return self.dict.keys()
			self.remove(node)
		except KeyError:
			pass
	def firstzero(self):
	def firstzero(self):
		"returns first node with zero references, or NULL if no such node exists"
		leaf_nodes = self.leaf_nodes()
		for x in self.okeys:
		if leaf_nodes:
			if self.dict[x][0]==0:
			return leaf_nodes[0]
				return x
		return None
		return None
	def depth(self, mykey):
		depth=0
		while (self.dict[mykey][1]):
			depth=depth+1
			mykey=self.dict[mykey][1][0]
		return depth
	def allzeros(self):
		"returns all nodes with zero references, or NULL if no such node exists"
		zerolist = []
		for x in self.dict.keys():
			mys = string.split(x)
			if mys[0] != "blocks" and self.dict[x][0]==0:
				zerolist.append(x)
		return zerolist
	def hasallzeros(self):
	def hasallzeros(self):
		"returns 0/1, Are all nodes zeros? 1 : 0"
		return len(self.leaf_nodes() == 0)
		zerolist = []
		for x in self.dict.keys():
			if self.dict[x][0]!=0:
				return 0
		return 1
	def empty(self):
	def depth(self, node):
		if len(self.dict)==0:
		"""Find how many nodes are in the parent chain of the passed node
			return 1
		
		return 0
		This method doesn't make sense unless there is no more than one
		parent for each node. As this digraph is capable of having multiple
		parents on a node, this implementation chooses an arbitrary parent
		for calculations, stopping as soon as a loop is detected in order
		to mimic the sorts of counts that would have previously been
		returned.
		
		This method is only used by emerge's --tree option. That option
		needs to be reworked to not use this so that this method can be
		removed altogether."""
		
		parents = {}
		while self.nodes[node][1]:
			parent = self.nodes[node][1].keys()[0]
			if parent in parents:
				break
			parents[parent] = True
			node = parent
		return len(parents)
	
	def debug_print(self):
		for node in self.nodes:
			print node,
			if self.nodes[node][0]:
				print "depends on"
			else:
				print "(no children)"
			for child in self.nodes[node][0]:
				print "  ",child,
				if self.nodes[node][0][child]:
					print "(hard)"
				else:
					print "(soft)"
	def hasnode(self,mynode):
		return self.dict.has_key(mynode)
	def copy(self):
		mygraph=digraph()
		for x in self.dict.keys():
			mygraph.dict[x]=self.dict[x][:]
			mygraph.okeys=self.okeys[:]
		return mygraph
def elog_process(cpv, mysettings):
def elog_process(cpv, mysettings):
	mylogfiles = listdir(mysettings["T"]+"/logging/")
	mylogfiles = listdir(mysettings["T"]+"/logging/")
 Lines 3293-3299    Link Here 
				return 0
				return 0
		return 1
		return 1
def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None, return_all_deps=False):
	"""Takes an unreduced and reduced deplist and removes satisfied dependencies.
	"""Takes an unreduced and reduced deplist and removes satisfied dependencies.
	Returned deplist contains steps that must be taken to satisfy dependencies."""
	Returned deplist contains steps that must be taken to satisfy dependencies."""
	if trees is None:
	if trees is None:
 Lines 3308-3315    Link Here 
		for (dep, satisfied) in zip(unreduced, reduced):
		for (dep, satisfied) in zip(unreduced, reduced):
			if isinstance(dep, list):
			if isinstance(dep, list):
				unresolved += dep_zapdeps(dep, satisfied, myroot,
				unresolved += dep_zapdeps(dep, satisfied, myroot,
					use_binaries=use_binaries, trees=trees)
					use_binaries=use_binaries, trees=trees, return_all_deps=return_all_deps)
			elif not satisfied:
			elif not satisfied or return_all_deps:
				unresolved.append(dep)
				unresolved.append(dep)
		return unresolved
		return unresolved
 Lines 3413-3419    Link Here 
		mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix
		mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None,
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None,
	use_cache=1, use_binaries=0, myroot="/", trees=None):
	use_cache=1, use_binaries=0, myroot="/", trees=None, return_all_deps=False):
	"""Takes a depend string and parses the condition."""
	"""Takes a depend string and parses the condition."""
	#check_config_instance(mysettings)
	#check_config_instance(mysettings)
 Lines 3478-3500    Link Here 
	writemsg("\n\n\n", 1)
	writemsg("\n\n\n", 1)
	writemsg("mysplit:  %s\n" % (mysplit), 1)
	writemsg("mysplit:  %s\n" % (mysplit), 1)
	writemsg("mysplit2: %s\n" % (mysplit2), 1)
	writemsg("mysplit2: %s\n" % (mysplit2), 1)
	myeval=dep_eval(mysplit2)
	writemsg("myeval:   %s\n" % (myeval), 1)
	if myeval:
	myzaps = dep_zapdeps(mysplit, mysplit2, myroot,
		return [1,[]]
		use_binaries=use_binaries, trees=trees, return_all_deps=return_all_deps)
	else:
	mylist = flatten(myzaps)
		myzaps = dep_zapdeps(mysplit, mysplit2, myroot,
	writemsg("myzaps:   %s\n" % (myzaps), 1)
			use_binaries=use_binaries, trees=trees)
	writemsg("mylist:   %s\n" % (mylist), 1)
		mylist = flatten(myzaps)
	#remove duplicates
		writemsg("myzaps:   %s\n" % (myzaps), 1)
	mydict={}
		writemsg("mylist:   %s\n" % (mylist), 1)
	for x in mylist:
		#remove duplicates
		mydict[x]=1
		mydict={}
	writemsg("mydict:   %s\n" % (mydict), 1)
		for x in mylist:
	return [1,mydict.keys()]
			mydict[x]=1
		writemsg("mydict:   %s\n" % (mydict), 1)
		return [1,mydict.keys()]
def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1):
def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1):
	"Reduces the deplist to ones and zeros"
	"Reduces the deplist to ones and zeros"