From: Fabian Groffen Date: Sun, 10 Dec 2006 11:16:12 +0000 (-0000) Subject: Merged from trunk 5226:5238 (+ one added modification in bin/repoman) X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=f43a39ee864d21906947e9edd8444e64c0a70428;p=portage.git Merged from trunk 5226:5238 (+ one added modification in bin/repoman) Indicate test failure with an exit code. Remove all traces of FEATURES=cvs since code for that feature no longer exists (apparently since portage-2.1). + Remove traces of FEATURES=svn for the same reason Clean up vardbapi.aux_get(). Remove locking from dbapi.aux_update() implementations so that the caller can handle locking instead. Go ahead and populate depgraph.mydbapi even when --emptytree is enabled since it doesn't matter anymore (dep_check now returns all deps anyway). Move the reset of the per-root initializations into the loop. Remove unused depgraph.match() method. Use tuples for digraph nodes in order to avoid lots of pointless join and split calls. Split some global updates functions out of depgraph and use them for depclean when necessary. Fix broken SLOT update logic in fakedbapi.cpv_inject(). adjust QA_* variable names for complex values of like x86-fbsd svn path=/main/branches/prefix/; revision=5257 --- diff --git a/bin/emerge b/bin/emerge index c8ba4d987..fb555d271 100755 --- a/bin/emerge +++ b/bin/emerge @@ -48,7 +48,7 @@ from portage_data import secpass if not hasattr(__builtins__, "set"): from sets import Set as set -from itertools import izip +from itertools import chain, izip class stdout_spinner(object): scroll_msgs = [ @@ -734,6 +734,27 @@ class FakeVartree(portage.vartree): self.settings.treeVirtuals = portage_util.map_dictlist_vals( portage.getCPFromCPV, self.get_all_provides()) +def grab_global_updates(portdir): + from portage_update import grab_updates, parse_updates + updpath = os.path.join(portdir, "profiles", "updates") + try: + rawupdates = grab_updates(updpath) + except portage_exception.DirectoryNotFound: + rawupdates = [] + upd_commands = [] + for mykey, mystat, mycontent in rawupdates: + commands, errors = parse_updates(mycontent) + upd_commands.extend(commands) + return upd_commands + +def perform_global_updates(mycpv, mydb, mycommands): + from portage_update import update_dbentries + aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"] + aux_dict = dict(izip(aux_keys, mydb.aux_get(mycpv, aux_keys))) + updates = update_dbentries(mycommands, aux_dict) + if updates: + mydb.aux_update(mycpv, updates) + class depgraph: pkg_tree_map = { @@ -752,6 +773,8 @@ class depgraph: self.spinner = spinner self.pkgsettings = {} self.pkg_node_map = {} + self.mydbapi = {} + self.useFlags = {} self.trees = {} for myroot in trees: self.trees[myroot] = {} @@ -762,40 +785,26 @@ class depgraph: self.pkgsettings[myroot] = portage.config( clone=self.trees[myroot]["vartree"].settings) self.pkg_node_map[myroot] = {} + vardb = self.trees[myroot]["vartree"].dbapi + # This fakedbapi instance will model the state that the vdb will + # have after new packages have been installed. + fakedb = portage.fakedbapi(settings=self.pkgsettings[myroot]) + self.mydbapi[myroot] = fakedb + for pkg in vardb.cpv_all(): + myslot = vardb.aux_get(pkg, ["SLOT"])[0] + fakedb.cpv_inject(pkg, metadata={"SLOT":myslot}) + del vardb, fakedb + self.useFlags[myroot] = {} + if "--usepkg" in self.myopts: + self.trees[myroot]["bintree"].populate( + "--getbinpkg" in self.myopts, + "--getbinpkgonly" in self.myopts) del trees - self.useFlags = {} - self.useFlags[self.target_root] = {} - if self.target_root != "/": - self.useFlags["/"] = {} self.missingbins=[] self.digraph=portage.digraph() self.orderedkeys=[] self.outdatedpackages=[] - self.mydbapi={} - self.mydbapi["/"] = portage.fakedbapi(settings=settings) - vardb = self.trees["/"]["vartree"].dbapi - fakedb = self.mydbapi["/"] - if "empty" not in self.myparams or self.target_root != "/": - for pkg in vardb.cpv_all(): - myslot = vardb.aux_get(pkg, ["SLOT"])[0] - fakedb.cpv_inject(pkg, metadata={"SLOT":myslot}) - if self.target_root != "/": - self.mydbapi[self.target_root] = \ - portage.fakedbapi(settings=settings) - vardb = self.trees[self.target_root]["vartree"].dbapi - fakedb = self.mydbapi[self.target_root] - if "empty" not in self.myparams: - for pkg in vardb.cpv_all(): - myslot = vardb.aux_get(pkg, ["SLOT"])[0] - fakedb.cpv_inject(pkg, metadata={"SLOT":myslot}) - if "--usepkg" in self.myopts: - self.trees["/"]["bintree"].populate( - "--getbinpkg" in self.myopts, "--getbinpkgonly" in self.myopts) - if self.target_root != "/": - self.trees[self.target_root]["bintree"].populate( - "--getbinpkg" in self.myopts, - "--getbinpkgonly" in self.myopts) self.args_keys = [] self.global_updates = {} self.blocker_digraph = digraph() @@ -816,7 +825,7 @@ class depgraph: #IUSE-aware emerge -> USE DEP aware depgraph #"no downgrade" emerge """ - jbigkey = " ".join(mybigkey) + " merge" + jbigkey = tuple(chain(mybigkey, ["merge"])) mytype, myroot, mykey = mybigkey if self.digraph.hasnode(jbigkey): if addme and jbigkey != myparent: @@ -824,17 +833,17 @@ class depgraph: # don't create a bogus circular dependency in self.altlist(). self.pkg_node_map[myroot][mykey] = jbigkey if rev_dep and myparent: - ptype, proot, pkey, pstatus = myparent.split() + ptype, proot, pkey, pstatus = myparent self.pkg_node_map[proot][pkey] = myparent self.digraph.addnode(myparent, jbigkey, priority=priority) else: self.digraph.addnode(jbigkey, myparent, priority=priority) return 1 - jbigkey = " ".join(mybigkey) + " nomerge" + jbigkey = tuple(chain(mybigkey, ["nomerge"])) if self.digraph.hasnode(jbigkey): self.pkg_node_map[myroot][mykey] = jbigkey if rev_dep and myparent: - ptype, proot, pkey, pstatus = myparent.split() + ptype, proot, pkey, pstatus = myparent self.pkg_node_map[proot][pkey] = myparent self.digraph.addnode(myparent, jbigkey, priority=priority) else: @@ -844,9 +853,9 @@ class depgraph: self.spinner.update() if mytype == "blocks": if addme and "--buildpkgonly" not in self.myopts and myparent: - mybigkey[1] = myparent.split()[1] + mybigkey[1] = myparent[1] self.blocker_parents.setdefault( - " ".join(mybigkey), set()).add(myparent) + tuple(mybigkey), set()).add(myparent) return 1 if not arg and myroot == self.target_root: arg = portage.best_match_to_list(mykey, self.args_keys) @@ -909,10 +918,10 @@ class depgraph: """ 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. """ - jbigkey = " ".join(mybigkey) + jbigkey = tuple(mybigkey) self.pkg_node_map[myroot][mykey] = jbigkey if rev_dep and myparent: - ptype, proot, pkey, pstatus = myparent.split() + ptype, proot, pkey, pstatus = myparent self.pkg_node_map[proot][pkey] = myparent self.digraph.addnode(myparent, jbigkey, priority=priority) @@ -959,7 +968,7 @@ class depgraph: """ We have retrieve the dependency information, now we need to recursively process them. DEPEND gets processed for root = "/", {R,P}DEPEND in myroot. """ - mp=string.join(mybigkey) + mp = tuple(mybigkey) try: if not self.select_dep("/", edepend["DEPEND"], myparent=mp, @@ -1175,8 +1184,7 @@ class depgraph: missing=0 if "--usepkgonly" in self.myopts: - for x in self.digraph.all_nodes(): - xs = x.split() + for xs in self.digraph.all_nodes(): if len(xs) >= 4 and xs[0] != "binary" and xs[3] == "merge": if missing == 0: print @@ -1241,7 +1249,7 @@ class depgraph: # virtuals, which are preferenced in dep_zapdeps by looking only at # the depstring, vdb, and available packages. - p_type, p_root, p_key, p_status = myparent.split() + p_type, p_root, p_key, p_status = myparent if p_status == "merge": # Update old-style virtuals if this package provides any. # These are needed for dep_virtual calls inside dep_check. @@ -1345,30 +1353,11 @@ class depgraph: This is done on the fly for single packages only when necessary, since it can be time consuming to run this on all installed packages.""" - from portage_update import grab_updates, \ - parse_updates, update_dbentries if myroot not in self.global_updates: - updpath = os.path.join( - pkgsettings["PORTDIR"], "profiles", "updates") - try: - rawupdates = grab_updates(updpath) - except portage_exception.DirectoryNotFound: - rawupdates = [] - upd_commands = [] - for mykey, mystat, mycontent in rawupdates: - commands, errors = parse_updates(mycontent) - upd_commands.extend(commands) - del updpath, rawupdates - self.global_updates[myroot] = upd_commands - upd_commands = self.global_updates[myroot] - aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"] - aux_vals = vardb.aux_get(myeb_inst, aux_keys) - aux_dict = dict(izip(aux_keys, aux_vals)) - updates = update_dbentries(upd_commands, aux_dict) - if updates: - vardb.aux_update(myeb_inst, updates) - del binpkguseflags, myeb_inst, upd_commands, \ - aux_keys, aux_vals, aux_dict, updates + self.global_updates[myroot] = \ + grab_global_updates(pkgsettings["PORTDIR"]) + perform_global_updates( + myeb_inst, vardb, self.global_updates[myroot]) if not matched_packages: if raise_on_missing: @@ -1378,7 +1367,9 @@ class depgraph: else: xinfo='"'+arg+'"' if myparent: - xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')' + xfrom = '(dependency required by '+ \ + green('"%s"' % myparent[2]) + \ + red(' [%s]' % myparent[0]) + ')' alleb = portdb.xmatch("match-all", x) if alleb: if "--usepkgonly" not in self.myopts: @@ -1448,7 +1439,7 @@ class depgraph: installed simultaneously.""" for blocker in self.blocker_parents.keys(): - mytype, myroot, mydep = blocker.split() + mytype, myroot, mydep = blocker vardb = self.trees[myroot]["vartree"].dbapi blocked_pkgs = vardb.match(mydep) blocked_after_update = self.mydbapi[myroot].match(mydep) @@ -1478,7 +1469,7 @@ class depgraph: continue for parent in list(self.blocker_parents[blocker]): - ptype, proot, pcpv, pstatus = parent.split() + ptype, proot, pcpv, pstatus = parent pdbapi = self.trees[proot][self.pkg_tree_map[ptype]].dbapi pslot = pdbapi.aux_get(pcpv, ["SLOT"])[0] pslot_atom = "%s:%s" % (portage.dep_getkey(pcpv), pslot) @@ -1611,7 +1602,7 @@ class depgraph: sys.exit(1) for node in selected_nodes: - retlist.append(node.split()) + retlist.append(list(node)) mygraph.remove(node) if not reversed and not circular_blocks and myblockers.contains(node): """This node may have invalidated one or more blockers.""" @@ -1629,7 +1620,7 @@ class depgraph: """ Add any unresolved blocks so that they can be displayed.""" for blocker in self.blocker_parents: - retlist.append(blocker.split()) + retlist.append(list(blocker)) self._altlist_cache[reversed] = retlist[:] return retlist @@ -1733,38 +1724,6 @@ class depgraph: return 1 - def match(self, mydep, myroot=None, mykey=None): - # support mutual exclusive deps - if myroot is None: - myroot = self.target_root - mydep2=mydep - if mydep2[0]=="!": - mydep2=mydep[1:] - - if mydep[0]=="!": - #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example) - myk="blocks "+myroot+" "+mydep2 - else: - myeb = self.trees[myroot]["porttree"].dep_bestmatch(mydep2) - if not myeb: - if not mykey: - print "\n!!! Error: couldn't find match for",mydep - else: - print "\n!!! Error: couldn't find match for",mydep,"in",mykey - print - sys.exit(1) - - if "--usepkg" in self.myopts: - mypk = self.trees[myroot]["bintree"].dep_bestmatch(mydep) - if myeb==mypk: - myk = " ".join(("binary", myroot, mypk)) - else: - myk = " ".join(("ebuild", myroot, myeb)) - else: - myk="ebuild "+myroot+" "+myeb - - return myk - def display(self,mylist,verbosity=None): if verbosity is None: verbosity = ("--quiet" in self.myopts and 1 or \ @@ -1853,7 +1812,7 @@ class depgraph: for x in mylist: if "blocks" == x[0]: continue - graph_key = " ".join(x) + graph_key = tuple(x) if "--tree" in self.myopts: depth = len(tree_nodes) while depth and graph_key not in \ @@ -1867,13 +1826,13 @@ class depgraph: for i in xrange(len(mylist)-1,-1,-1): if "blocks" == mylist[i][0]: continue - graph_key = " ".join(mylist[i]) + graph_key = tuple(mylist[i]) if mylist[i][-1] != "nomerge": last_merge_depth = node_depth[graph_key] continue if node_depth[graph_key] >= last_merge_depth or \ i < len(mylist) - 1 and \ - node_depth[graph_key] >= node_depth[" ".join(mylist[i+1])]: + node_depth[graph_key] >= node_depth[tuple(mylist[i+1])]: del mylist[i] del node_depth[graph_key] del tree_nodes @@ -1900,8 +1859,8 @@ class depgraph: resolved = portage.key_expand( pkg_key, mydb=vardb, settings=pkgsettings) print "["+x[0]+" "+addl+"]",red(resolved), - block_parents = self.blocker_parents[" ".join(x)] - block_parents = [pnode.split()[2] for pnode in block_parents] + block_parents = self.blocker_parents[tuple(x)] + block_parents = [pnode[2] for pnode in block_parents] block_parents = ", ".join(block_parents) if resolved!=x[2]: print bad("(\"%s\" is blocking %s)") % \ @@ -2112,7 +2071,7 @@ class depgraph: oldlp=mywidth-30 newlp=oldlp-30 - indent = " " * node_depth[" ".join(x)] + indent = " " * node_depth[tuple(x)] if myoldbest: myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2] @@ -3971,14 +3930,22 @@ def action_depclean(settings, trees, ldpath_mtimes, fake_vardb = portage.fakedbapi(settings=settings) fakedb_auxkeys = aux_keys[:] fakedb_auxkeys.append("SLOT") + global_updates = None for cpv in myvarlist: try: # Prefer live ebuild metadata when available. aux_vals = portdb.aux_get(cpv, fakedb_auxkeys) + live_ebuild = True except KeyError: aux_vals = vardb.aux_get(cpv, fakedb_auxkeys) + live_ebuild = False fake_vardb.cpv_inject( cpv, metadata=dict(izip(fakedb_auxkeys, aux_vals))) + if not live_ebuild: + if global_updates is None: + global_updates = grab_global_updates(settings["PORTDIR"]) + perform_global_updates(cpv, fake_vardb, global_updates) + # HACK: Ensure that installed packages are preferenced by dep_check(). trees[settings["ROOT"]]["porttree"].dbapi = fake_vardb diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index 497952149..0378ee504 100644 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -89,7 +89,7 @@ install_qa_check() { # binary-only and upstream isn't cooperating (nvidia-glx) ... we # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ... # the former overrides the latter ... regexes allowed ! :) - qa_var="QA_TEXTRELS_${ARCH}" + qa_var="QA_TEXTRELS_${ARCH/-/_}" [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var} [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS="" export QA_TEXTRELS @@ -126,10 +126,10 @@ install_qa_check() { # QA_EXECSTACK ... the former overrides the latter ... # regexes allowed ! :) - qa_var="QA_EXECSTACK_${ARCH}" + qa_var="QA_EXECSTACK_${ARCH/-/_}" [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var} [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK="" - qa_var="QA_WX_LOAD_${ARCH}" + qa_var="QA_WX_LOAD_${ARCH/-/_}" [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var} [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD="" export QA_EXECSTACK QA_WX_LOAD diff --git a/bin/repoman b/bin/repoman index 7f58346a0..bbb5a4ff6 100755 --- a/bin/repoman +++ b/bin/repoman @@ -400,13 +400,6 @@ if mymode == "commit": isCvs=False myreporoot=None if os.path.isdir("CVS"): - if "cvs" not in repoman_settings.features: - print - print - print red('!!! You do not have ')+bold('FEATURES="cvs" ')+red("enabled...") - print red("!!! ")+bold("Adding \"cvs\" to FEATURES") - print - os.environ["FEATURES"]=repoman_settings["FEATURES"]+" cvs" isCvs = True try: @@ -457,14 +450,6 @@ if os.path.isdir("CVS"): isSvn=False myreporoot=None if os.path.isdir(".svn"): - if "svn" not in repoman_settings.features: - print - print - print red('!!! You do not have ')+bold('FEATURES="svn" ')+red("enabled...") - print red("!!! ")+bold("Adding \"svn\" to FEATURES") - print - os.environ["FEATURES"]=repoman_settings["FEATURES"]+" svn" - try: isSvn=True myrepoinfo = os.popen("svn info").readlines() diff --git a/man/make.conf.5 b/man/make.conf.5 index d8c0732d2..affc47a7d 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -144,10 +144,6 @@ A QA\-feature to ensure that a package doesn't overwrite files it doesn't own. The \fICOLLISION_IGNORE\fR variable can be used to selectively disable this feature. .TP -.B cvs -A feature for developers that causes portage to enable all USE flags in SRC_URI -when creating digests. -.TP .B digest Autogenerate digests for packages when running the \fBemerge\fR(1) command. If the \fIassume-digests\fR feature is also enabled then existing SRC_URI digests diff --git a/pym/portage.py b/pym/portage.py index 00cde15ac..46a8d031f 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -4412,9 +4412,12 @@ class fakedbapi(dbapi): if myslot and mycp in self.cpdict: # If necessary, remove another package in the same SLOT. for cpv in self.cpdict[mycp]: - if mycpv != cpv and myslot == self.cpvdict[cpv]: - self.cpv_remove(cpv) - break + if mycpv != cpv: + other_metadata = self.cpvdict[cpv] + if other_metadata: + if myslot == other_metadata.get("SLOT", None): + self.cpv_remove(cpv) + break if mycp not in self.cpdict: self.cpdict[mycp] = [] if not mycpv in self.cpdict[mycp]: @@ -4497,16 +4500,12 @@ class bindbapi(fakedbapi): if not self.bintree.populated: self.bintree.populate() tbz2path = self.bintree.getname(cpv) - mylock = portage_locks.lockfile(tbz2path, wantnewlockfile=1) - try: - if not os.path.exists(tbz2path): - raise KeyError(cpv) - mytbz2 = xpak.tbz2(tbz2path) - mydata = mytbz2.get_data() - mydata.update(values) - mytbz2.recompose_mem(xpak.xpak_mem(mydata)) - finally: - portage_locks.unlockfile(mylock) + if not os.path.exists(tbz2path): + raise KeyError(cpv) + mytbz2 = xpak.tbz2(tbz2path) + mydata = mytbz2.get_data() + mydata.update(values) + mytbz2.recompose_mem(xpak.xpak_mem(mydata)) def cp_list(self, *pargs, **kwargs): if not self.bintree.populated: @@ -4798,41 +4797,34 @@ class vardbapi(dbapi): return self.root+VDB_PATH+"/"+str(mycpv)+"/"+mycpv.split("/")[1]+".ebuild" def aux_get(self, mycpv, wants): - global auxdbkeys + mydir = os.path.join(self.root, VDB_PATH, mycpv) + if not os.path.isdir(mydir): + raise KeyError(mycpv) results = [] for x in wants: - myfn = self.root+VDB_PATH+"/"+str(mycpv)+"/"+str(x) try: - myf = open(myfn, "r") - myd = myf.read() - myf.close() - myd = re.sub("[\n\r\t]+"," ",myd) - myd = re.sub(" +"," ",myd) - myd = string.strip(myd) - except (IOError, OSError): + myf = open(os.path.join(mydir, x), "r") + try: + myd = myf.read() + finally: + myf.close() + myd = " ".join(myd.split()) + except IOError: myd = "" - results.append(myd) - if "EAPI" in wants: - idx = wants.index("EAPI") - if not results[idx]: - results[idx] = "0" + if x == "EAPI" and not myd: + results.append("0") + else: + results.append(myd) return results def aux_update(self, cpv, values): cat, pkg = cpv.split("/") mylink = dblink(cat, pkg, self.root, self.settings, - treetype="vartree", vartree=self.vartree) - try: - mylink.lockdb() - except portage_exception.DirectoryNotFound: + treetype="vartree", vartree=self.vartree) + if not mylink.exists(): raise KeyError(cpv) - try: - if not mylink.exists(): - raise KeyError(cpv) - for k, v in values.iteritems(): - mylink.setfile(k, v) - finally: - mylink.unlockdb() + for k, v in values.iteritems(): + mylink.setfile(k, v) def counter_tick(self,myroot,mycpv=None): return self.counter_tick_core(myroot,incrementing=1,mycpv=mycpv) diff --git a/tests/__init__.py b/tests/__init__.py index 1a235ff26..6acf0c99f 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -18,4 +18,4 @@ def main(): except ImportError: pass - unittest.TextTestRunner(verbosity=2).run(suite) + return unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/runTests b/tests/runTests index 74b853f09..fed58f75d 100755 --- a/tests/runTests +++ b/tests/runTests @@ -16,5 +16,7 @@ sys.path.insert(0,'../pym') sys.path.insert(0, osp.dirname(osp.dirname(osp.abspath(__file__)))) import tests - -tests.main() +if __name__ == "__main__": + result = tests.main() + if result.failures: + sys.exit(1)