commit:     4438566500fdf116ba36c3c407022e89541867d6
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 29 14:50:41 2023 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Tue Jan 31 16:17:53 2023 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=44385665

checks: Add a check for Python pkgnames matching PyPI

Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/534
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/python.py | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 510689bb..6965d2a9 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -24,6 +24,8 @@ GITHUB_ARCHIVE_RE = 
re.compile(r"^https://github\.com/[^/]+/[^/]+/archive/";)
 SNAPSHOT_RE = re.compile(r"[a-fA-F0-9]{40}\.tar\.gz$")
 USE_FLAGS_PYTHON_USEDEP = re.compile(r"\[(.+,)?\$\{PYTHON_USEDEP\}(,.+)?\]$")
 
+PEP503_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]")
+
 
 def get_python_eclass(pkg):
     eclasses = ECLASSES.intersection(pkg.inherited)
@@ -694,3 +696,48 @@ class PythonGHDistfileSuffixCheck(Check):
                 if GITHUB_ARCHIVE_RE.match(uri):
                     yield PythonGHDistfileSuffix(f.filename, uri, pkg=pkg)
                     break
+
+
+class PythonMismatchedPackageName(results.PackageResult, results.Info):
+    """Package name does not follow PyPI-based naming policy"""
+
+    def __init__(self, recommended: str, **kwargs):
+        super().__init__(**kwargs)
+        self.recommended = recommended
+
+    @property
+    def desc(self) -> str:
+        return ("package name does not match remote-id, recommended name: "
+                f"{self.recommended!r}")
+
+
+class PythonPackageNameCheck(Check):
+    """Check ebuild names in dev-python/*."""
+
+    _source = sources.PackageRepoSource
+    known_results = frozenset([PythonMismatchedPackageName])
+
+    def feed(self, pkgs):
+        pkg = next(iter(pkgs))
+
+        # the policy applies to dev-python/* only
+        if pkg.category != "dev-python":
+            return
+
+        # consider only packages with a single pypi remote-id
+        pypi_remotes = [x for x in pkg.upstreams if x.type == "pypi"]
+        if len(pypi_remotes) != 1:
+            return
+
+        def normalize(project: str) -> str:
+            """
+            Normalize project name using PEP 503 rules
+
+            https://peps.python.org/pep-0503/#normalized-names
+            """
+            return PEP503_SYMBOL_NORMALIZE_RE.sub("-", project).lower()
+
+        pypi_name = pypi_remotes[0].name
+        if normalize(pkg.package) != normalize(pypi_name):
+            yield PythonMismatchedPackageName(pypi_name.replace(".", "-"),
+                                              pkg=pkg)

Reply via email to