def validate_readthedocs(self, repo): if not (repo["owner"]["login"] == "adafruit" and repo["name"].startswith("Adafruit_CircuitPython")): return [] if repo["name"] in BUNDLE_IGNORE_LIST: return [] global rtd_subprojects if not rtd_subprojects: rtd_response = requests.get( "https://readthedocs.org/api/v2/project/74557/subprojects/", timeout=15) if not rtd_response.ok: return [ERROR_RTD_SUBPROJECT_FAILED] rtd_subprojects = {} for subproject in rtd_response.json()["subprojects"]: rtd_subprojects[common_funcs.sanitize_url( subproject["repo"])] = subproject repo_url = common_funcs.sanitize_url(repo["clone_url"]) if repo_url not in rtd_subprojects: return [ERROR_RTD_SUBPROJECT_MISSING] errors = [] subproject = rtd_subprojects[repo_url] if 105398 not in subproject["users"]: errors.append(ERROR_RTD_ADABOT_MISSING) valid_versions = requests.get( "https://readthedocs.org/api/v2/project/{}/active_versions/". format(subproject["id"]), timeout=15) if not valid_versions.ok: errors.append(ERROR_RTD_VALID_VERSIONS_FAILED) else: valid_versions = valid_versions.json() latest_release = github.get("/repos/{}/releases/latest".format( repo["full_name"])) if not latest_release.ok: errors.append(ERROR_GITHUB_RELEASE_FAILED) # disabling this for now, since it is ignored and always fails #else: # if latest_release.json()["tag_name"] not in [tag["verbose_name"] for tag in valid_versions["versions"]]: # errors.append(ERROR_RTD_MISSING_LATEST_RELEASE) # There is no API which gives access to a list of builds for a project so we parse the html # webpage. builds_webpage = requests.get( "https://readthedocs.org/projects/{}/builds/".format( subproject["slug"]), timeout=15) if not builds_webpage.ok: errors.append(ERROR_RTD_FAILED_TO_LOAD_BUILDS) else: for line in builds_webpage.text.split("\n"): if "<div id=\"build-" in line: build_id = line.split("\"")[1][len("build-"):] # We only validate the most recent, latest build. So, break when the first "version # latest" found. Its in the page after the build id. if "version latest" in line: break build_info = requests.get( "https://readthedocs.org/api/v2/build/{}/".format(build_id), timeout=15) if not build_info.ok: errors.append(ERROR_RTD_FAILED_TO_LOAD_BUILD_INFO) else: build_info = build_info.json() output_ok = True autodoc_ok = True sphinx_ok = True for command in build_info["commands"]: if command["command"].endswith("_build/html"): for line in command["output"].split("\n"): if "... " in line: _, line = line.split("... ") if "WARNING" in line or "ERROR" in line: if not line.startswith(("WARNING", "ERROR")): line = line.split(" ", 1)[1] if not line.startswith(RTD_IGNORE_NOTICES): output_ok = False elif line.startswith("ImportError"): autodoc_ok = False elif line.startswith( "sphinx.errors") or line.startswith( "SphinxError"): sphinx_ok = False break if not output_ok: errors.append(ERROR_RTD_OUTPUT_HAS_WARNINGS) if not autodoc_ok: errors.append(ERROR_RTD_AUTODOC_FAILED) if not sphinx_ok: errors.append(ERROR_RTD_SPHINX_FAILED) return errors
def test_comparing_different_urls(self): test_a = common_funcs.sanitize_url('http://foo.bar/fooba.git') test_b = common_funcs.sanitize_url('http://foo.bar/foobar') self.assertNotEqual(test_a, test_b)