|
33 | 33 | from pylint import lint
|
34 | 34 | from pylint.reporters import JSONReporter
|
35 | 35 | from sh.contrib import git
|
| 36 | +import yaml |
36 | 37 |
|
37 | 38 | from adabot import github_requests as github
|
38 | 39 | from adabot import pypi_requests as pypi
|
@@ -187,11 +188,45 @@ def __init__(self, validators, bundle_submodules, latest_pylint, keep_repos=Fals
|
187 | 188 | self.validators = validators
|
188 | 189 | self.bundle_submodules = bundle_submodules
|
189 | 190 | self.latest_pylint = pkg_version_parse(latest_pylint)
|
| 191 | + self._rtd_yaml_base = None |
190 | 192 | self.output_file_data = []
|
191 | 193 | self.validate_contents_quiet = kw_args.get("validate_contents_quiet", False)
|
192 | 194 | self.has_setup_py_disabled = set()
|
193 | 195 | self.keep_repos = keep_repos
|
194 | 196 |
|
| 197 | + |
| 198 | + @property |
| 199 | + def rtd_yml_base(self): |
| 200 | + """ The parsed YAML from `.readthedocs.yml` in the cookiecutter-adafruit-circuitpython repo. |
| 201 | + Used to verify that a library's `.readthedocs.yml` matches this version. |
| 202 | + """ |
| 203 | + if self._rtd_yaml_base is None: |
| 204 | + rtd_yml_dl_url = ( |
| 205 | + "https://raw.githubusercontent.com/adafruit/cookiecutter-adafruit-" |
| 206 | + "circuitpython/master/%7B%25%20if%20cookiecutter.library_prefix" |
| 207 | + "%20%25%7D%7B%7B%20cookiecutter.library_prefix%20%7C%20capitalize" |
| 208 | + "%20%7D%7D_%7B%25%20endif%20%25%7DCircuitPython_%7B%7B%20cookiecutter" |
| 209 | + ".library_name%7D%7D/%7B%25%20if%20cookiecutter.sphinx_docs%20in" |
| 210 | + "%20%5B'y'%2C%20'yes'%5D%20%25%7D.readthedocs.yml%7B%25%20endif" |
| 211 | + "%20%25%7D" |
| 212 | + ) |
| 213 | + rtd_yml = requests.get(rtd_yml_dl_url) |
| 214 | + if rtd_yml.ok: |
| 215 | + try: |
| 216 | + self._rtd_yaml_base = yaml.safe_load(rtd_yml.text) |
| 217 | + except yaml.YAMLError: |
| 218 | + print( |
| 219 | + "Error parsing cookiecutter .readthedocs.yml." |
| 220 | + ) |
| 221 | + self._rtd_yaml_base = "" |
| 222 | + else: |
| 223 | + print( |
| 224 | + "Error retrieving cookiecutter .readthedocs.yml" |
| 225 | + ) |
| 226 | + self._rtd_yaml_base = "" |
| 227 | + |
| 228 | + return self._rtd_yaml_base |
| 229 | + |
195 | 230 | def run_repo_validation(self, repo):
|
196 | 231 | """Run all the current validation functions on the provided repository and
|
197 | 232 | return their results as a list of string errors.
|
@@ -652,13 +687,22 @@ def validate_contents(self, repo):
|
652 | 687 | errors.append(ERROR_UNABLE_PULL_REPO_CONTENTS)
|
653 | 688 |
|
654 | 689 | if "readthedocs.yml" in files or ".readthedocs.yml" in files:
|
655 |
| - fn = "readthedocs.yml" |
656 |
| - if ".readthedocs.yml" in files: |
657 |
| - fn = ".readthedocs.yml" |
658 |
| - file_info = content_list[files.index(fn)] |
659 |
| - if (file_info["sha"] != "f4243ad548bc5e4431f2d3c5d486f6c9c863888b" and |
660 |
| - file_info["sha"] != "78a4671650248f4382e6eb72dab71c2d86824ca2"): |
661 |
| - errors.append(ERROR_MISMATCHED_READTHEDOCS) |
| 690 | + if self.rtd_yml_base != "": |
| 691 | + fn = "readthedocs.yml" |
| 692 | + if ".readthedocs.yml" in files: |
| 693 | + fn = ".readthedocs.yml" |
| 694 | + file_info = content_list[files.index(fn)] |
| 695 | + rtd_contents = requests.get(file_info["download_url"]) |
| 696 | + if rtd_contents.ok: |
| 697 | + try: |
| 698 | + rtd_yml = yaml.safe_load(rtd_contents.text) |
| 699 | + if rtd_yml != self.rtd_yml_base: |
| 700 | + errors.append(ERROR_MISMATCHED_READTHEDOCS) |
| 701 | + except yaml.YAMLError: |
| 702 | + self.output_file_data.append( |
| 703 | + "Error parsing {} .readthedocs.yml.".format(repo["name"]) |
| 704 | + ) |
| 705 | + errors.append(ERROR_OUTPUT_HANDLER) |
662 | 706 | else:
|
663 | 707 | errors.append(ERROR_MISSING_READTHEDOCS)
|
664 | 708 |
|
@@ -713,8 +757,6 @@ def __check_lib_name(repo_name, file_name):
|
713 | 757 | if name_rebuilt: # avoid adding things like 'simpletest.py' -> ''
|
714 | 758 | file_names.add(name_rebuilt)
|
715 | 759 |
|
716 |
| - found = False |
717 |
| - |
718 | 760 | return any(
|
719 | 761 | name.startswith(repo_name) for name in file_names
|
720 | 762 | )
|
@@ -742,15 +784,15 @@ def __check_lib_name(repo_name, file_name):
|
742 | 784 | errors.append(ERROR_MISSING_EXAMPLE_FOLDER)
|
743 | 785 |
|
744 | 786 | # first location .py files whose names begin with "adafruit_"
|
745 |
| - re_str = re.compile('adafruit\_[\w]*\.py') |
| 787 | + re_str = re.compile(r'adafruit\_[\w]*\.py') |
746 | 788 | pyfiles = ([x["download_url"] for x in content_list
|
747 | 789 | if re_str.fullmatch(x["name"])])
|
748 | 790 | for pyfile in pyfiles:
|
749 | 791 | # adafruit_xxx.py file; check if for proper usage of u___ versions of modules
|
750 | 792 | errors.extend(self._validate_py_for_u_modules(repo, pyfile))
|
751 | 793 |
|
752 | 794 | # now location any directories whose names begin with "adafruit_"
|
753 |
| - re_str = re.compile('adafruit\_[\w]*') |
| 795 | + re_str = re.compile(r'adafruit\_[\w]*') |
754 | 796 | for adir in dirs:
|
755 | 797 | if re_str.fullmatch(adir):
|
756 | 798 | # retrieve the files in that directory
|
|
0 commit comments