From: Zac Medico Date: Mon, 22 Jul 2013 18:08:09 +0000 (-0700) Subject: inherit: optimize eclass search X-Git-Tag: v2.2.0_alpha189~34 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=56f416255d0fd5ccf29c08af2eb983080be40dc4;p=portage.git inherit: optimize eclass search 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. --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index fc7fd9e09..7ef8a769c 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -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 diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh index 8a52f3007..37503bf8b 100644 --- a/bin/phase-functions.sh +++ b/bin/phase-functions.sh @@ -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 \ diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 51aa61b41..13a34e695 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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) diff --git a/pym/portage/eclass_cache.py b/pym/portage/eclass_cache.py index cb2cf8a98..8c209c84a 100644 --- a/pym/portage/eclass_cache.py +++ b/pym/portage/eclass_cache.py @@ -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 diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py index 35f80e3dd..285572213 100644 --- a/pym/portage/package/ebuild/_config/special_env_vars.py +++ b/pym/portage/package/ebuild/_config/special_env_vars.py @@ -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", diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 506600823..6871bdf0d 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -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) diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 9db600ead..00159a5d2 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -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