|
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