From: "Arthur Zamarin" <arthurzam@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...
Date: Mon, 2 Jan 2023 20:19:03 +0000 (UTC) [thread overview]
Message-ID: <1672690303.4247e10d9c266ac1f6aac48b0c67f1092dde1d78.arthurzam@gentoo> (raw)
commit: 4247e10d9c266ac1f6aac48b0c67f1092dde1d78
Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Fri Dec 30 19:27:23 2022 +0000
Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Mon Jan 2 20:11:43 2023 +0000
URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4247e10d
ProvidedEclassInherit: new check for inheriting provided eclases
Resolves: https://github.com/pkgcore/pkgcheck/issues/504
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>
src/pkgcheck/checks/eclass.py | 103 ++++++++++++++-------
.../ProvidedEclassInherit/expected.json | 1 +
.../ProvidedEclassInherit/fix.patch | 10 ++
.../ProvidedEclassInherit-0.ebuild | 11 +++
4 files changed, 93 insertions(+), 32 deletions(-)
diff --git a/src/pkgcheck/checks/eclass.py b/src/pkgcheck/checks/eclass.py
index 5c4f205f..862dbb91 100644
--- a/src/pkgcheck/checks/eclass.py
+++ b/src/pkgcheck/checks/eclass.py
@@ -98,18 +98,36 @@ class MisplacedEclassVar(results.LineResult, results.Error):
return f"invalid pre-inherit placement, line {self.lineno}: {self.line!r}"
+class ProvidedEclassInherit(results.LineResult, results.Style):
+ """Ebuild inherits an eclass which is already provided by another eclass.
+
+ When inheriting an eclass which declares ``@PROVIDES``, those referenced
+ eclasses are guaranteed to be provided by the eclass. Therefore, inheriting
+ them in ebuilds is redundant and should be removed.
+ """
+
+ def __init__(self, provider, **kwargs):
+ super().__init__(**kwargs)
+ self.provider = provider
+
+ @property
+ def desc(self):
+ return f"line {self.lineno}: redundant eclass inherit {self.line!r}, provided by {self.provider!r}"
+
+
class EclassUsageCheck(Check):
"""Scan packages for various eclass-related issues."""
_source = sources.EbuildParseRepoSource
known_results = frozenset(
- [
+ {
DeprecatedEclass,
DeprecatedEclassVariable,
DeprecatedEclassFunction,
DuplicateEclassInherit,
MisplacedEclassVar,
- ]
+ ProvidedEclassInherit,
+ }
)
required_addons = (addons.eclass.EclassAddon,)
@@ -118,15 +136,16 @@ class EclassUsageCheck(Check):
self.deprecated_eclasses = eclass_addon.deprecated
self.eclass_cache = eclass_addon.eclasses
- def check_pre_inherits(self, pkg, inherits):
+ def check_pre_inherits(self, pkg, inherits: list[tuple[list[str], int]]):
"""Check for invalid @PRE_INHERIT variable placement."""
- pre_inherits = {}
# determine if any inherited eclasses have @PRE_INHERIT variables
- for eclasses, lineno in inherits:
- for eclass in eclasses:
- for var in self.eclass_cache[eclass].variables:
- if var.pre_inherit:
- pre_inherits[var.name] = lineno
+ pre_inherits = {
+ var.name: lineno
+ for eclasses, lineno in inherits
+ for eclass in eclasses
+ for var in self.eclass_cache[eclass].variables
+ if var.pre_inherit
+ }
# scan for any misplaced @PRE_INHERIT variables
if pre_inherits:
@@ -137,22 +156,23 @@ class EclassUsageCheck(Check):
line = pkg.node_str(node)
yield MisplacedEclassVar(var_name, line=line, lineno=lineno + 1, pkg=pkg)
- def check_deprecated_variables(self, pkg, inherits):
- """Check for usage of @DEPRECATED variables or functions."""
- deprecated = {}
+ def check_deprecated_variables(self, pkg, inherits: list[tuple[list[str], int]]):
+ """Check for usage of @DEPRECATED variables."""
# determine if any inherited eclasses have @DEPRECATED variables
- for eclasses, _ in inherits:
- for eclass in eclasses:
- for var in self.eclass_cache[eclass].variables:
- if var.deprecated:
- deprecated[var.name] = var.deprecated
+ deprecated = {
+ var.name: var.deprecated
+ for eclasses, _ in inherits
+ for eclass in eclasses
+ for var in self.eclass_cache[eclass].variables
+ if var.deprecated
+ }
# scan for usage of @DEPRECATED variables
if deprecated:
for node, _ in bash.var_query.captures(pkg.tree.root_node):
var_name = pkg.node_str(node)
- lineno, _colno = node.start_point
if var_name in deprecated:
+ lineno, _colno = node.start_point
line = pkg.node_str(node)
replacement = deprecated[var_name]
if not isinstance(replacement, str):
@@ -161,22 +181,23 @@ class EclassUsageCheck(Check):
var_name, replacement, line=line, lineno=lineno + 1, pkg=pkg
)
- def check_deprecated_functions(self, pkg, inherits):
- """Check for usage of @DEPRECATED variables or functions."""
- deprecated = {}
- # determine if any inherited eclasses have @DEPRECATED variables or functions
- for eclasses, _ in inherits:
- for eclass in eclasses:
- for func in self.eclass_cache[eclass].functions:
- if func.deprecated:
- deprecated[func.name] = func.deprecated
+ def check_deprecated_functions(self, pkg, inherits: list[tuple[list[str], int]]):
+ """Check for usage of @DEPRECATED functions."""
+ # determine if any inherited eclasses have @DEPRECATED functions
+ deprecated = {
+ func.name: func.deprecated
+ for eclasses, _ in inherits
+ for eclass in eclasses
+ for func in self.eclass_cache[eclass].functions
+ if func.deprecated
+ }
# scan for usage of @DEPRECATED functions
if deprecated:
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
func_name = pkg.node_str(node.child_by_field_name("name"))
- lineno, _colno = node.start_point
if func_name in deprecated:
+ lineno, _colno = node.start_point
line = pkg.node_str(node)
replacement = deprecated[func_name]
if not isinstance(replacement, str):
@@ -185,10 +206,22 @@ class EclassUsageCheck(Check):
func_name, replacement, line=line, lineno=lineno + 1, pkg=pkg
)
+ def check_provided_eclasses(self, pkg, inherits: list[tuple[list[str], int]]):
+ """Check for usage of eclasses (i.e. redundant inherits) that are
+ provided by another inherited eclass."""
+ provided_eclasses = {
+ provided: (eclass, lineno + 1)
+ for eclasses, lineno in inherits
+ for eclass in eclasses
+ for provided in pkg.inherit.intersection(self.eclass_cache[eclass].provides)
+ }
+ for provided, (eclass, lineno) in provided_eclasses.items():
+ yield ProvidedEclassInherit(eclass, pkg=pkg, line=provided, lineno=lineno)
+
def feed(self, pkg):
if pkg.inherit:
inherited = set()
- inherits = []
+ inherits: list[tuple[list[str], int]] = []
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
name = pkg.node_str(node.child_by_field_name("name"))
if name == "inherit":
@@ -207,6 +240,7 @@ class EclassUsageCheck(Check):
eclass, line=call, lineno=lineno + 1, pkg=pkg
)
+ yield from self.check_provided_eclasses(pkg, inherits)
# verify @PRE_INHERIT variable placement
yield from self.check_pre_inherits(pkg, inherits)
# verify @DEPRECATED variables or functions
@@ -281,7 +315,7 @@ class EclassParseCheck(Check):
for var_node, _ in bash.var_query.captures(func_node):
var_name = eclass.node_str(var_node)
if var_name in variables:
- lineno, colno = var_node.start_point
+ lineno, _colno = var_node.start_point
usage[var_name].add(lineno + 1)
for var, lines in sorted(usage.items()):
yield EclassVariableScope(
@@ -369,7 +403,12 @@ class EclassCheck(Check):
_source = sources.EclassRepoSource
known_results = frozenset(
- [EclassBashSyntaxError, EclassDocError, EclassDocMissingFunc, EclassDocMissingVar]
+ [
+ EclassBashSyntaxError,
+ EclassDocError,
+ EclassDocMissingFunc,
+ EclassDocMissingVar,
+ ]
)
def __init__(self, *args):
@@ -393,7 +432,7 @@ class EclassCheck(Check):
lineno = 0
error = []
for line in p.stderr.splitlines():
- path, line, msg = line.split(": ", 2)
+ _path, line, msg = line.split(": ", 2)
lineno = line[5:]
error.append(msg.strip("\n"))
error = ": ".join(error)
diff --git a/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/expected.json b/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/expected.json
new file mode 100644
index 00000000..397c0644
--- /dev/null
+++ b/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/expected.json
@@ -0,0 +1 @@
+{"__class__": "ProvidedEclassInherit", "category": "EclassUsageCheck", "package": "ProvidedEclassInherit", "version": "0", "line": "inherit", "lineno": 2, "provider": "deep-provided-inherit"}
diff --git a/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/fix.patch b/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/fix.patch
new file mode 100644
index 00000000..607e8caf
--- /dev/null
+++ b/testdata/data/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/fix.patch
@@ -0,0 +1,10 @@
+diff -Naur eclass/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild fixed/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild
+--- eclass/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild 2021-05-23 20:23:16.423009026 -0600
++++ fixed/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild 2021-05-23 20:23:43.734588313 -0600
+@@ -1,5 +1,5 @@
+ EAPI=7
+-inherit inherit deep-provided-inherit
++inherit deep-provided-inherit
+ DESCRIPTION="Ebuild inheriting provided eclass"
+ HOMEPAGE="https://github.com/pkgcore/pkgcheck"
+ SLOT="0"
diff --git a/testdata/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild b/testdata/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild
new file mode 100644
index 00000000..cd8585ea
--- /dev/null
+++ b/testdata/repos/eclass/EclassUsageCheck/ProvidedEclassInherit/ProvidedEclassInherit-0.ebuild
@@ -0,0 +1,11 @@
+EAPI=7
+inherit inherit deep-provided-inherit
+DESCRIPTION="Ebuild inheriting provided eclass"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck"
+SLOT="0"
+LICENSE="BSD"
+
+src_prepare() {
+ inherit_public_func
+ deep-provided-inherit_public_func
+}
next reply other threads:[~2023-01-02 20:19 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-02 20:19 Arthur Zamarin [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-11-22 21:35 [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, Michał Górny
2024-08-01 19:41 Arthur Zamarin
2023-09-23 15:10 Arthur Zamarin
2023-04-24 16:43 Arthur Zamarin
2023-02-03 13:03 Arthur Zamarin
2023-01-30 19:07 Arthur Zamarin
2023-01-18 5:19 Arthur Zamarin
2023-01-18 5:19 Arthur Zamarin
2023-01-14 20:29 Arthur Zamarin
2022-10-30 18:04 Arthur Zamarin
2022-10-13 17:06 Arthur Zamarin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1672690303.4247e10d9c266ac1f6aac48b0c67f1092dde1d78.arthurzam@gentoo \
--to=arthurzam@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox