From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 9346D158094 for ; Sat, 8 Oct 2022 10:09:16 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id E3C0AE0A6F; Sat, 8 Oct 2022 10:09:15 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id C8A36E0A6F for ; Sat, 8 Oct 2022 10:09:15 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id ED2AA340DC3 for ; Sat, 8 Oct 2022 10:09:14 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 94BBA5DD for ; Sat, 8 Oct 2022 10:09:13 +0000 (UTC) From: "Arthur Zamarin" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Arthur Zamarin" Message-ID: <1665223099.3fa274977405f73221055c7287880a9dc3038765.arthurzam@gentoo> Subject: [gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/ebuild/, tests/ebuild/ X-VCS-Repository: proj/pkgcore/pkgcore X-VCS-Files: src/pkgcore/ebuild/domain.py src/pkgcore/ebuild/inspect_profile.py src/pkgcore/ebuild/profiles.py src/pkgcore/ebuild/repo_objs.py tests/ebuild/test_profiles.py X-VCS-Directories: tests/ebuild/ src/pkgcore/ebuild/ X-VCS-Committer: arthurzam X-VCS-Committer-Name: Arthur Zamarin X-VCS-Revision: 3fa274977405f73221055c7287880a9dc3038765 X-VCS-Branch: master Date: Sat, 8 Oct 2022 10:09:13 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 7649f8d7-70fd-4ee3-a179-ef81930252a2 X-Archives-Hash: 73744a3900d834c1f772a3f1358fb026 commit: 3fa274977405f73221055c7287880a9dc3038765 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Oct 7 18:52:15 2022 +0000 Commit: Arthur Zamarin gentoo org> CommitDate: Sat Oct 8 09:58:19 2022 +0000 URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=3fa27497 profiles: support package.bashrc files Add support for `profile-bashrcs` profile format, which adds support for per-profile bashrc mechanism `package.bashrc`, which enables to specify per restriction the extra bashrc files to run. See portage(5) for format details. Signed-off-by: Arthur Zamarin gentoo.org> src/pkgcore/ebuild/domain.py | 9 +++--- src/pkgcore/ebuild/inspect_profile.py | 9 ++++++ src/pkgcore/ebuild/profiles.py | 26 ++++++++++++++++ src/pkgcore/ebuild/repo_objs.py | 2 +- tests/ebuild/test_profiles.py | 56 +++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/pkgcore/ebuild/domain.py b/src/pkgcore/ebuild/domain.py index 47f31ef2f..a1f231e9f 100644 --- a/src/pkgcore/ebuild/domain.py +++ b/src/pkgcore/ebuild/domain.py @@ -596,10 +596,11 @@ class domain(config_domain): return self def get_package_bashrcs(self, pkg): - for source in self.profile.bashrcs: - yield source - for source in self.bashrcs: - yield source + yield from self.profile.bashrcs + for restrict, bashrcs in self.profile.pkg_bashrcs: + if restrict.match(pkg): + yield from bashrcs + yield from self.bashrcs if not os.path.exists(self.ebuild_hook_dir): return # matching portage behavior... it's whacked. diff --git a/src/pkgcore/ebuild/inspect_profile.py b/src/pkgcore/ebuild/inspect_profile.py index a0be246c1..dc8c5942d 100644 --- a/src/pkgcore/ebuild/inspect_profile.py +++ b/src/pkgcore/ebuild/inspect_profile.py @@ -187,6 +187,15 @@ class bashrcs(_base, metaclass=_register_command): out.write(bashrc.path) +class package_bashrc(_base, metaclass=_register_command): + """inspect package.bashrc""" + + def __call__(self, namespace, out, err): + for package, bashrcs in namespace.profile.pkg_bashrcs: + bashrcs = ", ".join(s.path for s in bashrcs) + out.write(f'{package}: {bashrcs}') + + class keywords(_base, metaclass=_register_command): """inspect package.keywords""" diff --git a/src/pkgcore/ebuild/profiles.py b/src/pkgcore/ebuild/profiles.py index 4607639cb..34e839e9b 100644 --- a/src/pkgcore/ebuild/profiles.py +++ b/src/pkgcore/ebuild/profiles.py @@ -452,6 +452,27 @@ class ProfileNode(metaclass=caching.WeakInstMeta): return local_source(path) return None + @load_property("package.bashrc", allow_recurse=True) + def pkg_bashrc(self, data): + repo_config = self.repoconfig + if repo_config is None or 'profile-bashrcs' not in repo_config.profile_formats: + return () + + d = defaultdict(list) + for line, lineno, relpath in data: + l = line.split() + try: + a = self.eapi_atom(l[0]) + except ebuild_errors.MalformedAtom as exc: + logger.error(f'{relpath!r}, line {lineno}: parsing error: {exc}') + continue + if len(l) == 1: + logger.error(f'{relpath!r}, line {lineno}: missing bashrc files: {line!r}') + continue + for filename in l[1:]: + d[a].append(local_source(pjoin(self.path, 'bashrc', filename))) + return tuple((k, tuple(v)) for k, v in d.items()) + @load_property('eapi', fallback='0') def eapi(self, data): # handle fallback @@ -522,6 +543,7 @@ class EmptyRootNode(ProfileNode): deprecated = None pkg_use = masked_use = stable_masked_use = forced_use = stable_forced_use = misc.ChunkedDataDict() forced_use.freeze() + pkg_bashrc = () pkg_use_force = pkg_use_mask = ImmutableDict() pkg_provided = system = profile_set = ((), ()) @@ -747,6 +769,10 @@ class ProfileStack: def bashrcs(self): return tuple(x.bashrc for x in self.stack if x.bashrc is not None) + @klass.jit_attr + def pkg_bashrcs(self): + return tuple(chain.from_iterable(x.pkg_bashrc for x in self.stack)) + bashrc = klass.alias_attr("bashrcs") path = klass.alias_attr("node.path") diff --git a/src/pkgcore/ebuild/repo_objs.py b/src/pkgcore/ebuild/repo_objs.py index 633c858e3..78371e29a 100644 --- a/src/pkgcore/ebuild/repo_objs.py +++ b/src/pkgcore/ebuild/repo_objs.py @@ -682,7 +682,7 @@ class RepoConfig(syncable.tree, klass.ImmutableInstance, metaclass=WeakInstMeta) default_hashes = ('size', 'blake2b', 'sha512') default_required_hashes = ('size', 'blake2b') - supported_profile_formats = ('pms', 'portage-1', 'portage-2', 'profile-set') + supported_profile_formats = ('pms', 'portage-1', 'portage-2', 'profile-bashrcs', 'profile-set') supported_cache_formats = ('md5-dict', 'pms') __inst_caching__ = True diff --git a/tests/ebuild/test_profiles.py b/tests/ebuild/test_profiles.py index 8f920825c..a7abfe9f2 100644 --- a/tests/ebuild/test_profiles.py +++ b/tests/ebuild/test_profiles.py @@ -545,6 +545,17 @@ class TestPmsProfileNode(profile_mixin): self.write_file(tmp_path, "profile.bashrc", '') assert self.klass(path).bashrc is not None + def test_pkg_bashrc(self, tmp_path, caplog): + path = tmp_path / self.profile + assert not self.klass(path).pkg_bashrc + self.write_file(tmp_path, "package.bashrc", "@dsfg", profile=self.profile) + assert not self.klass(path).pkg_bashrc + self.write_file(tmp_path, "package.bashrc", "dev-util/foo", profile=self.profile) + assert not self.klass(path).pkg_bashrc + self.write_file(tmp_path, "package.bashrc", "dev-util/foo file1 file2\ndev-util/bar file3", profile=self.profile) + assert not self.klass(path).pkg_bashrc + assert not caplog.text + class TestPortage1ProfileNode(TestPmsProfileNode): @@ -593,6 +604,51 @@ class TestPortage2ProfileNode(TestPortage1ProfileNode): (tmp_path / "metadata" / "layout.conf").write_text("masters = ''\nprofile-formats = portage-2") +class TestProfileBashrcProfileNode(TestPmsProfileNode): + + profile = os.path.join("profiles", "default") + + def assert_pkg_bashrc(self, actual, expected): + assert expected == { + str(k): [s.path for s in v] + for k, v in actual + } + + def setup_repo(self, tmp_path): + (tmp_path / "profiles" / "repo_name").write_bytes(binascii.b2a_hex(os.urandom(10))) + (tmp_path / "metadata").mkdir() + (tmp_path / "metadata" / "layout.conf").write_text("masters = ''\nprofile-formats = profile-bashrcs") + + def test_pkg_bashrc(self, tmp_path, caplog): + path = tmp_path / self.profile + assert not self.klass(path).pkg_bashrc + self.parsing_checks(tmp_path, "package.bashrc", "pkg_bashrc") + assert not caplog.text + + caplog.clear() + self.write_file(tmp_path, "package.bashrc", "@dsfg", profile=self.profile) + assert not self.klass(path).pkg_bashrc + assert "line 1: parsing error: invalid package atom: '@dsfg'" in caplog.text + + caplog.clear() + self.write_file(tmp_path, "package.bashrc", "dev-util/foo", profile=self.profile) + assert not self.klass(path).pkg_bashrc + assert "line 1: missing bashrc files: 'dev-util/foo'" in caplog.text + + caplog.clear() + self.write_file(tmp_path, "package.bashrc", "dev-util/foo file1", profile=self.profile) + self.assert_pkg_bashrc(self.klass(path).pkg_bashrc, {"dev-util/foo": [str(path / "bashrc/file1")]}) + assert not caplog.text + + caplog.clear() + self.write_file(tmp_path, "package.bashrc", "dev-util/foo file1 file2\ndev-util/bar file3", profile=self.profile) + self.assert_pkg_bashrc(self.klass(path).pkg_bashrc, { + "dev-util/foo": [str(path / "bashrc/file1"), str(path / "bashrc/file2")], + "dev-util/bar": [str(path / "bashrc/file3")], + }) + assert not caplog.text + + class TestProfileSetProfileNode(TestPmsProfileNode): profile = os.path.join("profiles", "default")