inherit: optimize eclass search
authorZac Medico <zmedico@gentoo.org>
Mon, 22 Jul 2013 18:08:09 +0000 (11:08 -0700)
committerZac Medico <zmedico@gentoo.org>
Mon, 22 Jul 2013 18:08:09 +0000 (11:08 -0700)
Use PORTAGE_ECLASS_LOCATIONS variable ordered so that we can break out
of the eclass search loop as soon as the first match is found.

bin/ebuild.sh
bin/phase-functions.sh
pym/portage/__init__.py
pym/portage/eclass_cache.py
pym/portage/package/ebuild/_config/special_env_vars.py
pym/portage/package/ebuild/config.py
pym/portage/package/ebuild/doebuild.py

index fc7fd9e098374642a4e50e35f1b9eaaa4de2c897..7ef8a769c6beeb83c10e197afab29053a743e798 100755 (executable)
@@ -207,7 +207,6 @@ inherit() {
                        | fmt -w 75 | while read -r ; do eqawarn "$REPLY" ; done
        fi
 
-       local repo
        local repo_location
        local location
        local potential_location
@@ -246,12 +245,12 @@ inherit() {
                        fi
                fi
 
-               for repo in $(__repo_key ${PORTAGE_REPO_NAME} masters) ${PORTAGE_REPO_NAME} $(__repo_key ${PORTAGE_REPO_NAME} eclass-overrides); do
-                       repo_location="$(__repo_key ${repo} location)"
+               for repo_location in ${PORTAGE_ECLASS_LOCATIONS[@]}; do
                        potential_location="${repo_location}/eclass/${1}.eclass"
                        if [[ -f ${potential_location} ]]; then
                                location="${potential_location}"
                                debug-print "  eclass exists: ${location}"
+                               break
                        fi
                done
                debug-print "inherit: $1 -> $location"
@@ -515,6 +514,9 @@ if ___eapi_enables_globstar; then
        shopt -s globstar
 fi
 
+# Convert quoted paths to array.
+eval "PORTAGE_ECLASS_LOCATIONS=(${PORTAGE_ECLASS_LOCATIONS})"
+
 # Source the ebuild every time for FEATURES=noauto, so that ebuild
 # modifications take effect immediately.
 if ! has "$EBUILD_PHASE" clean cleanrm ; then
index 8a52f3007df0b0a9736375ef81f75199b7a73074..37503bf8bf493066ff2d6ef28dfea9ba8c126626 100644 (file)
@@ -20,6 +20,7 @@ PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE EBUILD_PHASE_FUNC \
        PORTAGE_BUILD_USER PORTAGE_BUNZIP2_COMMAND \
        PORTAGE_BZIP2_COMMAND PORTAGE_COLORMAP PORTAGE_CONFIGROOT \
        PORTAGE_DEBUG PORTAGE_DEPCACHEDIR PORTAGE_EBUILD_EXIT_FILE \
+       PORTAGE_ECLASS_LOCATIONS \
        PORTAGE_GID PORTAGE_GRPNAME PORTAGE_INST_GID PORTAGE_INST_UID \
        PORTAGE_INTERNAL_CALLER PORTAGE_IPC_DAEMON PORTAGE_IUSE PORTAGE_LOG_FILE \
        PORTAGE_MUTABLE_FILTERED_VARS PORTAGE_OVERRIDE_EPREFIX \
index 51aa61b41ec7033fad2532119d82ddc40dbf84af..13a34e695f15228932b2956ea65e5bf34b03f055 100644 (file)
@@ -404,12 +404,16 @@ def _get_stdin():
                return sys.__stdin__
        return sys.stdin
 
+_shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
+
 def _shell_quote(s):
        """
        Quote a string in double-quotes and use backslashes to
        escape any backslashes, double-quotes, dollar signs, or
        backquotes in the string.
        """
+       if _shell_quote_re.search(s) is None:
+               return s
        for letter in "\\\"$`":
                if letter in s:
                        s = s.replace(letter, "\\" + letter)
index cb2cf8a980892bd26aa8c0123421c84d9e6dd01a..8c209c84a244a56af5ea0fcae1d844b7ec4aea12 100644 (file)
@@ -1,7 +1,9 @@
-# Copyright 2005-2011 Gentoo Foundation
+# Copyright 2005-2013 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 # Author(s): Nicholas Carpaski (carpaski@gentoo.org), Brian Harring (ferringb@gentoo.org)
 
+from __future__ import unicode_literals
+
 __all__ = ["cache"]
 
 import stat
@@ -12,6 +14,7 @@ import errno
 from portage.exception import FileNotFound, PermissionDenied
 from portage import os
 from portage import checksum
+from portage import _shell_quote
 
 if sys.hexversion >= 0x3000000:
        long = int
@@ -60,6 +63,7 @@ class cache(object):
 
                self.eclasses = {} # {"Name": hashed_path}
                self._eclass_locations = {}
+               self._eclass_locations_str = None
 
                # screw with the porttree ordering, w/out having bash inherit match it, and I'll hurt you.
                # ~harring
@@ -98,6 +102,7 @@ class cache(object):
                self.porttrees = self.porttrees + other.porttrees
                self.eclasses.update(other.eclasses)
                self._eclass_locations.update(other._eclass_locations)
+               self._eclass_locations_str = None
 
        def update_eclasses(self):
                self.eclasses = {}
@@ -169,3 +174,10 @@ class cache(object):
                        ec_dict[x] = self.eclasses[x]
 
                return ec_dict
+
+       @property
+       def eclass_locations_string(self):
+               if self._eclass_locations_str is None:
+                       self._eclass_locations_str = " ".join(_shell_quote(x)
+                               for x in reversed(self.porttrees))
+               return self._eclass_locations_str
index 35f80e3dd735ba4514d8a7f8c0117e7d899c8edb..285572213eb1651d95e75126795eebd484eb52d3 100644 (file)
@@ -66,7 +66,7 @@ environ_whitelist += [
        "PORTAGE_GID", "PORTAGE_GRPNAME",
        "PORTAGE_INTERNAL_CALLER",
        "PORTAGE_INST_GID", "PORTAGE_INST_UID",
-       "PORTAGE_IPC_DAEMON", "PORTAGE_IUSE",
+       "PORTAGE_IPC_DAEMON", "PORTAGE_IUSE", "PORTAGE_ECLASS_LOCATIONS",
        "PORTAGE_LOG_FILE", "PORTAGE_OVERRIDE_EPREFIX", "PORTAGE_PIPE_FD",
        "PORTAGE_PYM_PATH", "PORTAGE_PYTHON",
        "PORTAGE_PYTHONPATH", "PORTAGE_QUIET",
index 506600823293ab52594f9f142d14333555db0fc0..6871bdf0dc57d5b8da7eb34ed67db76ac044c448 100644 (file)
@@ -524,13 +524,10 @@ class config(object):
 
                        new_ov = []
                        if portdir_overlay:
-                               shell_quote_re = re.compile(r"[\s\\\"'$`]")
                                for ov in portdir_overlay:
                                        ov = normalize_path(ov)
                                        if isdir_raise_eaccess(ov):
-                                               if shell_quote_re.search(ov) is not None:
-                                                       ov = portage._shell_quote(ov)
-                                               new_ov.append(ov)
+                                               new_ov.append(portage._shell_quote(ov))
                                        else:
                                                writemsg(_("!!! Invalid PORTDIR_OVERLAY"
                                                        " (not a dir): '%s'\n") % ov, noiselevel=-1)
index 9db600ead6b6806f344744ec8ade69a7a834fbc1..00159a5d248e734419c36f59802a57a763cc485e 100644 (file)
@@ -305,6 +305,7 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
        if hasattr(mydbapi, 'repositories'):
                repo = mydbapi.repositories.get_repo_for_location(mytree)
                mysettings['PORTDIR'] = repo.eclass_db.porttrees[0]
+               mysettings['PORTAGE_ECLASS_LOCATIONS'] = repo.eclass_db.eclass_locations_string
                mysettings['PORTAGE_REPOSITORIES'] = mydbapi.repositories.config_string()
                mysettings.configdict["pkg"]["PORTAGE_REPO_NAME"] = repo.name