|
102 | 102 | ERROR_UNABLE_PULL_REPO_EXAMPLES = "Unable to pull repository examples files"
|
103 | 103 | ERROR_NOT_ON_PYPI = "Not listed on PyPi for CPython use"
|
104 | 104 | ERROR_PYLINT_VERSION_NOT_FIXED = "PyLint version not fixed"
|
105 |
| -ERROR_PYLINT_VERSION_VERY_OUTDATED = "PyLint version very out of date" |
106 | 105 | ERROR_PYLINT_VERSION_NOT_LATEST = "PyLint version not latest"
|
107 | 106 | ERROR_NEW_REPO_IN_WORK = "New repo(s) currently in work, and unreleased"
|
108 | 107 |
|
@@ -156,7 +155,7 @@ class library_validator():
|
156 | 155 | def __init__(self, validators, bundle_submodules, latest_pylint, **kw_args):
|
157 | 156 | self.validators = validators
|
158 | 157 | self.bundle_submodules = bundle_submodules
|
159 |
| - self.latest_pylint = latest_pylint |
| 158 | + self.latest_pylint = latest_pylint.replace(".", "") |
160 | 159 | self.full_auth = None
|
161 | 160 | self.output_file_data = []
|
162 | 161 | self.github_token = kw_args.get("github_token", False)
|
@@ -372,41 +371,71 @@ def _validate_py_for_u_modules(self, repo, download_url):
|
372 | 371 |
|
373 | 372 | return errors
|
374 | 373 |
|
375 |
| - def _validate_travis_yml(self, repo, travis_yml_file_info): |
376 |
| - """DISABLED/NO LONGER CALLED: Check size and then check pypi compatibility. |
| 374 | + def _validate_actions_build_yml(self, repo, actions_build_info): |
| 375 | + """Check the following configurations in the GitHub Actions |
| 376 | + build.yml file: |
| 377 | + - Pylint version is the latest release |
377 | 378 | """
|
378 |
| - return [] |
379 | 379 |
|
380 |
| - download_url = travis_yml_file_info["download_url"] |
| 380 | + download_url = actions_build_info["download_url"] |
381 | 381 | contents = requests.get(download_url, timeout=30)
|
382 | 382 | if not contents.ok:
|
383 | 383 | return [ERROR_PYFILE_DOWNLOAD_FAILED]
|
384 | 384 |
|
385 | 385 | errors = []
|
386 | 386 |
|
387 |
| - lines = contents.text.split("\n") |
388 |
| - pypi_providers_lines = ( |
389 |
| - [l for l in lines |
390 |
| - if re.match(r"[\s]*-[\s]*provider:[\s]*pypi[\s]*", l)] |
| 387 | + pylint_version = None |
| 388 | + re_pip_pattern = r"pip\sinstall.*" |
| 389 | + re_pylint_pattern = ( |
| 390 | + r"pylint(?P<eval>(?:[<>~=]){0,2})(?P<major>\d*)(?P<minor>(?:\.\d){0,2})" |
391 | 391 | )
|
392 | 392 |
|
393 |
| - if not pypi_providers_lines: |
394 |
| - errors.append(ERROR_MISSING_PYPIPROVIDER) |
| 393 | + pip_line = re.search(re_pip_pattern, contents.text) |
| 394 | + if not pip_line: |
| 395 | + return [ERROR_PYLINT_VERSION_NOT_FIXED] |
| 396 | + |
| 397 | + pip_line = pip_line[0] |
| 398 | + |
| 399 | + pylint_info = re.search(re_pylint_pattern, pip_line) |
| 400 | + if not pylint_info: |
| 401 | + return [ERROR_PYLINT_VERSION_NOT_FIXED] |
| 402 | + |
| 403 | + if pylint_info.group("eval"): |
| 404 | + pylint_version = ( |
| 405 | + f"{pylint_info.group('major')}" |
| 406 | + f"{pylint_info.group('minor').replace('.', '')}" |
| 407 | + ) |
| 408 | + eval_func = pylint_info.group("eval") |
| 409 | + eval_len = len(pylint_version) |
| 410 | + |
| 411 | + if "<" in eval_func: |
| 412 | + eval_str = ( |
| 413 | + f"{self.latest_pylint[:eval_len]} " |
| 414 | + f"{eval_func} " |
| 415 | + f"{pylint_version}" |
| 416 | + ) |
| 417 | + elif "~" not in eval_func: |
| 418 | + eval_str = ( |
| 419 | + f"{pylint_version} " |
| 420 | + f"{eval_func} " |
| 421 | + f"{self.latest_pylint[:eval_len]}" |
| 422 | + ) |
| 423 | + else: |
| 424 | + return [ERROR_PYLINT_VERSION_NOT_FIXED] |
395 | 425 |
|
396 |
| - pylint_version = None |
397 |
| - for line in lines: |
398 |
| - if not line.strip().startswith("- pip install --force-reinstall pylint=="): |
399 |
| - continue |
400 |
| - pylint_version = line.split("=")[-1] |
| 426 | + else: |
| 427 | + pylint_version = self.latest_pylint |
| 428 | + eval_str = "True" |
| 429 | + |
| 430 | + #print( |
| 431 | + # f"{repo['name']}: pylint_version: {pylint_version} latest: {self.latest_pylint}\n" |
| 432 | + # f"{pylint_info.groups()} eval_str: {eval_str}" |
| 433 | + #) |
401 | 434 |
|
402 | 435 | if not pylint_version:
|
403 | 436 | errors.append(ERROR_PYLINT_VERSION_NOT_FIXED)
|
404 |
| - # disabling below for now, since we know all pylint versions are old |
405 |
| - # will re-enable once efforts are underway to update pylint |
406 |
| - #elif pylint_version.startswith("1."): |
407 |
| - # errors.append(ERROR_PYLINT_VERSION_VERY_OUTDATED) |
408 |
| - #elif pylint_version != self.latest_pylint: |
409 |
| - # errors.append(ERROR_PYLINT_VERSION_NOT_LATEST) |
| 437 | + elif not eval(eval_str): |
| 438 | + errors.append(ERROR_PYLINT_VERSION_NOT_LATEST) |
410 | 439 |
|
411 | 440 | return errors
|
412 | 441 |
|
@@ -506,6 +535,28 @@ def validate_contents(self, repo):
|
506 | 535 |
|
507 | 536 | if ".travis.yml" in files:
|
508 | 537 | errors.append(ERROR_NEEDS_ACTION_MIGRATION)
|
| 538 | + elif ".github" in files: |
| 539 | + # grab '.github' entry, extract URL, build new URL to build.yml, retrieve and pass |
| 540 | + build_yml_url = "" |
| 541 | + actions_build_info = None |
| 542 | + |
| 543 | + for item in content_list: |
| 544 | + if item.get("name") == ".github" and item.get("type") == "dir": |
| 545 | + build_yml_url = item["url"].split("?")[0] |
| 546 | + break |
| 547 | + |
| 548 | + if build_yml_url: |
| 549 | + build_yml_url = build_yml_url + "/workflows/build.yml" |
| 550 | + response = github.get(build_yml_url) |
| 551 | + if response.ok: |
| 552 | + actions_build_info = response.json() |
| 553 | + |
| 554 | + if actions_build_info: |
| 555 | + errors.extend( |
| 556 | + self._validate_actions_build_yml(repo, actions_build_info) |
| 557 | + ) |
| 558 | + else: |
| 559 | + errors.append(ERROR_UNABLE_PULL_REPO_CONTENTS) |
509 | 560 |
|
510 | 561 | if "readthedocs.yml" in files or ".readthedocs.yml" in files:
|
511 | 562 | fn = "readthedocs.yml"
|
|
0 commit comments