Merged from trunk 10625:10654
authorFabian Groffen <grobian@gentoo.org>
Tue, 17 Jun 2008 16:43:29 +0000 (16:43 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 17 Jun 2008 16:43:29 +0000 (16:43 -0000)
   | 10626   | Fix missing initialization.                                  |
   | zmedico |                                                              |

   | 10628   | Fix typo.                                                    |
   | zmedico |                                                              |

   | 10631   | Fix typo.                                                    |
   | zmedico |                                                              |

   | 10633   | Add some sanity checks and error tolerance in the owners     |
   | zmedico | cache.                                                       |

   | 10636   | Bug #225285 - Allow digestcheck() to succeed when the        |
   | zmedico | Manifest is empty and strict mode is disabled.               |

   | 10638   | Use isinstance() instead of handling TypeError.              |
   | zmedico |                                                              |

   | 10640   | Add another sanity check in the owners cache.                |
   | zmedico |                                                              |

   | 10642   | Use spawn() instead of system().                             |
   | zmedico |                                                              |

   | 10644   | Bug #225767 - Suppress warnings for installed packages       |
   | zmedico | masked by keywords if there is an equivalent ebuild in the   |
   |         | portage tree (same cpv) with visible keywords.               |

   | 10645   | Handle InvalidDependString.                                  |
   | zmedico |                                                              |

   | 10646   | Fix indent.                                                  |
   | zmedico |                                                              |

   | 10648   | Handle InvalidDependString in _package_cache.__setitem__().  |
   | zmedico |                                                              |

   | 10651   | Pass missing "installed" parameter into Package constructor. |
   | zmedico |                                                              |

   | 10652   | Add two new build log qa checks, suggested by Diego          |
   | zmedico | Pettenò: * Detect automake "maintainer mode". See           |
   |         | http://www.gentoo.org/proj/en/qa/autofailure.xml for more    |
   |         | information. * Detect "Unrecognized options" messages from   |
   |         | configure scripts.                                           |

   | 10653   | Fix the 'inherit.autotools' check to account for             |
   | zmedico | apache-2_src_unpack() calling eautoreconf.                   |

   | 10654   | Add support for and ACCEPT_CHOSTS variable that controls     |
   | zmedico | masking behavior for binary packages wrt CHOST. The variable |
   |         | is a space separated list of chosts. It support regular      |
   |         | expressions, so if the actual chost contains any special     |
   |         | characters then the user must escape them when setting       |
   |         | ACCEPT_CHOSTS.                                               |

svn path=/main/branches/prefix/; revision=10691

bin/dispatch-conf
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/vartree.py
pym/repoman/checks.py

index 3069dd8374f85903d285c1d9062878d4b70366df..28516c9dc792d3b23cf7c35175a708e80d69a74f 100755 (executable)
@@ -220,10 +220,12 @@ class dispatch:
             while 1:
                 clear_screen()
                 if show_new_diff:
-                    os.system((self.options['diff']) % (conf['new'], mrgconf))
+                    cmd = self.options['diff'] % (conf['new'], mrgconf)
+                    spawn_shell(cmd)
                     show_new_diff = 0
                 else:
-                    os.system((self.options['diff']) % (conf['current'], newconf))
+                    cmd = self.options['diff'] % (conf['current'], newconf)
+                    spawn_shell(cmd)
 
                 print
                 print '>> (%i of %i) -- %s' % (count, len(confs), conf ['current'])
@@ -395,6 +397,20 @@ def clear_screen():
         pass
     os.system("clear 2>/dev/null")
 
+from portage.process import find_binary, spawn
+shell = os.environ.get("SHELL")
+if not shell or not os.access(shell, os.EX_OK):
+    shell = find_binary("sh")
+
+def spawn_shell(cmd):
+    if shell:
+        spawn([shell, "-c", cmd], env=os.environ,
+            fd_pipes = {  0 : sys.stdin.fileno(),
+                          1 : sys.stdout.fileno(),
+                          2 : sys.stderr.fileno()})
+    else:
+        os.system(cmd)
+
 # run
 d = dispatch ()
 
index fe0acb8581af2541a31e3aee0efde9e08fa42a5a..fc8428ae62a3c72ea06172e12c30af411a44876f 100644 (file)
@@ -1129,9 +1129,8 @@ def visible(pkgsettings, pkg):
        """
        if not pkg.metadata["SLOT"]:
                return False
-       if pkg.built and not pkg.installed:
-               pkg_chost = pkg.metadata.get("CHOST")
-               if pkg_chost and pkg_chost != pkgsettings["CHOST"]:
+       if pkg.built and not pkg.installed and "CHOST" in pkg.metadata:
+               if not pkgsettings._accept_chost(pkg):
                        return False
        if pkg.built and not pkg.installed:
                # we can have an old binary which has no EPREFIX information
@@ -1161,9 +1160,8 @@ def get_masking_status(pkg, pkgsettings, root_config):
                pkg, settings=pkgsettings,
                portdb=root_config.trees["porttree"].dbapi)
 
-       if pkg.built and not pkg.installed:
-               pkg_chost = pkg.metadata.get("CHOST")
-               if pkg_chost and pkg_chost != pkgsettings["CHOST"]:
+       if pkg.built and not pkg.installed and "CHOST" in pkg.metadata:
+               if not pkgsettings._accept_chost(pkg):
                        mreasons.append("CHOST: %s" % \
                                pkg.metadata["CHOST"])
 
@@ -3471,6 +3469,32 @@ class depgraph(object):
                                        return 0
                return 1
 
+       def _pkg(self, cpv, type_name, root_config, installed=False):
+               """
+               Get a package instance from the cache, or create a new
+               one if necessary. Raises KeyError from aux_get if it
+               failures for some reason (package does not exist or is
+               corrupt).
+               """
+               operation = "merge"
+               if installed:
+                       operation = "nomerge"
+               pkg = self._pkg_cache.get(
+                       (type_name, root_config.root, cpv, operation))
+               if pkg is None:
+                       db = root_config.trees[
+                               self.pkg_tree_map[type_name]].dbapi
+                       metadata = izip(Package.metadata_keys,
+                               db.aux_get(cpv, Package.metadata_keys))
+                       pkg = Package(cpv=cpv, metadata=metadata,
+                               root_config=root_config, installed=installed)
+                       if type_name == "ebuild":
+                               settings = self.pkgsettings[root_config.root]
+                               settings.setcpv(pkg)
+                               pkg.metadata["USE"] = settings["PORTAGE_USE"]
+                       self._pkg_cache[pkg] = pkg
+               return pkg
+
        def validate_blockers(self):
                """Remove any blockers from the digraph that do not match any of the
                packages within the graph.  If necessary, create hard deps to ensure
@@ -3538,7 +3562,19 @@ class depgraph(object):
                                                        pkg.cpv, pkg.metadata) and \
                                                        pkg.metadata["KEYWORDS"].split() and \
                                                        not pkg_in_graph:
