diff --git a/README.md b/README.md index 3e70fa4..d5beb39 100644 --- a/README.md +++ b/README.md @@ -23,34 +23,32 @@ of Sphinx we're using where: Sphinx configuration in various branches: - ========= ============= ============= ================== ================== - version travis azure requirements.txt conf.py - ========= ============= ============= ================== ================== - 2.7 sphinx~=2.0.1 ø ø needs_sphinx='1.2' - 3.5 sphinx==1.8.2 ø ø needs_sphinx='1.8' - 3.6 sphinx==1.8.2 sphinx==1.8.2 ø needs_sphinx='1.2' - 3.7 ø ø ø ø - 3.8 ø ø sphinx==2.4.4 needs_sphinx='1.8' - 3.9 ø ø sphinx==2.4.4 needs_sphinx='1.8' - 3.1 ø ø sphinx==3.4.3 needs_sphinx='3.2' - 3.11 ø ø sphinx==4.5.0 needs_sphinx='4.2' - 3.12 ø ø sphinx==4.5.0 needs_sphinx='4.2' - 3.13 ø ø sphinx==6.2.1 needs_sphinx='4.2' - ========= ============= ============= ================== ================== + ========= ============= ================== ==================== + version travis requirements.txt conf.py + ========= ============= ================== ==================== + 2.7 sphinx~=2.0.1 ø needs_sphinx='1.2' + 3.5 sphinx==1.8.2 ø needs_sphinx='1.8' + 3.6 sphinx==1.8.2 ø needs_sphinx='1.2' + 3.7 sphinx==1.8.2 sphinx==2.3.1 needs_sphinx="1.6.6" + 3.8 ø sphinx==2.4.4 needs_sphinx='1.8' + 3.9 ø sphinx==2.4.4 needs_sphinx='1.8' + 3.10 ø sphinx==3.4.3 needs_sphinx='3.2' + 3.11 ø sphinx~=7.2.0 needs_sphinx='4.2' + 3.12 ø sphinx~=8.0.0 needs_sphinx='6.2.1' + 3.13 ø sphinx~=8.0.0 needs_sphinx='6.2.1' + 3.14 ø sphinx~=8.0.0 needs_sphinx='6.2.1' + ========= ============= ================== ==================== Sphinx build as seen on docs.python.org: ========= ===== ===== ===== ===== ===== ===== ===== ===== ======= ===== ===== ======= ======= version en es fr id it ja ko pl pt-br tr uk zh-cn zh-tw ========= ===== ===== ===== ===== ===== ===== ===== ===== ======= ===== ===== ======= ======= - 2.7 ø 2.3.1 ø 2.3.1 2.3.1 ø 2.3.1 2.3.1 ø 2.3.1 2.3.1 ø 2.3.1 - 3.5 ø 1.8.4 1.8.4 1.8.4 1.8.4 ø 1.8.4 1.8.4 ø 1.8.4 1.8.4 1.8.4 1.8.4 - 3.6 ø 2.3.1 2.3.1 2.3.1 2.3.1 ø 2.3.1 2.3.1 ø 2.3.1 2.3.1 2.3.1 2.3.1 - 3.7 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 2.3.1 3.8 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 3.9 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 2.4.4 3.10 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 3.4.3 - 3.11 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 - 3.12 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 4.5.0 - 3.13 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 6.2.1 + 3.11 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 7.2.6 + 3.12 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 + 3.13 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 + 3.14 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 8.0.2 ========= ===== ===== ===== ===== ===== ===== ===== ===== ======= ===== ===== ======= ======= diff --git a/build_docs.py b/build_docs.py index 212989e..93dcac4 100755 --- a/build_docs.py +++ b/build_docs.py @@ -1079,7 +1079,9 @@ def parse_versions_from_devguide(): "python/devguide/main/include/release-cycle.json", timeout=30, ).json() - return [Version.from_json(name, release) for name, release in releases.items()] + versions = [Version.from_json(name, release) for name, release in releases.items()] + versions.sort(key=Version.as_tuple) + return versions def parse_languages_from_config(): diff --git a/check_versions.py b/check_versions.py index 630eb6e..a1900c3 100644 --- a/check_versions.py +++ b/check_versions.py @@ -13,6 +13,8 @@ import build_docs logger = logging.getLogger(__name__) +VERSIONS = build_docs.parse_versions_from_devguide() +LANGUAGES = build_docs.parse_languages_from_config() def parse_args(): @@ -24,102 +26,107 @@ def parse_args(): return parser.parse_args() -def remote_by_url(repo: git.Repo, url_pattern: str): +def find_upstream_remote_name(repo: git.Repo) -> str: """Find a remote of repo matching the regex url_pattern.""" for remote in repo.remotes: for url in remote.urls: - if re.search(url_pattern, url): - return remote + if "github.com/python" in url: + return f"{remote.name}/" def find_sphinx_spec(text: str): if found := re.search( - """sphinx[=<>~]{1,2}[0-9.]{3,}|needs_sphinx = [0-9.'"]*""", text, flags=re.I + """sphinx[=<>~]{1,2}[0-9.]{3,}|needs_sphinx = [0-9.'"]*""", + text, + flags=re.IGNORECASE, ): return found.group(0).replace(" ", "") return "ø" -def find_sphinx_in_file(repo: git.Repo, branch, filename): - upstream = remote_by_url(repo, "github.com.python").name - # Just in case you don't use origin/: - branch = branch.replace("origin/", upstream + "/") - try: - return find_sphinx_spec(repo.git.show(f"{branch}:{filename}")) - except git.exc.GitCommandError: - return "ø" +def find_sphinx_in_files(repo: git.Repo, branch_or_tag, filenames): + upstream = find_upstream_remote_name(repo) + # Just in case you don't use upstream/: + branch_or_tag = branch_or_tag.replace("upstream/", upstream) + specs = [] + for filename in filenames: + try: + blob = repo.git.show(f"{branch_or_tag}:{filename}") + except git.exc.GitCommandError: + specs.append("ø") + else: + specs.append(find_sphinx_spec(blob)) + return specs CONF_FILES = { "travis": ".travis.yml", - "azure": ".azure-pipelines/docs-steps.yml", "requirements.txt": "Doc/requirements.txt", "conf.py": "Doc/conf.py", } -def search_sphinx_versions_in_cpython(repo: git.Repo): - repo.git.fetch("https://github.com/python/cpython") - table = [] - for version in sorted(build_docs.VERSIONS): - table.append( - [ - version.name, - *[ - find_sphinx_in_file(repo, version.branch_or_tag, filename) - for filename in CONF_FILES.values() - ], - ] - ) - print(tabulate(table, headers=["version", *CONF_FILES.keys()], tablefmt="rst")) +def branch_or_tag_for(version): + if version.status == "EOL": + return f"tags/{version.branch_or_tag}" + return f"upstream/{version.branch_or_tag}" -async def get_version_in_prod(language, version): - url = f"https://docs.python.org/{language}/{version}/".replace("/en/", "/") +def search_sphinx_versions_in_cpython(repo: git.Repo): + repo.git.fetch("https://github.com/python/cpython") + filenames = CONF_FILES.values() + table = [ + [ + version.name, + *find_sphinx_in_files(repo, branch_or_tag_for(version), filenames), + ] + for version in VERSIONS + ] + headers = ["version", *CONF_FILES.keys()] + print(tabulate(table, headers=headers, tablefmt="rst", disable_numparse=True)) + + +async def get_version_in_prod(language: str, version: str) -> str: + if language == "en": + url = f"https://docs.python.org/{version}/" + else: + url = f"https://docs.python.org/{language}/{version}/" async with httpx.AsyncClient() as client: try: - response = await client.get(url, timeout=10) + response = await client.get(url, timeout=5) except httpx.ConnectTimeout: return "(timeout)" - text = response.text.encode("ASCII", errors="ignore").decode("ASCII") + # Python 2.6--3.7: sphinx.pocoo.org + # from Python 3.8: www.sphinx-doc.org if created_using := re.search( - r"(?:sphinx.pocoo.org|www.sphinx-doc.org).*?([0-9.]+[0-9])", text, flags=re.M + r"(?:sphinx.pocoo.org|www.sphinx-doc.org).*?([0-9.]+[0-9])", response.text ): return created_using.group(1) return "ø" async def which_sphinx_is_used_in_production(): - table = [] - for version in sorted(build_docs.VERSIONS): - table.append( - [ - version.name, - *await asyncio.gather( - *[ - get_version_in_prod(language.tag, version.name) - for language in build_docs.LANGUAGES - ] - ), - ] - ) - print( - tabulate( - table, - disable_numparse=True, - headers=[ - "version", - *[language.tag for language in sorted(build_docs.LANGUAGES)], - ], - tablefmt="rst", - ) - ) + table = [ + [ + version.name, + *await asyncio.gather( + *[ + get_version_in_prod(language.tag, version.name) + for language in LANGUAGES + ] + ), + ] + for version in VERSIONS + ] + headers = ["version", *[language.tag for language in LANGUAGES]] + print(tabulate(table, headers=headers, tablefmt="rst", disable_numparse=True)) def main(): logging.basicConfig(level=logging.INFO) logging.getLogger("charset_normalizer").setLevel(logging.WARNING) logging.getLogger("asyncio").setLevel(logging.WARNING) + logging.getLogger("httpx").setLevel(logging.WARNING) args = parse_args() repo = git.Repo(args.cpython_clone) print("Sphinx configuration in various branches:", end="\n\n")