View | Details | Raw Unified
Collapse All | Expand All

(-) portage.orig/bin/emerge (-25 / +40 lines)
 Lines 352-358    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"):
 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,hard_dep=True,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, hard_dep=hard_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, hard_dep=hard_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, hard_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,hard_dep=hard_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 821-840    Link Here 
		try:
		try:
			if myroot=="/":
			if myroot=="/":
				mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
				mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
				if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
				if not self.select_dep("/",edepend["DEPEND"],myparent=mp,myuse=myuse):
					return 0
				if not self.select_dep("/",edepend["RDEPEND"],myparent=mp,myuse=myuse,soft_deps=True):
					return 0
					return 0
			else:
			else:
				mydep["/"]=edepend["DEPEND"]
				mydep["/"]=edepend["DEPEND"]
				mydep[myroot]=edepend["RDEPEND"]
				mydep[myroot]=edepend["RDEPEND"]
				if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
				if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
					return 0
					return 0
				if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
				if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse,soft_deps=True):
					return 0
					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
				hard_dep = not soft_deps and len(vardb.match(x)) == 0
				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], hard_dep=hard_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(include_soft_deps=False)
				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 / +141 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 : hard_dep } , { parent : hard_dep } ) }
		self.nodes = {}
	def addnode(self,mykey,myparent):
		self.order = []
		if not self.dict.has_key(mykey):
			self.okeys.append(mykey)
	def add(self, node, parent, hard_dep=True):
			if myparent is None:
		"""Adds the specified node with the specified parent. If the dep
				self.dict[mykey]=[0,[]]
		is a hard-dep and the node already has a relationship to the parent
			else:
		the relationship is ensured to be hard."""
				self.dict[mykey]=[0,[myparent]]
		
				self.dict[myparent][0]=self.dict[myparent][0]+1
		if node not in self.nodes:
			self.nodes[node] = ({}, {})
			self.order.append(node)
		
		if not parent:
			return
			return
		if myparent and (not myparent in self.dict[mykey][1]):
		
			self.dict[mykey][1].append(myparent)
		if parent not in self.nodes:
			self.dict[myparent][0]=self.dict[myparent][0]+1
			self.nodes[parent] = ({}, {})
			self.order.append(parent)
		
		if parent in self.nodes[node][1]:
			if hard_dep:
				self.nodes[node][1][parent] = True
		else:
			self.nodes[node][1][parent] = hard_dep
		
		if node in self.nodes[parent][0]:
			if hard_dep:
				self.nodes[parent][0][node] = True
		else:
			self.nodes[parent][0][node] = hard_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 delnode(self,mykey):
	def contains(self, node):
		if not self.dict.has_key(mykey):
		"""Checks if the digraph contains mynode"""
			return
		return node in self.nodes
		for x in self.dict[mykey][1]:
			self.dict[x][0]=self.dict[x][0]-1
	def all_nodes(self):
		del self.dict[mykey]
		return self.order[:]
		while 1:
			try:
	def child_nodes(self, node):
				self.okeys.remove(mykey)
		return self.nodes[node][0].keys()
			except ValueError:
	
				break
	def parent_nodes(self, node):
		return self.nodes[node][1].keys()
	def allnodes(self):
	def leaf_nodes(self, include_soft_deps=False):
		"returns all nodes in the dictionary"
		leaf_nodes = []
		return self.dict.keys()
		for node in self.order:
			is_leaf_node = True
			for child in self.nodes[node][0]:
				if include_soft_deps or 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
	delnode = remove
	allnodes = all_nodes
	allzeros = leaf_nodes
	hasnode = contains
	empty = is_empty
	copy = clone
	def firstzero(self):
	def firstzero(self):
		"returns first node with zero references, or NULL if no such node exists"
		leaf_nodes = self.leaf_nodes(include_soft_deps=True)
		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,"depends on"
			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"