* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/, ...
@ 2023-03-04 5:59 Arthur Zamarin
0 siblings, 0 replies; only message in thread
From: Arthur Zamarin @ 2023-03-04 5:59 UTC (permalink / raw
To: gentoo-commits
commit: d1e4aef5532f1d407169e7f53d6816ca7ba2da82
Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 2 20:20:50 2023 +0000
Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Fri Mar 3 05:49:43 2023 +0000
URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d1e4aef5
EbuildReservedCheck: check for semi-reserved names
Resolves: https://github.com/pkgcore/pkgcheck/issues/536
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>
src/pkgcheck/bash/__init__.py | 5 +--
src/pkgcheck/checks/reserved.py | 48 +++++++++++++++++++---
.../EbuildSemiReservedName/expected.json | 5 +++
.../EbuildSemiReservedName-0.ebuild | 13 ++++++
4 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/src/pkgcheck/bash/__init__.py b/src/pkgcheck/bash/__init__.py
index bff1a94d..70040981 100644
--- a/src/pkgcheck/bash/__init__.py
+++ b/src/pkgcheck/bash/__init__.py
@@ -1,6 +1,5 @@
"""bash parsing support"""
-from functools import partial
import os
from snakeoil.osutils import pjoin
@@ -100,7 +99,7 @@ except ImportError: # pragma: no cover
if syslib is not None or os.path.exists(lib):
lang = Language(syslib or lib, "bash")
- query = partial(lang.query)
+ query = lang.query
parser = Parser()
parser.set_language(lang)
@@ -114,7 +113,7 @@ if syslib is not None or os.path.exists(lib):
class ParseTree:
"""Bash parse tree object and support."""
- def __init__(self, data, **kwargs):
+ def __init__(self, data: bytes, **kwargs):
super().__init__(**kwargs)
self.data = data
self.tree = parser.parse(data)
diff --git a/src/pkgcheck/checks/reserved.py b/src/pkgcheck/checks/reserved.py
index a67d1683..f99a9050 100644
--- a/src/pkgcheck/checks/reserved.py
+++ b/src/pkgcheck/checks/reserved.py
@@ -1,4 +1,5 @@
import re
+import string
from pkgcore.ebuild.eapi import EAPI
@@ -22,7 +23,7 @@ class _ReservedNameCheck(Check):
"""Approved good exceptions to using of variables."""
variables_usage_whitelist = {"EBUILD_PHASE", "EBUILD_PHASE_FUNC"}
- def _check(self, used_type: str, used_names):
+ def _check(self, used_type: str, used_names: dict[str, tuple[int, int]]):
for used_name, (lineno, _) in used_names.items():
if used_name in self.special_whitelist:
continue
@@ -36,7 +37,7 @@ class _ReservedNameCheck(Check):
if self.reserved_ebuild_regex.match(test_name):
yield used_name, used_type, "ebuild", "substring", lineno + 1
- def _feed(self, item):
+ def _feed(self, item: bash.ParseTree):
yield from self._check(
"function",
{
@@ -82,7 +83,7 @@ class EclassReservedCheck(_ReservedNameCheck):
super().__init__(*args)
self.eclass_cache = eclass_addon.eclasses
- def feed(self, eclass):
+ def feed(self, eclass: sources._ParsedEclass):
for *args, _ in self._feed(eclass):
yield EclassReservedName(*args, eclass=eclass.name)
@@ -101,11 +102,34 @@ class EbuildReservedName(results.LineResult, results.Warning):
return f'line {self.lineno}: {self.used_type} name "{self.line}" is disallowed because "{self.reserved_word}" is a reserved {self.reserved_type}'
+class EbuildSemiReservedName(results.LineResult, results.Warning):
+ """Ebuild uses semi-reserved variable or function name.
+
+ Ebuild is using in global scope semi-reserved variable or function names,
+ which is likely to clash with future EAPIs. Currently it include
+ single-letter uppercase variables, and ``[A-Z]DEPEND`` variables.
+ """
+
+ def __init__(self, used_type: str, **kwargs):
+ super().__init__(**kwargs)
+ self.used_type = used_type
+
+ @property
+ def desc(self):
+ return f'line {self.lineno}: uses semi-reserved {self.used_type} name "{self.line}", likely to clash with future EAPIs'
+
+
class EbuildReservedCheck(_ReservedNameCheck):
"""Scan ebuilds for reserved function or variable names."""
_source = sources.EbuildParseRepoSource
- known_results = frozenset([EbuildReservedName])
+ known_results = frozenset({EbuildReservedName, EbuildSemiReservedName})
+
+ global_reserved = (
+ frozenset(string.ascii_uppercase)
+ .union(c + "DEPEND" for c in string.ascii_uppercase)
+ .difference(("CDEPEND",))
+ )
def __init__(self, options, **kwargs):
super().__init__(options, **kwargs)
@@ -116,7 +140,7 @@ class EbuildReservedCheck(_ReservedNameCheck):
for eapi_name, eapi in EAPI.known_eapis.items()
}
- def feed(self, pkg):
+ def feed(self, pkg: sources._ParsedPkg):
for used_name, *args, lineno in self._feed(pkg):
yield EbuildReservedName(*args, lineno=lineno, line=used_name, pkg=pkg)
@@ -127,3 +151,17 @@ class EbuildReservedCheck(_ReservedNameCheck):
yield EbuildReservedName(
"function", used_name, "phase hook", lineno=lineno + 1, line=used_name, pkg=pkg
)
+
+ current_global_reserved = self.global_reserved.difference(
+ pkg.eapi.eclass_keys, pkg.eapi.dep_keys
+ )
+ for node in pkg.global_query(bash.var_assign_query):
+ used_name = pkg.node_str(node.child_by_field_name("name"))
+ if used_name in current_global_reserved:
+ lineno, _ = node.start_point
+ yield EbuildSemiReservedName(
+ "variable",
+ lineno=lineno + 1,
+ line=used_name,
+ pkg=pkg,
+ )
diff --git a/testdata/data/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/expected.json b/testdata/data/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/expected.json
new file mode 100644
index 00000000..c5916b53
--- /dev/null
+++ b/testdata/data/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/expected.json
@@ -0,0 +1,5 @@
+{"__class__": "EbuildSemiReservedName", "category": "DependencyCheck", "package": "MisplacedWeakBlocker", "version": "6", "line": "BDEPEND", "lineno": 8, "used_type": "variable"}
+{"__class__": "EbuildSemiReservedName", "category": "DependencyCheck", "package": "MisplacedWeakBlocker", "version": "6", "line": "IDEPEND", "lineno": 12, "used_type": "variable"}
+{"__class__": "EbuildSemiReservedName", "category": "DependencyCheck", "package": "MisplacedWeakBlocker", "version": "7", "line": "IDEPEND", "lineno": 12, "used_type": "variable"}
+{"__class__": "EbuildSemiReservedName", "category": "EbuildReservedCheck", "package": "EbuildSemiReservedName", "version": "0", "line": "B", "lineno": 9, "used_type": "variable"}
+{"__class__": "EbuildSemiReservedName", "category": "EbuildReservedCheck", "package": "EbuildSemiReservedName", "version": "0", "line": "TDEPEND", "lineno": 13, "used_type": "variable"}
diff --git a/testdata/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/EbuildSemiReservedName-0.ebuild b/testdata/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/EbuildSemiReservedName-0.ebuild
new file mode 100644
index 00000000..846fbb03
--- /dev/null
+++ b/testdata/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/EbuildSemiReservedName-0.ebuild
@@ -0,0 +1,13 @@
+EAPI=8
+
+DESCRIPTION="Ebuild with semi-reserved names"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck"
+SLOT="0"
+LICENSE="BSD"
+
+S=${WORKDIR} # ok
+B=${WORKDIR} # fail
+BDEPEND="app-arch/unzip" # ok
+CDEPEND="app-arch/unzip" # ok
+RDEPEND="${CDEPEND}" # ok
+TDEPEND="app-arch/unzip" # fail
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2023-03-04 5:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-04 5:59 [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/standalone/EbuildReservedCheck/EbuildSemiReservedName/, Arthur Zamarin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox