Merged from trunk 9001:9029
authorFabian Groffen <grobian@gentoo.org>
Sat, 22 Dec 2007 13:29:47 +0000 (13:29 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 22 Dec 2007 13:29:47 +0000 (13:29 -0000)
   | 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

bin/portageq
bin/repoman
bin/sed
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/porttree.py
pym/portage/process.py

index 756b1b2fdc6922e018e0c2461c6f568135792b3a..eec63a50463d61c24ee73ce8934ddc32527337a6 100755 (executable)
@@ -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:
index 83f494263a86f8715a26874c1adfdbf55f13a577..c934e876bcc38bfca6bd4c303ee7e88afe44e441 100755 (executable)
@@ -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 fbff4ffdf0e206a2d1584e0837cf42989345402b..fb0148023da8ce5145ed0353500ae1c2620aa90f 100755 (executable)
--- 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$
index 1a238775d4fbe510377d9594f32f5edecec67401..b53a0764f13210f1d199a0d60768874560fc0ce7 100644 (file)
@@ -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 = {}
index 522d0a1d63dcfb3d6e1c3a1a206d273e54c81476..b9f20ca08d5afa825fc4b11071687b208adba28c 100644 (file)
@@ -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:
index a1de0695fc0b2be4c4cc591b0af4de87c64333f3..0e473ddd15a9ba8b24e0ad5459ad20885301eb65 100644 (file)
@@ -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
 
index f448c4afc44d38ed981efab5357c38026c4569e8..21617844ce63de4fd8e1e2742fa56c35d1af1b10 100644 (file)
@@ -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)
index 89bc801618302bb74ac7332b4a1a81ec878d2d83..7ce65b998363b4a64d64a0865a3189e1e9a4adab 100644 (file)
@@ -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()
index fcec7588c3246926a16e7dc58b016133a3d5a1c1..e9a1fab703d20ed491f26940efa501836d91e824 100644 (file)
@@ -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 = []