-                                                       self._masked_installed.add(pkg)
+                                                       try:
+                                                               ebuild = self._pkg(pkg.cpv,
+                                                                       "ebuild", pkg.root_config)
+                                                       except KeyError:
+                                                               ebuild = None
+                                                       else:
+                                                               try:
+                                                                       if not visible(pkgsettings, ebuild):
+                                                                               ebuild = None
+                                                               except portage.exception.InvalidDependString:
+                                                                       ebuild = None
+                                                       if ebuild is None:
+                                                               self._masked_installed.add(pkg)
 
                                        blocker_atoms = None
                                        blockers = None
@@ -5653,10 +5689,13 @@ class depgraph(object):
                def __setitem__(self, k, v):
                        dict.__setitem__(self, k, v)
                        root_config = self._depgraph.roots[v.root]
-                       if visible(root_config.settings, v) and \
-                               not (v.installed and \
-                               v.root_config.settings.getMissingKeywords(v.cpv, v.metadata)):
-                               root_config.visible_pkgs.cpv_inject(v)
+                       try:
+                               if visible(root_config.settings, v) and \
+                                       not (v.installed and \
+                                       v.root_config.settings.getMissingKeywords(v.cpv, v.metadata)):
+                                       root_config.visible_pkgs.cpv_inject(v)
+                       except portage.exception.InvalidDependString:
+                               pass
 
 class RepoDisplay(object):
        def __init__(self, roots):
