commit: 03df2f52b71ec03e84047409b4564ae27b7c4a46 Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> AuthorDate: Sat Oct 1 14:10:02 2022 +0000 Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> CommitDate: Tue Oct 4 10:43:06 2022 +0000 URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=03df2f52
ProfilesCheck: new check for UnmatchedProfilePackageUnmask Add missing check from repoman, for unmatched unmask of atom in `package.mask` files. This checks for any unmask of package, which isn't masked in parent profiles. Resolves: https://github.com/pkgcore/pkgcheck/issues/369 Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> src/pkgcheck/checks/profiles.py | 49 ++++++++++++++++++++-- .../UnmatchedProfilePackageUnmask/expected.json | 1 + .../UnmatchedProfilePackageUnmask/fix.patch | 7 ++++ testdata/repos/profiledir/profiles/profiles.desc | 1 + .../profiledir/profiles/unmatched_unmasks/eapi | 1 + .../profiles/unmatched_unmasks/package.mask | 2 + .../profiledir/profiles/unmatched_unmasks/parent | 1 + 7 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py index d825730f..73e2898e 100644 --- a/src/pkgcheck/checks/profiles.py +++ b/src/pkgcheck/checks/profiles.py @@ -28,6 +28,23 @@ class UnknownProfilePackage(results.ProfilesResult, results.Warning): return f'{self.path!r}: unknown package: {self.atom!r}' +class UnmatchedProfilePackageUnmask(results.ProfilesResult, results.Warning): + """The profile's files include a package.unmask (or similar) entry which + negates a non-existent mask, i.e. it undoes a mask which doesn't exist in + the parent profile. + + No atoms matching this entry were found in the parent profile to unmask.""" + + def __init__(self, path, atom): + super().__init__() + self.path = path + self.atom = str(atom) + + @property + def desc(self): + return f'{self.path!r}: unmask of not masked package: {self.atom!r}' + + class UnknownProfilePackageUse(results.ProfilesResult, results.Warning): """Profile files include entries with USE flags that aren't used on any matching packages.""" @@ -129,7 +146,8 @@ class ProfilesCheck(Check): _source = sources.ProfilesRepoSource required_addons = (addons.UseAddon, addons.KeywordsAddon) known_results = frozenset([ - UnknownProfilePackage, UnknownProfilePackageUse, UnknownProfileUse, + UnknownProfilePackage, UnmatchedProfilePackageUnmask, + UnknownProfilePackageUse, UnknownProfileUse, UnknownProfilePackageKeywords, UnknownProfileUseExpand, ProfileWarning, ProfileError, ]) @@ -145,11 +163,19 @@ class ProfilesCheck(Check): self.profiles_dir = repo.config.profiles_base self.use_expand_groups = frozenset(x.upper() for x in repo.config.use_expand_desc) - local_iuse = {use for pkg, (use, desc) in repo.config.use_local_desc} + local_iuse = {use for _pkg, (use, _desc) in repo.config.use_local_desc} self.available_iuse = frozenset( local_iuse | use_addon.global_iuse | use_addon.global_iuse_expand | use_addon.global_iuse_implicit) + @staticmethod + def traverse_parents_tree(profile): + def _traverse(node): + for parent in node.parents: + yield parent + yield from _traverse(parent) + return set(_traverse(profile)) + @verify_files(('parent', 'parents'), ('eapi', 'eapi')) def _pull_attr(self, *args): @@ -160,7 +186,7 @@ class ProfilesCheck(Check): def _deprecated(self, filename, node, vals): # make sure replacement profile exists if vals is not None: - replacement, msg = vals + replacement, _msg = vals try: addons.profiles.ProfileNode(pjoin(self.profiles_dir, replacement)) except profiles_mod.ProfileError: @@ -195,7 +221,6 @@ class ProfilesCheck(Check): pjoin(node.name, filename), unknown_enabled) @verify_files(('packages', 'packages'), - ('package.mask', 'masks'), ('package.unmask', 'unmasks'), ('package.deprecated', 'pkg_deprecated')) def _pkg_atoms(self, filename, node, vals): @@ -203,6 +228,22 @@ class ProfilesCheck(Check): if not self.search_repo.match(x): yield UnknownProfilePackage(pjoin(node.name, filename), x) + @verify_files(('package.mask', 'masks'),) + def _pkg_masks(self, filename, node, vals): + all_parents = self.traverse_parents_tree(node) + all_masked = set().union(*(masked[1] + for p in all_parents if (masked := p.masks))) + + unmasked, masked = vals + for x in masked: + if not self.search_repo.match(x): + yield UnknownProfilePackage(pjoin(node.name, filename), x) + for x in unmasked: + if not self.search_repo.match(x): + yield UnknownProfilePackage(pjoin(node.name, filename), x) + elif x not in all_masked: + yield UnmatchedProfilePackageUnmask(pjoin(node.name, filename), x) + @verify_files(('package.use', 'pkg_use'), ('package.use.force', 'pkg_use_force'), ('package.use.stable.force', 'pkg_use_stable_force'), diff --git a/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/expected.json b/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/expected.json new file mode 100644 index 00000000..2f162524 --- /dev/null +++ b/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/expected.json @@ -0,0 +1 @@ +{"__class__": "UnmatchedProfilePackageUnmask", "path": "unmatched_unmasks/package.mask", "atom": "cat/pkg4"} diff --git a/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/fix.patch b/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/fix.patch new file mode 100644 index 00000000..5c385d94 --- /dev/null +++ b/testdata/data/repos/profiledir/ProfilesCheck/UnmatchedProfilePackageUnmask/fix.patch @@ -0,0 +1,7 @@ +diff -Naur profiledir/profiles/unmatched_unmasks/package.mask fixed/profiles/unmatched_unmasks/package.mask +index fc6201bc..73b38bc7 100644 +--- profiledir/profiles/unmatched_unmasks/package.mask ++++ fixed/profiles/unmatched_unmasks/package.mask +@@ -1,2 +1 @@ +--cat/pkg4 + -cat/pkg3 diff --git a/testdata/repos/profiledir/profiles/profiles.desc b/testdata/repos/profiledir/profiles/profiles.desc index 0cdb97be..ea649fd9 100644 --- a/testdata/repos/profiledir/profiles/profiles.desc +++ b/testdata/repos/profiledir/profiles/profiles.desc @@ -5,6 +5,7 @@ amd64 nonexistent exp amd64 unknown_pkgs exp amd64 unknown_kwds exp +amd64 unmatched_unmasks exp amd64 unknown_use exp amd64 unknown_use/unknown_stable_use exp diff --git a/testdata/repos/profiledir/profiles/unmatched_unmasks/eapi b/testdata/repos/profiledir/profiles/unmatched_unmasks/eapi new file mode 100644 index 00000000..7f8f011e --- /dev/null +++ b/testdata/repos/profiledir/profiles/unmatched_unmasks/eapi @@ -0,0 +1 @@ +7 diff --git a/testdata/repos/profiledir/profiles/unmatched_unmasks/package.mask b/testdata/repos/profiledir/profiles/unmatched_unmasks/package.mask new file mode 100644 index 00000000..fc6201bc --- /dev/null +++ b/testdata/repos/profiledir/profiles/unmatched_unmasks/package.mask @@ -0,0 +1,2 @@ +-cat/pkg4 +-cat/pkg3 diff --git a/testdata/repos/profiledir/profiles/unmatched_unmasks/parent b/testdata/repos/profiledir/profiles/unmatched_unmasks/parent new file mode 100644 index 00000000..e4166365 --- /dev/null +++ b/testdata/repos/profiledir/profiles/unmatched_unmasks/parent @@ -0,0 +1 @@ +../unknown_pkgs