From 2703a9dc40186dbe68f0bf81578f16b2205c1525 Mon Sep 17 00:00:00 2001 From: Silke Hofstra Date: Wed, 6 May 2026 22:21:29 +0200 Subject: [PATCH] ci/package_checks: Add a check for installed licenses --- common/CI/package_checks.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/common/CI/package_checks.py b/common/CI/package_checks.py index 408e17afe1f9..8b1a9ae2311e 100755 --- a/common/CI/package_checks.py +++ b/common/CI/package_checks.py @@ -266,6 +266,7 @@ def _record(self) -> logging.LogRecord: class PullRequestCheck: _package_files = ['package.yml'] + _pspec_files = ['pspec_x86_64.xml'] _two_letter_dirs = ['py'] _config: Optional[Config] = None @@ -290,6 +291,10 @@ def config(self) -> Config: def package_files(self) -> List[str]: return self.filter_files(*self._package_files) + @property + def pspec_files(self) -> List[str]: + return self.filter_files(*self._pspec_files) + def filter_files(self, *allowed: str) -> List[str]: return [f for f in self.files if os.path.basename(f) in allowed] @@ -458,6 +463,26 @@ def _has_monitoring_yml(self, file: str) -> bool: return self._exists(os.path.join(os.path.dirname(file), 'monitoring.yaml')) +class License(PullRequestCheck): + _error = 'Package is missing license files' + _level = Level.WARNING + _globs = [ + '**/licenses/**', + '/usr/lib/python*/site-packages/*.dist-info/LICENSE', + ] + + def run(self) -> List[Result]: + return [Result(message=self._error, file=f, level=self._level) + for f in self.pspec_files + if not self._has_license(f)] + + def _has_license(self, file: str) -> bool: + return any(self._match_globs(f) for f in PspecXML(self._read(file)).files) + + def _match_globs(self, path: str) -> bool: + return any(fnmatch.fnmatch(path, pattern) for pattern in self._globs) + + class PackageBumped(PullRequestCheck): _msg = 'Package release is not incremented by 1' _msg_new = 'Package release is not 1' @@ -847,6 +872,7 @@ class Checker: FrozenPackage, Homepage, Monitoring, + License, PackageBumped, PackageDependenciesOrder, PackageDirectory,