index 390ec238dcbcbfff01a125ea408b2ae1be32d149..2fd9217f76e97f4fc7125232c4743c51f1eaf2e6 100644 (file)
@@ -1005,6 +1005,7 @@ class config(object):
        ]
 
        _environ_filter = frozenset(_environ_filter)
+       _accept_chost_re = None
 
        def __init__(self, clone=None, mycpv=None, config_profile_path=None,
                config_incrementals=None, config_root=None, target_root=None,
@@ -2401,6 +2402,26 @@ class config(object):
                                        ret.append(element)
                return ret
 
+       def _accept_chost(self, pkg):
+               """
+               @return True if pkg CHOST is accepted, False otherwise.
+               """
+               if self._accept_chost_re is None:
+                       accept_chost = self.get("ACCEPT_CHOSTS", "").split()
+                       if not accept_chost:
+                               chost = self.get("CHOST")
+                               if chost:
+                                       accept_chost.append(chost)
+                       if not accept_chost:
+                               self._accept_chost_re = re.compile(".*")
+                       elif len(accept_chost) == 1:
+                               self._accept_chost_re = re.compile(accept_chost[0])
+                       else:
+                               self._accept_chost_re = re.compile(
+                                       r'^(%s)$' % "|".join(accept_chost))
+               return self._accept_chost_re.match(
+                       pkg.metadata.get("CHOST", "")) is not None
+
        def setinst(self,mycpv,mydbapi):
                """This updates the preferences for old-style virtuals,
                affecting the behavior of dep_expand() and dep_check()
@@ -4072,6 +4093,18 @@ def digestcheck(myfiles, mysettings, strict=0, justmanifest=0):
                else:
                        return 1
        mf = Manifest(pkgdir, mysettings["DISTDIR"])
+       manifest_empty = True
+       for d in mf.fhashdict.itervalues():
+               if d:
+                       manifest_empty = False
+                       break
+       if manifest_empty:
+               writemsg("!!! Manifest is empty: '%s'\n" % manifest_path,
+                       noiselevel=-1)
+               if strict:
+                       return 0
+               else:
+                       return 1
        eout = portage.output.EOutput()
        eout.quiet = mysettings.get("PORTAGE_QUIET", None) == "1"
        try:
@@ -4170,6 +4203,57 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None):
                        filemode=060, filemask=0)
 
        if phase_retval == os.EX_OK:
+               if mydo == "install" and logfile:
+                       try:
+                               f = open(logfile, 'rb')
+                       except EnvironmentError:
+                               pass
+                       else:
+                               am_maintainer_mode = []
+                               configure_opts_warn = []
+                               configure_opts_warn_re = re.compile(
+                                       r'^configure: WARNING: Unrecognized options: .*')
+                               am_maintainer_mode_re = re.compile(r'.*/missing --run .*')
+                               try:
+                                       for line in f:
+                                               if am_maintainer_mode_re.search(line) is not None:
+                                                       am_maintainer_mode.append(line.rstrip("\n"))
+                                               if configure_opts_warn_re.match(line) is not None:
+                                                       configure_opts_warn.append(line.rstrip("\n"))
+                               finally:
+                                       f.close()
+
+                               from portage.elog.messages import eqawarn
+                               def _eqawarn(lines):
+                                       for line in lines:
+                                               eqawarn(line, phase=mydo, key=mysettings.mycpv)
+                               from textwrap import wrap
+                               wrap_width = 70
+
+                               if am_maintainer_mode:
+                                       msg = ["QA Notice: Automake \"maintainer mode\" detected:"]
+                                       msg.append("")
+                                       msg.extend("\t" + line for line in am_maintainer_mode)
+                                       msg.append("")
+                                       msg.extend(wrap(
+                                               "If you patch Makefile.am, " + \
+                                               "configure.in,  or configure.ac then you " + \
+                                               "should use autotools.eclass and " + \
+                                               "eautomake or eautoreconf. Exceptions " + \
+                                               "are limited to system packages " + \
+                                               "for which it is impossible to run " + \
+                                               "autotools during stage building. " + \
+                                               "See http://www.gentoo.org/p" + \
+                                               "roj/en/qa/autofailure.xml for more information.",
+                                               wrap_width))
+                                       _eqawarn(msg)
+
+                               if configure_opts_warn:
+                                       msg = ["QA Notice: Unrecognized configure options:"]
+                                       msg.append("")
+                                       msg.extend("\t" + line for line in configure_opts_warn)
+                                       _eqawarn(msg)
+
                if mydo == "install":
                        # User and group bits that match the "portage" user or group are
                        # automatically mapped to PORTAGE_INST_UID and PORTAGE_INST_GID if
index dfe1b98a312223208560f59dbe2df50a56d64650..26165a4c89a0cf2d194d53c3286d1523e14af4d9 100644 (file)
@@ -691,6 +691,7 @@ class vardbapi(dbapi):
                return self._aux_cache_obj
 
        def _aux_cache_init(self):
+               aux_cache = None
                try:
                        f = open(self._aux_cache_filename)
                        mypickle = cPickle.Unpickler(f)
@@ -721,6 +722,8 @@ class vardbapi(dbapi):
                                owners = None
                        elif "base_names" not in owners:
                                owners = None
+                       elif not isinstance(owners["base_names"], dict):
+                               owners = None
 
                if owners is None:
                        owners = {
@@ -967,8 +970,7 @@ class vardbapi(dbapi):
                                # Empty path is a code used to represent empty contents.
                                self._add_path("", pkg_hash)
                        for x in contents:
-                               relative_path = x[root_len:]
-                               self._add_path(x, pkg_hash)
+                               self._add_path(x[root_len:], pkg_hash)
                        self._vardb._aux_cache["modified"].add(cpv)
 
                def _add_path(self, path, pkg_hash):
@@ -1020,7 +1022,10 @@ class vardbapi(dbapi):
                        base_names = self._vardb._aux_cache["owners"]["base_names"]
 
                        # Take inventory of all cached package hashes.
-                       for hash_values in base_names.itervalues():
+                       for name, hash_values in base_names.items():
+                               if not isinstance(hash_values, dict):
+                                       del base_names[name]
+                                       continue
                                cached_hashes.update(hash_values)
 
                        # Create sets of valid package hashes and uncached packages.
@@ -1097,8 +1102,18 @@ class vardbapi(dbapi):
                                pkgs = base_names.get(name_hash)
                                if pkgs is not None:
                                        for hash_value in pkgs:
+                                               if not isinstance(hash_value, tuple) or \
+                                                       len(hash_value) != 3:
+                                                       continue
                                                cpv, counter, mtime = hash_value
-                                               if hash_pkg(cpv) != hash_value:
+                                               if not isinstance(cpv, basestring):
+                                                       continue
+                                               try:
+                                                       current_hash = hash_pkg(cpv)
+                                               except KeyError:
+                                                       continue
+
+                                               if current_hash != hash_value:
                                                        continue
                                                if dblink(cpv).isowner(path, root):
                                                        yield dblink(cpv), path
@@ -2516,7 +2531,7 @@ class dblink(object):
                        msg.append("")
                        eerror(msg)
 
-                       owners = self.vartree.dbapi._owners.get_owners(files)
+                       owners = self.vartree.dbapi._owners.get_owners(collisions)
                        self.vartree.dbapi.flush_cache()
 
                        for pkg, owned_files in owners.iteritems():
index e340a57f3a733854c7f5c8ffa915f89002536ce2..0f339adbcd0060ed79d4dfefe23384ae861e724c 100644 (file)
@@ -230,6 +230,11 @@ def run_checks(contents, pkg):
        checks.append(EbuildHeader(pkg.mtime))
        iuse_def = None
        inherit_autotools = "autotools" in pkg.inherited
+       if inherit_autotools:
+               if "apache-2" in pkg.inherited:
+                       # eautoreconf is called by apache-2_src_unpack(),
+                       # so the ebuild doesn't need to call it.
+                       inherit_autotools = False
        autotools_func_call = None
        for num, line in enumerate(contents):
                comment = _comment_re.match(line)