From: Fabian Groffen Date: Sat, 22 Dec 2007 13:29:47 +0000 (-0000) Subject: Merged from trunk 9001:9029 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=6c31a19d8412d8f18ce0fc24cb8fcf32fb163f2e;p=portage.git Merged from trunk 9001:9029 | 9002 | Hardcode #!/bin/bash for consistency with other scripts. | | zmedico | | | 9004 | Bug #202566 - Move the 'global portage' statement to avoid | | zmedico | "SyntaxWarning: name 'portage' is assigned to before global | | | declaration" messages produced by earlier python-2.4. | | 9005 | Fix a reference to an undefined "mykey" variable. | | zmedico | | | 9006 | Slightly improved the masked package check inside | | zmedico | dep_zapdeps(). | | 9008 | Add "metadata" and "licenses" to _non_category_dirs. | | zmedico | | | 9010 | Use a regex to validate package directory names in | | zmedico | portdbapi.cp_list() and also simplify the catagory regex a | | | bit. | | 9012 | Use regex category validation in binarytree.populate(). | | zmedico | | | 9013 | Fix references to dbapi._category_re. | | zmedico | | | 9015 | Tweak profile validation and warning logic a bit. | | zmedico | | | 9016 | In portage.spawn(), make the default fd_pipes value get file | | zmedico | descriptors from sys.std{in,out,err} so that they can be | | | overridden. | | 9018 | In portage.process.spawn(), make the default fd_pipes value | | zmedico | get file descriptors from sys.std{in,out,err} so that they | | | can be overridden. | | 9020 | Fix xmatch "match-all" typo. | | zmedico | | | 9023 | Eliminate redundant "notadded" error filtering. | | zmedico | | | 9025 | Make the "test" flag that's enabled by FEATURES=test into an | | zmedico | implicit iuse member. | | 9027 | Implement emerge --search support for installed packages, so | | zmedico | it works even without a portage tree or binary packages. | | 9028 | Don't show "Size of files: 0 kB" in emerge --search output | | zmedico | for installed packages that have no available ebuild in the | | | tree. | | 9029 | Implement binary package visibility filtering for emerge | | zmedico | --search. | svn path=/main/branches/prefix/; revision=9041 --- diff --git a/bin/portageq b/bin/portageq index 756b1b2fd..eec63a504 100755 --- a/bin/portageq +++ b/bin/portageq @@ -435,6 +435,8 @@ def main(): sys.exit(os.EX_USAGE) os.environ["ROOT"] = sys.argv[2] + global portage + # First import the main portage module without legacy globals since it # is almost certain to succeed in that case. This provides access to # the portage.exception namespace which is needed for later exception @@ -444,7 +446,6 @@ def main(): import portage del os.environ["PORTAGE_LEGACY_GLOBALS"] try: - global portage try: reload(portage) except ImportError: diff --git a/bin/repoman b/bin/repoman index 83f494263..c934e876b 100755 --- a/bin/repoman +++ b/bin/repoman @@ -477,9 +477,6 @@ def last(full=False): for x in qacats: if not stats[x]: continue - if "notadded" in x and not isCvs: - stats[x] = 0 - continue dowarn = 1 if x not in qawarnings: dofail = 1 @@ -1279,7 +1276,7 @@ for x in scanlist: if os.stat(checkdir+"/"+y+".ebuild")[0] & 0x0248: stats["file.executable"] += 1 fails["file.executable"].append(x+"/"+y+".ebuild") - if y not in eadded: + if isCvs and y not in eadded: #ebuild not added to cvs stats["ebuild.notadded"]=stats["ebuild.notadded"]+1 fails["ebuild.notadded"].append(x+"/"+y+".ebuild") @@ -1710,9 +1707,6 @@ dofull = options.mode not in ("full", "lfull") for x in qacats: if not stats[x]: continue - if "notadded" in x and not isCvs and not isSvn: - stats[x] = 0 - continue dowarn = 1 if x not in qawarnings: dofail = 1 diff --git a/bin/sed b/bin/sed index fbff4ffdf..fb0148023 100755 --- a/bin/sed +++ b/bin/sed @@ -1,5 +1,4 @@ #!@BASH@ -# Copyright 2006 Gentoo Foundation # Copyright 2007 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 1a238775d..b53a0764f 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -409,17 +409,28 @@ class search(object): self.verbose = verbose self.searchdesc = searchdesc self.setconfig = root_config.setconfig - _portdb = root_config.trees["porttree"].dbapi - if _portdb._have_root_eclass_dir: - self.portdb = _portdb - else: - def fake_portdb(): - pass - self.portdb = fake_portdb - self._dbs = [root_config.trees["bintree"].dbapi] - for attrib in ("aux_get", "cp_all", - "xmatch", "findname", "getfetchlist"): - setattr(fake_portdb, attrib, getattr(self, "_"+attrib)) + + def fake_portdb(): + pass + self.portdb = fake_portdb + for attrib in ("aux_get", "cp_all", + "xmatch", "findname", "getfetchlist"): + setattr(fake_portdb, attrib, getattr(self, "_"+attrib)) + + self._dbs = [] + + portdb = root_config.trees["porttree"].dbapi + bindb = root_config.trees["bintree"].dbapi + vardb = root_config.trees["vartree"].dbapi + + if portdb._have_root_eclass_dir: + self._dbs.append(portdb) + + if bindb.cp_all(): + self._dbs.append(bindb) + + self._dbs.append(vardb) + self._portdb = portdb def _cp_all(self): cp_all = set() @@ -437,6 +448,12 @@ class search(object): def _findname(self, *args, **kwargs): for db in self._dbs: + if db is not self._portdb: + # We don't want findname to return anything + # unless it's an ebuild in a portage tree. + # Otherwise, it's already built and we don't + # care about it. + continue func = getattr(db, "findname", None) if func: value = func(*args, **kwargs) @@ -451,30 +468,73 @@ class search(object): value = func(*args, **kwargs) if value: return value - return None + return [], [] + + def _visible(self, db, cpv, metadata): + installed = db is self.vartree.dbapi + built = installed or db is not self._portdb + return visible(self.settings, cpv, metadata, + built=built, installed=installed) def _xmatch(self, level, atom): - if level.startswith("bestmatch-"): - matches = [] + """ + This method does not expand old-style virtuals because it + is restricted to returning matches for a single ${CATEGORY}/${PN} + and old-style virual matches unreliable for that when querying + multiple package databases. If necessary, old-style virtuals + can be performed on atoms prior to calling this method. + """ + cp = portage.dep_getkey(atom) + if level == "match-all": + matches = set() for db in self._dbs: - bestmatch = None if hasattr(db, "xmatch"): - bestmatch = db.xmatch(level, atom) + matches.update(db.xmatch(level, atom)) else: - bestmatch = portage.best(db.match(atom)) - if bestmatch: - matches.append(bestmatch) - return portage.best(matches) - else: + matches.update(db.match(atom)) + result = list(x for x in matches if portage.cpv_getkey(x) == cp) + db._cpv_sort_ascending(result) + elif level == "match-visible": matches = set() for db in self._dbs: if hasattr(db, "xmatch"): matches.update(db.xmatch(level, atom)) else: - matches.update(db.match(atom)) - matches = list(matches) - db._cpv_sort_ascending(matches) - return matches + db_keys = list(db._aux_cache_keys) + for cpv in db.match(atom): + metadata = dict(izip(db_keys, + db.aux_get(cpv, db_keys))) + if not self._visible(db, cpv, metadata): + continue + matches.add(cpv) + result = list(x for x in matches if portage.cpv_getkey(x) == cp) + db._cpv_sort_ascending(result) + elif level == "bestmatch-visible": + result = None + for db in self._dbs: + if hasattr(db, "xmatch"): + cpv = db.xmatch("bestmatch-visible", atom) + if not cpv or portage.cpv_getkey(cpv) != cp: + continue + if not result or cpv == portage.best([cpv, result]): + result = cpv + else: + db_keys = list(db._aux_cache_keys) + # break out of this loop with highest visible + # match, checked in descending order + for cpv in reversed(db.match(atom)): + if portage.cpv_getkey(cpv) != cp: + continue + metadata = dict(izip(db_keys, + db.aux_get(cpv, db_keys))) + if not self._visible(db, cpv, metadata): + continue + if not result or cpv == portage.best([cpv, result]): + result = cpv + break + else: + raise NotImplementedError(level) + return result def execute(self,searchkey): """Performs the search for the supplied search key""" @@ -557,6 +617,7 @@ class search(object): print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]" print "[ Applications found : "+white(str(self.mlen))+" ]" print " " + vardb = self.vartree.dbapi for mtype in self.matches: for match,masked in self.matches[mtype]: full_package = None @@ -613,8 +674,16 @@ class search(object): mysum[0] = "Unknown (missing digest for %s)" % \ str(e) + available = False + for db in self._dbs: + if db is not vardb and \ + db.cpv_exists(mycpv): + available = True + break + if self.verbose: - print " ", darkgreen("Latest version available:"),myversion + if available: + print " ", darkgreen("Latest version available:"),myversion print " ", self.getInstallationStatus(mycat+'/'+mypkg) if myebuild: print " %s %s" % \ @@ -2047,7 +2116,7 @@ class depgraph(object): except SystemExit, e: raise # Needed else can't exit except Exception, e: - print >> sys.stderr, "\n\n!!! Problem in '%s' dependencies." % mykey + print >> sys.stderr, "\n\n!!! Problem in '%s' dependencies." % atom print >> sys.stderr, "!!!", str(e), getattr(e, "__module__", None) raise @@ -6816,7 +6885,9 @@ def parse_opts(tmpcmdline, silent=False): return myaction, myopts, myfiles def validate_ebuild_environment(trees): - pass + for myroot in trees: + settings = trees[myroot]["vartree"].settings + settings.validate() def load_emerge_config(trees=None): kwargs = {} diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 522d0a1d6..b9f20ca08 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1693,9 +1693,9 @@ class config(object): abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"], PROFILE_PATH.lstrip(os.path.sep)) - if not os.path.islink(abs_profile_path) and \ + if not self.profile_path or (not os.path.islink(abs_profile_path) and \ not os.path.exists(os.path.join(abs_profile_path, "parent")) and \ - os.path.exists(os.path.join(self["PORTDIR"], "profiles")): + os.path.exists(os.path.join(self["PORTDIR"], "profiles"))): writemsg("\a\n\n!!! %s is not a symlink and will probably prevent most merges.\n" % abs_profile_path, noiselevel=-1) writemsg("!!! It should point into a profile within %s/profiles/\n" % self["PORTDIR"]) @@ -2415,6 +2415,7 @@ class config(object): # * Masked flags, such as those from {,package}use.mask # * Forced flags, such as those from {,package}use.force # * build and bootstrap flags used by bootstrap.sh + # * The "test" flag that's enabled by FEATURES=test # Do this even when there's no package since setcpv() can # optimize away regenerate() calls. @@ -2443,6 +2444,7 @@ class config(object): # build and bootstrap flags used by bootstrap.sh iuse_implicit.add("build") iuse_implicit.add("bootstrap") + iuse_implicit.add("test") # prefix flag is used in Prefix iuse_implicit.add("prefix") @@ -2778,7 +2780,11 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero fd_pipes = keywords.get("fd_pipes") if fd_pipes is None: - fd_pipes = {0:0, 1:1, 2:2} + fd_pipes = { + 0:sys.stdin.fileno(), + 1:sys.stdout.fileno(), + 2:sys.stderr.fileno(), + } # In some cases the above print statements don't flush stdout, so # it needs to be flushed before allowing a child process to use it # so that output always shows in the correct order. @@ -5281,15 +5287,15 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): if avail_pkg: avail_slot = "%s:%s" % (dep_getkey(atom), mydbapi.aux_get(avail_pkg, ["SLOT"])[0]) - elif not avail_pkg and \ - (use_binaries or not mydbapi.cp_list(dep_getkey(atom))): - # With --usepkgonly, count installed packages as "available". - # Note that --usepkgonly currently has no package.mask support. - # See bug #149816. - avail_pkg = best(vardb.match(atom)) - if avail_pkg: - avail_slot = "%s:%s" % (dep_getkey(atom), - vardb.aux_get(avail_pkg, ["SLOT"])[0]) + elif not avail_pkg: + has_mask = False + if hasattr(mydbapi, "xmatch"): + has_mask = bool(mydbapi.xmatch("match-all", atom)) + if (use_binaries or not has_mask): + avail_pkg = best(vardb.match(atom)) + if avail_pkg: + avail_slot = "%s:%s" % (dep_getkey(atom), + vardb.aux_get(avail_pkg, ["SLOT"])[0]) if not avail_pkg: all_available = False break @@ -6250,7 +6256,6 @@ def create_trees(config_root=None, target_root=None, trees=None): settings = config(config_root=config_root, target_root=target_root, config_incrementals=portage.const.INCREMENTALS) settings.lock() - settings.validate() myroots = [(settings["ROOT"], settings)] if settings["ROOT"] != "/": @@ -6276,7 +6281,6 @@ def create_trees(config_root=None, target_root=None, trees=None): backupenv.pop(k, None) settings.regenerate() settings.lock() - settings.validate() myroots.append((settings["ROOT"], settings)) for myroot, mysettings in myroots: diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index a1de0695f..0e473ddd1 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -13,7 +13,8 @@ from portage.versions import catpkgsplit, catsplit, pkgcmp class dbapi(object): - _category_re = re.compile(r'^[+\w][-\.+\w]*$') + _category_re = re.compile(r'^\w[-.+\w]*$') + _pkg_dir_name_re = re.compile(r'^\w[-+\w]*$') def __init__(self): pass diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index f448c4afc..21617844c 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -499,7 +499,7 @@ class binarytree(object): if mycpv in pkg_paths: # All is first, so it's preferred. continue - if not mycat: + if not self.dbapi._category_re.match(mycat): writemsg(("!!! Binary package has an " + \ "unrecognized category: '%s'\n") % full_path, noiselevel=-1) @@ -662,7 +662,7 @@ class binarytree(object): continue mycat = self.remotepkgs[mypkg]["CATEGORY"].strip() fullpkg = mycat+"/"+mypkg[:-5] - if not mycat: + if not self.dbapi._category_re.match(mycat): writemsg(("!!! Remote binary package has an " + \ "unrecognized category: '%s'\n") % fullpkg, noiselevel=-1) diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 89bc80161..7ce65b998 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -27,8 +27,9 @@ from itertools import izip class portdbapi(dbapi): """this tree will scan a portage directory located at root (passed to init)""" portdbapi_instances = [] - _non_category_dirs = re.compile(r'^(%s)$' % \ - "|".join(["eclass", "profiles", "scripts"])) + _non_category_dirs = ["eclass", "licenses", + "metadata", "profiles", "scripts"] + _non_category_dirs = re.compile(r'^(%s)$' % "|".join(_non_category_dirs)) def __init__(self, porttree_root, mysettings=None): portdbapi.portdbapi_instances.append(self) @@ -492,6 +493,9 @@ class portdbapi(dbapi): self._non_category_dirs.match(x): continue for y in listdir(oroot+"/"+x, EmptyOnError=1, ignorecvs=1, dirsonly=1): + if not self._pkg_dir_name_re.match(y) or \ + y == "CVS": + continue d[x+"/"+y] = None l = d.keys() l.sort() diff --git a/pym/portage/process.py b/pym/portage/process.py index fcec7588c..e9a1fab70 100644 --- a/pym/portage/process.py +++ b/pym/portage/process.py @@ -185,7 +185,11 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, # If we haven't been told what file descriptors to use # default to propogating our stdin, stdout and stderr. if fd_pipes is None: - fd_pipes = {0:0, 1:1, 2:2} + fd_pipes = { + 0:sys.stdin.fileno(), + 1:sys.stdout.fileno(), + 2:sys.stderr.fileno(), + } # mypids will hold the pids of all processes created. mypids = []