commit: eea598a20b2db5ecbe3975dc96885f529ae54c1c Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sat Mar 9 21:22:35 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Sat Mar 9 21:22:35 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=eea598a2
__dyn_install: Record REPO_REVISIONS in build-info Record REPO_REVISIONS as a json object that maps repo name to revision for an ebuild's source repository and any repositories that eclasses were inherited from: $ cat /var/tmp/portage/sys-apps/portage-3.0.63/build-info/REPO_REVISIONS {"gentoo": "34875e30e73e33d3597d1101cdf97dc22729b268"} Ultimately the intention is to expose this information in binhost metadata so that clients can select consistent revisions of source repositories. Bug: https://bugs.gentoo.org/924772 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> bin/phase-functions.sh | 1 + lib/_emerge/EbuildPhase.py | 46 ++++++++++++++++++++++ .../package/ebuild/_config/special_env_vars.py | 1 + 3 files changed, 48 insertions(+) diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh index ab130a3be5..9ff5554405 100644 --- a/bin/phase-functions.sh +++ b/bin/phase-functions.sh @@ -719,6 +719,7 @@ __dyn_install() { cp "${EBUILD}" "${PF}.ebuild" [[ -n "${PORTAGE_REPO_NAME}" ]] && echo "${PORTAGE_REPO_NAME}" > repository + [[ -n ${PORTAGE_REPO_REVISIONS} ]] && echo "${PORTAGE_REPO_REVISIONS}" > REPO_REVISIONS if has nostrip ${FEATURES} ${PORTAGE_RESTRICT} || has strip ${PORTAGE_RESTRICT}; then >> DEBUGBUILD fi diff --git a/lib/_emerge/EbuildPhase.py b/lib/_emerge/EbuildPhase.py index b472803438..86a64be78e 100644 --- a/lib/_emerge/EbuildPhase.py +++ b/lib/_emerge/EbuildPhase.py @@ -4,6 +4,7 @@ import functools import gzip import io +import json import sys import tempfile @@ -83,6 +84,50 @@ async def _setup_locale(settings): raise AssertionError("C locale did not pass the test!") +async def _setup_repo_revisions(settings): + repo_name = settings.configdict["pkg"].get("PORTAGE_REPO_NAME") + db = getattr(settings.mycpv, "_db", None) + if ( + isinstance(db, portage.portdbapi) + and repo_name + and "PORTAGE_REPO_REVISIONS" not in settings.configdict["pkg"] + ): + inherits = frozenset( + ( + await db.async_aux_get( + settings.mycpv, + ["INHERITED"], + myrepo=repo_name, + ) + )[0].split() + ) + repo = db.repositories[repo_name] + ec_dict = repo.eclass_db.get_eclass_data(inherits) + referenced_repos = {repo.name: repo} + for ec_info in ec_dict.values(): + ec_repo = db.repositories.get_repo_for_location( + os.path.dirname(os.path.dirname(ec_info.location)) + ) + referenced_repos.setdefault(ec_repo.name, ec_repo) + repo_revisions = {} + for repo_ref in referenced_repos.values(): + if repo_ref.sync_type: + sync = portage.sync.module_controller.get_class(repo_ref.sync_type)() + try: + # TODO: Wait for subprocesses asynchronously here. + status, repo_revision = sync.retrieve_head( + options={"repo": repo_ref} + ) + except NotImplementedError: + pass + else: + if status == os.EX_OK: + repo_revisions[repo_ref.name] = repo_revision.strip() + settings.configdict["pkg"]["PORTAGE_REPO_REVISIONS"] = json.dumps( + repo_revisions, ensure_ascii=False, sort_keys=True + ) + + class EbuildPhase(CompositeTask): __slots__ = ("actionmap", "fd_pipes", "phase", "settings") + ("_ebuild_lock",) @@ -120,6 +165,7 @@ class EbuildPhase(CompositeTask): async def _async_start(self): await _setup_locale(self.settings) + await _setup_repo_revisions(self.settings) need_builddir = self.phase not in EbuildProcess._phases_without_builddir diff --git a/lib/portage/package/ebuild/_config/special_env_vars.py b/lib/portage/package/ebuild/_config/special_env_vars.py index 6020029e35..1a66192c96 100644 --- a/lib/portage/package/ebuild/_config/special_env_vars.py +++ b/lib/portage/package/ebuild/_config/special_env_vars.py @@ -165,6 +165,7 @@ environ_whitelist = frozenset( "PORTAGE_PYTHON", "PORTAGE_PYTHONPATH", "PORTAGE_QUIET", + "PORTAGE_REPO_REVISIONS", "PORTAGE_REPO_NAME", "PORTAGE_REPOSITORIES", "PORTAGE_RESTRICT",