diff --git a/.readthedocs.yml b/.readthedocs.yml index 0c8f935d58c..b83ba05b128 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -6,6 +6,10 @@ build: os: ubuntu-22.04 tools: python: "3" + jobs: + post_checkout: + - git remote add upstream https://github.com/python-pillow/Pillow.git # For forks + - git fetch upstream --tags python: install: diff --git a/docs/conf.py b/docs/conf.py index 392cf317e5f..f12b30e65fb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,6 +28,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + "dater", "sphinx.ext.autodoc", "sphinx.ext.extlinks", "sphinx.ext.intersphinx", diff --git a/docs/dater.py b/docs/dater.py new file mode 100644 index 00000000000..f9fb0c1da6e --- /dev/null +++ b/docs/dater.py @@ -0,0 +1,48 @@ +""" +Sphinx extension to add timestamps to release notes based on Git versions. + +Based on https://github.com/jaraco/rst.linker, with thanks to Jason R. Coombs. +""" + +from __future__ import annotations + +import re +import subprocess +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from sphinx.application import Sphinx + +DOC_NAME_REGEX = re.compile(r"releasenotes/\d+\.\d+\.\d+") +VERSION_TITLE_REGEX = re.compile(r"^(\d+\.\d+\.\d+)\n-+\n") + + +def get_date_for(git_version: str) -> str | None: + cmd = ["git", "log", "-1", "--format=%ai", git_version] + try: + out = subprocess.check_output( + cmd, stderr=subprocess.DEVNULL, text=True, encoding="utf-8" + ) + except subprocess.CalledProcessError: + return None + return out.split()[0] + + +def add_date(app: Sphinx, doc_name: str, source: list[str]) -> None: + if DOC_NAME_REGEX.match(doc_name) and (m := VERSION_TITLE_REGEX.match(source[0])): + old_title = m.group(1) + + if tag_date := get_date_for(old_title): + new_title = f"{old_title} ({tag_date})" + else: + new_title = f"{old_title} (unreleased)" + + new_underline = "-" * len(new_title) + + result = source[0].replace(m.group(0), f"{new_title}\n{new_underline}\n", 1) + source[0] = result + + +def setup(app: Sphinx) -> dict[str, bool]: + app.connect("source-read", add_date) + return {"parallel_read_safe": True}