--- pym/portage.py.orig 2006-09-17 15:28:28.000000000 +0000 +++ pym/portage.py 2006-09-17 16:00:26.000000000 +0000 @@ -461,6 +461,16 @@ 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)" @@ -3375,7 +3385,7 @@ return 0 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. Returned deplist contains steps that must be taken to satisfy dependencies.""" if trees is None: @@ -3390,8 +3400,8 @@ for (dep, satisfied) in zip(unreduced, reduced): if isinstance(dep, list): unresolved += dep_zapdeps(dep, satisfied, myroot, - use_binaries=use_binaries, trees=trees) - elif not satisfied: + use_binaries=use_binaries, trees=trees, return_all_deps=return_all_deps) + elif not satisfied or return_all_deps: unresolved.append(dep) return unresolved @@ -3495,7 +3505,7 @@ mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix 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.""" #check_config_instance(mysettings) @@ -3557,23 +3567,18 @@ writemsg("\n\n\n", 1) writemsg("mysplit: %s\n" % (mysplit), 1) writemsg("mysplit2: %s\n" % (mysplit2), 1) - myeval=dep_eval(mysplit2) - writemsg("myeval: %s\n" % (myeval), 1) - if myeval: - return [1,[]] - else: - myzaps = dep_zapdeps(mysplit, mysplit2, myroot, - use_binaries=use_binaries, trees=trees) - mylist = flatten(myzaps) - writemsg("myzaps: %s\n" % (myzaps), 1) - writemsg("mylist: %s\n" % (mylist), 1) - #remove duplicates - mydict={} - for x in mylist: - mydict[x]=1 - writemsg("mydict: %s\n" % (mydict), 1) - return [1,mydict.keys()] + myzaps = dep_zapdeps(mysplit, mysplit2, myroot, + use_binaries=use_binaries, trees=trees, return_all_deps=return_all_deps) + mylist = flatten(myzaps) + writemsg("myzaps: %s\n" % (myzaps), 1) + writemsg("mylist: %s\n" % (mylist), 1) + #remove duplicates + mydict={} + for x in mylist: + mydict[x]=1 + writemsg("mydict: %s\n" % (mydict), 1) + return [1,mydict.keys()] def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1): "Reduces the deplist to ones and zeros" --- bin/emerge.orig 2006-09-17 15:15:44.000000000 +0000 +++ bin/emerge 2006-09-17 16:43:05.000000000 +0000 @@ -352,7 +352,7 @@ # recurse: go into the dependencies # deep: go into the dependencies of already merged packages # empty: pretend nothing is merged - myparams=["self","recurse"] + myparams=["self","recurse","selective"] add=[] sub=[] if "--update" in myopts or myaction in ("system", "world"): @@ -679,7 +679,7 @@ "--getbinpkg" 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,force_merge=False): """ Fills the digraph with nodes comprised of packages to merge. mybigkey is the package spec of the package to merge. @@ -697,10 +697,11 @@ if addme and jbigkey != myparent: # Refuse to make a node depend on itself so that the we don't # 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 jbigkey = " ".join(mybigkey) + " nomerge" if self.digraph.hasnode(jbigkey): + self.digraph.addnode(jbigkey, myparent, hard_dep=hard_dep) return 1 self.spinner.update() @@ -723,7 +724,7 @@ if self.mydbapi[parent_root].match(mykey) or \ self.trees[parent_root]["vartree"].dbapi.match(mykey): mybigkey.append(myparent.split()[2]) - self.digraph.addnode(" ".join(mybigkey), myparent) + self.digraph.addnode(" ".join(mybigkey), myparent, hard_dep) return 1 else: mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi @@ -743,10 +744,10 @@ is always included and if in 'selective' mode package is already installed we skip merging it.""" if "self" not in self.myparams or \ - ("selective" in self.myparams and \ + ("selective" in self.myparams and not force_merge and \ vardbapi.cpv_exists(mykey)): merging=0 - elif "selective" in self.myparams and vardbapi.cpv_exists(mykey): + elif "selective" in self.myparams and not force_merge and vardbapi.cpv_exists(mykey): merging=0 """ If we aren't merging, perform the --newuse check. @@ -782,7 +783,7 @@ """ 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 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. We want to go deeper on a few occasions: @@ -821,20 +822,22 @@ try: if myroot=="/": 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 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): + if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse,soft_deps=True): return 0 if edepend.has_key("PDEPEND") and edepend["PDEPEND"]: # Post Depend -- Add to the list without a parent, as it depends # 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 except ValueError, e: pkgs = e.args[0] @@ -883,7 +886,7 @@ print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n") sys.exit(1) if not self.create(["binary", myroot, mykey], - None, "--onlydeps" not in self.myopts): + None, "--onlydeps" not in self.myopts, force_merge=("--noreplace" not in self.myopts)): return (0,myfavorites) elif not "--oneshot" in self.myopts: myfavorites.append(mykey) @@ -906,7 +909,7 @@ raise portage_exception.PackageNotFound( "%s is not in a valid portage tree hierarchy or does not exist" % x) if not self.create(["ebuild", myroot, mykey], - None, "--onlydeps" not in self.myopts): + None, "--onlydeps" not in self.myopts, force_merge==("--noreplace" not in self.myopts)): return (0,myfavorites) elif not "--oneshot" in self.myopts: myfavorites.append(mykey) @@ -940,7 +943,7 @@ sys.stderr.flush() try: - self.mysd = self.select_dep(myroot, mykey, arg=x) + self.mysd = self.select_dep(myroot, mykey, arg=x, force_merge=("--noreplace" not in self.myopts)) except portage_exception.MissingSignature, e: 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") @@ -969,7 +972,7 @@ missing=0 if "--usepkgonly" in self.myopts: - for x in self.digraph.dict.keys(): + for x in self.digraph.all_nodes(): xs=string.split(x," ") if (xs[0] != "binary") and (xs[3]=="merge"): if missing == 0: @@ -993,7 +996,7 @@ if curslot == myslot: 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,force_merge=False): """ Given a depstring, create the depgraph such that all dependencies are satisfied. myroot = $ROOT from environment, where {R,P}DEPENDs are merged to. myparent = the node whose depstring is being passed in @@ -1006,6 +1009,7 @@ portdb = self.trees[myroot]["porttree"].dbapi bindb = self.trees[myroot]["bintree"].dbapi + vardb = self.trees[myroot]["vartree"].dbapi pkgsettings = self.pkgsettings[myroot] if "--debug" in self.myopts: @@ -1020,7 +1024,7 @@ mycheck = portage.dep_check(depstring, self.mydbapi[myroot], pkgsettings, myuse=myuse, use_binaries=("--usepkgonly" in self.myopts), - myroot=myroot, trees=self.trees) + myroot=myroot, trees=self.trees, return_all_deps=True) if not mycheck[0]: mymerge=[] @@ -1056,9 +1060,6 @@ self.pkgsettings[p_root].setinst(p_key, self.trees[p_root][self.pkg_tree_map[p_type]].dbapi) - if not mymerge: - return 1 - if "--debug" in self.myopts: print "Candidates:",mymerge for x in mymerge: @@ -1178,15 +1179,16 @@ if myparent: #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, - myuse=selected_pkg[-1]): + myuse=selected_pkg[-1], hard_dep=hard_dep): return 0 else: #if mysource is not set, then we are a command-line dependency and should not be added #if --onlydeps is specified. if not self.create(selected_pkg[0:3], myparent, addme=("--onlydeps" not in self.myopts), - myuse=selected_pkg[-1]): + myuse=selected_pkg[-1], force_merge=force_merge): return 0 if "--debug" in self.myopts: @@ -1205,13 +1207,16 @@ while (not mygraph.empty()): mycurkey=mygraph.firstzero() if not mycurkey: - print "!!! Error: circular dependencies:" - print - for x in mygraph.allnodes(): - for y in mygraph.parent_nodes(x): - print y,"depends on",x - print - sys.exit(1) + installables = mygraph.leaf_nodes(include_soft_deps=True) + if not installables: + print "!!! Error: circular dependencies:" + print + for x in mygraph.allnodes(): + for y in mygraph.parent_nodes(x): + print y,"depends on",x + print + sys.exit(1) + mycurkey = installables[0] splitski=string.split(mycurkey) #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