From a00baf7ef659ec41d1a91f96ef704f81fa4a7acb Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Tue, 17 Jun 2008 16:43:29 +0000 Subject: [PATCH] Merged from trunk 10625:10654 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit | 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 | 20 ++++++++- pym/_emerge/__init__.py | 61 +++++++++++++++++++++----- pym/portage/__init__.py | 84 ++++++++++++++++++++++++++++++++++++ pym/portage/dbapi/vartree.py | 25 ++++++++--- pym/repoman/checks.py | 5 +++ 5 files changed, 177 insertions(+), 18 deletions(-) diff --git a/bin/dispatch-conf b/bin/dispatch-conf index 3069dd837..28516c9dc 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -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 () diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index fe0acb858..fc8428ae6 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -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): diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 390ec238d..2fd9217f7 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index dfe1b98a3..26165a4c8 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -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(): diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py index e340a57f3..0f339adbc 100644 --- a/pym/repoman/checks.py +++ b/pym/repoman/checks.py @@ -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) -- 2.26.2