aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Zamarin <arthurzam@gentoo.org>2024-01-13 11:16:10 +0200
committerArthur Zamarin <arthurzam@gentoo.org>2024-01-13 11:16:10 +0200
commitf2d4e371da2bfa834644973d4dd0bede50deafb4 (patch)
treeb01862d2cd0d1c25a6af0417080bf6b7b18bdcd2
parentDeprecatedDep: fix mishandling of slotted deprecates (diff)
downloadpkgcheck-f2d4e371da2bfa834644973d4dd0bede50deafb4.tar.gz
pkgcheck-f2d4e371da2bfa834644973d4dd0bede50deafb4.tar.bz2
pkgcheck-f2d4e371da2bfa834644973d4dd0bede50deafb4.zip
UnstatedIuse: check for unstated IUSE in "?" dependencies
Check for cases where a dependency uses conditional use dependency with unknown USE flag. PMS states: It is an error for an ebuild to use a conditional use dependency when that ebuild does not have the flag in IUSE_EFFECTIVE. Bug: https://bugs.gentoo.org/921841 Requested-by: Sam James <sam@gentoo.org> Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
-rw-r--r--src/pkgcheck/checks/metadata.py33
-rw-r--r--testdata/data/repos/standalone/DependencyCheck/MissingUseDepDefault/fix.patch4
-rw-r--r--testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected-verbose.json1
-rw-r--r--testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected.json1
-rw-r--r--testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild1
-rw-r--r--testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/metadata.xml7
-rw-r--r--testdata/repos/standalone/DependencyCheck/UnstatedIuse/UnstatedIuse-0.ebuild3
-rw-r--r--tests/checks/test_metadata.py2
8 files changed, 37 insertions, 15 deletions
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 2aba62f0..2cbb8985 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -7,8 +7,8 @@ from difflib import SequenceMatcher
from functools import partial
from operator import attrgetter
-from pkgcore.ebuild import atom as atom_mod, restricts
-from pkgcore.ebuild.atom import atom as atom_cls
+from pkgcore.ebuild import restricts
+from pkgcore.ebuild.atom import atom as atom_cls, transitive_use_atom
from pkgcore.ebuild.eapi import get_eapi
from pkgcore.ebuild.misc import sort_keywords
from pkgcore.fetch import fetchable, unknown_mirror
@@ -871,7 +871,7 @@ class DependencyCheck(Check):
required_addons = (addons.UseAddon,)
known_results = frozenset(
- [
+ {
BadDependency,
MissingPackageRevision,
MissingUseDepDefault,
@@ -883,7 +883,7 @@ class DependencyCheck(Check):
InvalidBdepend,
InvalidIdepend,
MisplacedWeakBlocker,
- ]
+ }
)
def __init__(self, *args, use_addon):
@@ -929,12 +929,9 @@ class DependencyCheck(Check):
)
yield from unstated
+ unknowns_useflags = set()
for node in nodes:
- if isinstance(node, boolean.OrRestriction):
- in_or_restriction = True
- else:
- in_or_restriction = False
-
+ in_or_restriction = isinstance(node, boolean.OrRestriction)
for atom in iflatten_instance(node, (atom_cls,)):
# Skip reporting blockers on deprecated packages; the primary
# purpose of deprecations is to get rid of dependencies
@@ -959,6 +956,15 @@ class DependencyCheck(Check):
if atom.op == "=" and not atom.revision:
yield MissingPackageRevision(attr, str(atom), pkg=pkg)
+ if isinstance(atom, transitive_use_atom) and atom.use is not None:
+ for useflag in atom.use:
+ if useflag[-1] == "?":
+ useflag = useflag[:-1].removeprefix("!")
+ if useflag[-1] == ")":
+ useflag = useflag[:-3]
+ if useflag not in pkg.iuse_stripped:
+ unknowns_useflags.add(useflag)
+
if atom.blocks:
if atom.match(pkg):
yield BadDependency(attr, atom, "package blocks itself", pkg=pkg)
@@ -969,6 +975,9 @@ class DependencyCheck(Check):
elif not atom.blocks_strongly:
weak_blocks[attr].add(atom)
+ if unknowns_useflags:
+ yield UnstatedIuse(attr, sorted(unknowns_useflags), pkg=pkg)
+
for attr in ("depend", "bdepend"):
weak_blocks[attr].difference_update(weak_blocks["rdepend"])
weak_blocks["idepend"].difference_update(weak_blocks["rdepend"], weak_blocks["depend"])
@@ -1597,7 +1606,7 @@ class InvalidProperties(results.MetadataError, results.VersionResult):
class _RestrictPropertiesCheck(Check):
"""Generic check for RESTRICT and PROPERTIES."""
- _attr = None
+ _attr: str = None
_unknown_result_cls = None
required_addons = (addons.UseAddon,)
@@ -1606,9 +1615,9 @@ class _RestrictPropertiesCheck(Check):
self.filter = use_addon.get_filter(self._attr)
# pull allowed values from a repo and its masters
- allowed = []
+ allowed = set()
for repo in self.options.target_repo.trees:
- allowed.extend(getattr(repo.config, f"{self._attr}_allowed"))
+ allowed.update(getattr(repo.config, f"{self._attr}_allowed"))
self.allowed = frozenset(allowed)
def feed(self, pkg):
diff --git a/testdata/data/repos/standalone/DependencyCheck/MissingUseDepDefault/fix.patch b/testdata/data/repos/standalone/DependencyCheck/MissingUseDepDefault/fix.patch
index c86bbe16..c1cd3750 100644
--- a/testdata/data/repos/standalone/DependencyCheck/MissingUseDepDefault/fix.patch
+++ b/testdata/data/repos/standalone/DependencyCheck/MissingUseDepDefault/fix.patch
@@ -1,10 +1,10 @@
diff -Naur standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild fixed/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild
--- standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild 2019-12-02 21:50:34.617257001 -0700
+++ fixed/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild 2019-12-02 21:52:56.547749364 -0700
-@@ -3,7 +3,7 @@
- HOMEPAGE="https://github.com/pkgcore/pkgcheck"
+@@ -4,7 +4,7 @@
SLOT="0"
LICENSE="BSD"
+ IUSE="foo"
-DEPEND="stub/stub1[foo]"
-RDEPEND="|| ( stub/stub2[used] stub/stub2[-foo] )"
-BDEPEND="stub/stub3[foo?]"
diff --git a/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected-verbose.json b/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected-verbose.json
index 799fec6f..12e2f462 100644
--- a/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected-verbose.json
+++ b/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected-verbose.json
@@ -1,2 +1,3 @@
+{"__class__": "UnstatedIuse", "category": "DependencyCheck", "package": "UnstatedIuse", "version": "0", "attr": "depend", "flags": ["used"], "profile": null, "num_profiles": null}
{"__class__": "UnstatedIuse", "category": "DependencyCheck", "package": "UnstatedIuse", "version": "0", "attr": "rdepend", "flags": ["used"], "profile": "default/amd64", "num_profiles": null}
{"__class__": "UnstatedIuse", "category": "DependencyCheck", "package": "UnstatedIuse", "version": "0", "attr": "rdepend", "flags": ["used"], "profile": "default/x86", "num_profiles": null}
diff --git a/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected.json b/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected.json
index 512b0afa..0950d1f3 100644
--- a/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected.json
+++ b/testdata/data/repos/standalone/DependencyCheck/UnstatedIuse/expected.json
@@ -1 +1,2 @@
+{"__class__": "UnstatedIuse", "category": "DependencyCheck", "package": "UnstatedIuse", "version": "0", "attr": "depend", "flags": ["used"], "profile": null, "num_profiles": null}
{"__class__": "UnstatedIuse", "category": "DependencyCheck", "package": "UnstatedIuse", "version": "0", "attr": "rdepend", "flags": ["used"], "profile": "default/amd64", "num_profiles": 2}
diff --git a/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild b/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild
index 53992988..f03b475b 100644
--- a/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild
+++ b/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/MissingUseDepDefault-0.ebuild
@@ -4,6 +4,7 @@ DESCRIPTION="Ebuild missing USE dependency default"
HOMEPAGE="https://github.com/pkgcore/pkgcheck"
SLOT="0"
LICENSE="BSD"
+IUSE="foo"
DEPEND="stub/stub1[foo]"
RDEPEND="|| ( stub/stub2[used] stub/stub2[-foo] )"
BDEPEND="stub/stub3[foo?]"
diff --git a/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/metadata.xml b/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/metadata.xml
new file mode 100644
index 00000000..bd802a63
--- /dev/null
+++ b/testdata/repos/standalone/DependencyCheck/MissingUseDepDefault/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <use>
+ <flag name="foo">stub</flag>
+ </use>
+</pkgmetadata>
diff --git a/testdata/repos/standalone/DependencyCheck/UnstatedIuse/UnstatedIuse-0.ebuild b/testdata/repos/standalone/DependencyCheck/UnstatedIuse/UnstatedIuse-0.ebuild
index b7438aaa..1179764b 100644
--- a/testdata/repos/standalone/DependencyCheck/UnstatedIuse/UnstatedIuse-0.ebuild
+++ b/testdata/repos/standalone/DependencyCheck/UnstatedIuse/UnstatedIuse-0.ebuild
@@ -1,5 +1,8 @@
+EAPI=7
+
DESCRIPTION="Ebuild with unstated IUSE in depsets"
HOMEPAGE="https://github.com/pkgcore/pkgcheck"
SLOT="0"
LICENSE="BSD"
RDEPEND="used? ( stub/stub1 )"
+DEPEND="stub/stub4[used?]"
diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index 77c062c6..f6c2f00b 100644
--- a/tests/checks/test_metadata.py
+++ b/tests/checks/test_metadata.py
@@ -953,7 +953,7 @@ class TestDependencyCheck(use_based(), misc.ReportTestCase):
@pytest.mark.parametrize("attr", dep_attrs)
def test_depset_missing_usedep_default(self, attr):
chk = self.mk_check()
- mk_pkg = partial(self.mk_pkg, attr)
+ mk_pkg = partial(self.mk_pkg, attr, iuse="foo bar baz blah")
# USE flag exists on all matching pkgs
self.assertNoReport(chk, mk_pkg(eapi="4", depset="dev-libs/foo[bar?]"))