Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

During docs builds, leave newsfragments unchanged #3086

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 55 additions & 9 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
from __future__ import annotations

import collections.abc
import glob
import os
import sys
import types
from pathlib import Path
from typing import TYPE_CHECKING, cast

if TYPE_CHECKING:
Expand All @@ -36,19 +38,62 @@
# Enable reloading with `typing.TYPE_CHECKING` being True
os.environ["SPHINX_AUTODOC_RELOAD_MODULES"] = "1"

# https://docs.readthedocs.io/en/stable/builds.html#build-environment
if "READTHEDOCS" in os.environ:
import glob

if glob.glob("../../newsfragments/*.*.rst"):
print("-- Found newsfragments; running towncrier --", flush=True)
import subprocess

# Handle writing newsfragments into the history file.
# We want to keep files unchanged when testing locally.
# So immediately revert the contents after running towncrier,
# then substitute when Sphinx wants to read it in.
history_file = Path("history.rst")

history_new: str | None
if glob.glob("../../newsfragments/*.*.rst"):
print("-- Found newsfragments; running towncrier --", flush=True)
history_orig = history_file.read_bytes()
import subprocess

# In case changes were staged, preserve indexed version.
# This grabs the hash of the current staged version.
history_staged = subprocess.run(
["git", "rev-parse", "--verify", ":docs/source/history.rst"],
check=True,
cwd="../..",
stdout=subprocess.PIPE,
encoding="ascii",
).stdout.strip()
try:
subprocess.run(
["towncrier", "--yes", "--date", "not released yet"],
["towncrier", "--keep", "--date", "not released yet"],
cwd="../..",
check=True,
)
history_new = history_file.read_text("utf8")
finally:
# Make sure this reverts even if a failure occurred.
# Restore whatever was staged.
print(f"Restoring history.rst = {history_staged}")
subprocess.run(
[
"git",
"update-index",
"--cacheinfo",
f"100644,{history_staged},docs/source/history.rst",
],
cwd="../..",
check=False,
)
# And restore the working copy.
history_file.write_bytes(history_orig)
del history_orig # We don't need this any more.
else:
# Leave it as is.
history_new = None


def on_read_source(app: Sphinx, docname: str, content: list[str]) -> None:
"""Substitute the modified history file."""
if docname == "history" and history_new is not None:
# This is a 1-item list with the file contents.
content[0] = history_new


# Sphinx is very finicky, and somewhat buggy, so we have several different
# methods to help it resolve links.
Expand Down Expand Up @@ -153,6 +198,7 @@ def setup(app: Sphinx) -> None:
app.connect("autodoc-process-signature", autodoc_process_signature)
# After Intersphinx runs, add additional mappings.
app.connect("builder-inited", add_intersphinx, priority=1000)
app.connect("source-read", on_read_source)


# -- General configuration ------------------------------------------------
Expand Down
Loading