Skip to content

Commit

Permalink
During docs builds, leave newsfragments unchanged (#3086)
Browse files Browse the repository at this point in the history
* Undo towncrier changes when building docs

* Restore git index after towncrier run

* Add type annotation for history_new
  • Loading branch information
TeamSpen210 authored Sep 18, 2024
1 parent 7d81c27 commit b834f73
Showing 1 changed file with 55 additions and 9 deletions.
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

0 comments on commit b834f73

Please sign in to comment.