public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [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