commit: 357f6104cb08913d840b749659096eeb2d0fa325 Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> AuthorDate: Thu Jan 12 20:40:27 2023 +0000 Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> CommitDate: Thu Jan 12 20:40:27 2023 +0000 URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=357f6104
EclassUsageCheck: check for setting user variables in ebuilds Check ebuilds for overriding eclass' user variables. Resolves: https://github.com/pkgcore/pkgcheck/issues/512 Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> src/pkgcheck/checks/eclass.py | 37 +++++++++++++++++++++- .../EclassUserVariableUsage/expected.json | 1 + .../EclassUserVariableUsage-0.ebuild | 12 +++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/pkgcheck/checks/eclass.py b/src/pkgcheck/checks/eclass.py index 862dbb91..935ed960 100644 --- a/src/pkgcheck/checks/eclass.py +++ b/src/pkgcheck/checks/eclass.py @@ -47,6 +47,18 @@ class DeprecatedEclassVariable(results.LineResult, results.Warning): return f"uses deprecated variable on line {self.lineno}: {self.variable} ({replacement})" +class EclassUserVariableUsage(results.LineResult, results.Warning): + """Package uses a user variable from an eclass.""" + + def __init__(self, eclass, **kwargs): + super().__init__(**kwargs) + self.eclass = eclass + + @property + def desc(self): + return f"line {self.lineno}: uses user variable {self.line!r} from eclass {self.eclass!r}" + + class DeprecatedEclassFunction(results.LineResult, results.Warning): """Package uses a deprecated function from an eclass.""" @@ -125,6 +137,7 @@ class EclassUsageCheck(Check): DeprecatedEclassVariable, DeprecatedEclassFunction, DuplicateEclassInherit, + EclassUserVariableUsage, MisplacedEclassVar, ProvidedEclassInherit, } @@ -156,6 +169,27 @@ class EclassUsageCheck(Check): line = pkg.node_str(node) yield MisplacedEclassVar(var_name, line=line, lineno=lineno + 1, pkg=pkg) + def check_user_variables(self, pkg: bash.ParseTree, inherits: list[tuple[list[str], int]]): + """Check for usage of @USER_VARIABLE variables.""" + # determine if any inherited eclasses have @USER_VARIABLE variables + user_variables = { + var.name: eclass + for eclasses, _ in inherits + for eclass in eclasses + for var in self.eclass_cache[eclass].variables + if var.user_variable + } + + # scan for usage of @USER_VARIABLE variables + if user_variables: + for node, _ in bash.var_assign_query.captures(pkg.tree.root_node): + var_name = pkg.node_str(node.child_by_field_name("name")) + if var_name in user_variables: + lineno, _colno = node.start_point + yield EclassUserVariableUsage( + user_variables[var_name], line=var_name, lineno=lineno + 1, pkg=pkg + ) + 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 @@ -220,7 +254,7 @@ class EclassUsageCheck(Check): def feed(self, pkg): if pkg.inherit: - inherited = set() + inherited: set[str] = set() 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")) @@ -241,6 +275,7 @@ class EclassUsageCheck(Check): ) yield from self.check_provided_eclasses(pkg, inherits) + yield from self.check_user_variables(pkg, inherits) # verify @PRE_INHERIT variable placement yield from self.check_pre_inherits(pkg, inherits) # verify @DEPRECATED variables or functions diff --git a/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json b/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json new file mode 100644 index 00000000..03b11f6a --- /dev/null +++ b/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json @@ -0,0 +1 @@ +{"__class__": "EclassUserVariableUsage", "category": "EclassUsageCheck", "package": "EclassUserVariableUsage", "version": "0", "line": "EBZR_STORE_DIR", "lineno": 8, "eclass": "unquotedvariable"} diff --git a/testdata/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/EclassUserVariableUsage-0.ebuild b/testdata/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/EclassUserVariableUsage-0.ebuild new file mode 100644 index 00000000..dae4c7d1 --- /dev/null +++ b/testdata/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/EclassUserVariableUsage-0.ebuild @@ -0,0 +1,12 @@ +EAPI=8 +inherit unquotedvariable +DESCRIPTION="Ebuild with user variable override" +HOMEPAGE="https://github.com/pkgcore/pkgcheck" +SLOT="0" +LICENSE="BSD" + +EBZR_STORE_DIR="/var/tmp/portage" # FAIL + +src_prepare() { + echo "${EBZR_STORE_DIR}" # ok +}