1 |
commit: 4438566500fdf116ba36c3c407022e89541867d6 |
2 |
Author: Michał Górny <mgorny <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Jan 29 14:50:41 2023 +0000 |
4 |
Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Jan 31 16:17:53 2023 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=44385665 |
7 |
|
8 |
checks: Add a check for Python pkgnames matching PyPI |
9 |
|
10 |
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org> |
11 |
Closes: https://github.com/pkgcore/pkgcheck/pull/534 |
12 |
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> |
13 |
|
14 |
src/pkgcheck/checks/python.py | 47 +++++++++++++++++++++++++++++++++++++++++++ |
15 |
1 file changed, 47 insertions(+) |
16 |
|
17 |
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py |
18 |
index 510689bb..6965d2a9 100644 |
19 |
--- a/src/pkgcheck/checks/python.py |
20 |
+++ b/src/pkgcheck/checks/python.py |
21 |
@@ -24,6 +24,8 @@ GITHUB_ARCHIVE_RE = re.compile(r"^https://github\.com/[^/]+/[^/]+/archive/") |
22 |
SNAPSHOT_RE = re.compile(r"[a-fA-F0-9]{40}\.tar\.gz$") |
23 |
USE_FLAGS_PYTHON_USEDEP = re.compile(r"\[(.+,)?\$\{PYTHON_USEDEP\}(,.+)?\]$") |
24 |
|
25 |
+PEP503_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]") |
26 |
+ |
27 |
|
28 |
def get_python_eclass(pkg): |
29 |
eclasses = ECLASSES.intersection(pkg.inherited) |
30 |
@@ -694,3 +696,48 @@ class PythonGHDistfileSuffixCheck(Check): |
31 |
if GITHUB_ARCHIVE_RE.match(uri): |
32 |
yield PythonGHDistfileSuffix(f.filename, uri, pkg=pkg) |
33 |
break |
34 |
+ |
35 |
+ |
36 |
+class PythonMismatchedPackageName(results.PackageResult, results.Info): |
37 |
+ """Package name does not follow PyPI-based naming policy""" |
38 |
+ |
39 |
+ def __init__(self, recommended: str, **kwargs): |
40 |
+ super().__init__(**kwargs) |
41 |
+ self.recommended = recommended |
42 |
+ |
43 |
+ @property |
44 |
+ def desc(self) -> str: |
45 |
+ return ("package name does not match remote-id, recommended name: " |
46 |
+ f"{self.recommended!r}") |
47 |
+ |
48 |
+ |
49 |
+class PythonPackageNameCheck(Check): |
50 |
+ """Check ebuild names in dev-python/*.""" |
51 |
+ |
52 |
+ _source = sources.PackageRepoSource |
53 |
+ known_results = frozenset([PythonMismatchedPackageName]) |
54 |
+ |
55 |
+ def feed(self, pkgs): |
56 |
+ pkg = next(iter(pkgs)) |
57 |
+ |
58 |
+ # the policy applies to dev-python/* only |
59 |
+ if pkg.category != "dev-python": |
60 |
+ return |
61 |
+ |
62 |
+ # consider only packages with a single pypi remote-id |
63 |
+ pypi_remotes = [x for x in pkg.upstreams if x.type == "pypi"] |
64 |
+ if len(pypi_remotes) != 1: |
65 |
+ return |
66 |
+ |
67 |
+ def normalize(project: str) -> str: |
68 |
+ """ |
69 |
+ Normalize project name using PEP 503 rules |
70 |
+ |
71 |
+ https://peps.python.org/pep-0503/#normalized-names |
72 |
+ """ |
73 |
+ return PEP503_SYMBOL_NORMALIZE_RE.sub("-", project).lower() |
74 |
+ |
75 |
+ pypi_name = pypi_remotes[0].name |
76 |
+ if normalize(pkg.package) != normalize(pypi_name): |
77 |
+ yield PythonMismatchedPackageName(pypi_name.replace(".", "-"), |
78 |
+ pkg=pkg) |