From 61cb80844ce63678c597bcc079edb8652cf8decb Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Mon, 21 Sep 2026 20:33:54 -0400 Subject: [PATCH 1/3] build: Create the current_lang symlink in conf.py, not in the Makefile `setup()` already writes into `build//`, so it can create the symlink beside it, and remove it once the build finishes. This drops the Make prerequisite from every build, extract and linkcheck target. include/common.mk is synced from standard_profile_template, where the same change is on the `current-lang` branch. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01UAeUtu5XGYmmSwtyjVU7gL (cherry picked from commit a24d2b192c40648b0e40bc113fe9cb68a5d32856) (cherry picked from commit f83e559f9769b9738d1a4b69bfd56a3b64a3974f) --- docs/conf.py | 7 +++++++ include/common.mk | 35 +++++++++++------------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ce755efa9..a43601430 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -132,6 +132,13 @@ def setup(app): standard_dir = basedir / "schema" standard_build_dir = basedir / "build" / language + # `build/current_lang` paths in directives resolve to the language being built. + standard_build_dir.parent.mkdir(parents=True, exist_ok=True) + current_lang = standard_build_dir.parent / "current_lang" + current_lang.unlink(missing_ok=True) + current_lang.symlink_to(language) + app.connect("build-finished", lambda *args: current_lang.unlink(missing_ok=True)) + branch = os.getenv("GITHUB_REF_NAME", "latest") translate( diff --git a/include/common.mk b/include/common.mk index 12a9c619b..f66e69026 100644 --- a/include/common.mk +++ b/include/common.mk @@ -47,11 +47,11 @@ extract_schema: $(POT_DIR) # directives to succeed, but the contents of the files have no effect on the generated .pot files. # See https://www.sphinx-doc.org/en/master/usage/builders/index.html#sphinx.builders.gettext.MessageCatalogBuilder .PHONY: extract_markdown -extract_markdown: current_lang.en +extract_markdown: sphinx-build -nW --keep-going -q -b gettext $(DOCS_DIR) $(POT_DIR) .PHONY: extract -extract: extract_theme extract_codelists extract_schema $(EXTRACT_TARGETS) extract_markdown clean_current_lang +extract: extract_theme extract_codelists extract_schema $(EXTRACT_TARGETS) extract_markdown $(TRANSLATIONS:.%=docs/locale/%): docs/locale/%: FORCE sphinx-intl update -p $(POT_DIR) -d $(LOCALE_DIR) -l "$*" @@ -63,43 +63,30 @@ docs/locale: $(TRANSLATIONS:.%=docs/locale/%) pocount: find $(LOCALE_DIR) -name LC_MESSAGES -exec pocount --incomplete --short "{}" + -### Current language - -# Create a symlink for the language, so that file paths in `jsonschema` directives resolve. -# (Don't use clean_current_lang as a prerequisite, as then it won't run as a prerequisite later.) -$(LANGUAGES:.%=current_lang.%): current_lang.%: $(BUILD_DIR) - rm -f $(BUILD_DIR)/current_lang - ln -s $* $(BUILD_DIR)/current_lang - -# Deploy script complains if current_lang is present. -.PHONY: clean_current_lang -clean_current_lang: - rm $(BUILD_DIR)/current_lang - ### Build # Build the source documentation. # See https://www.sphinx-doc.org/en/master/usage/builders/index.html#sphinx.builders.html.DirectoryHTMLBuilder .PHONY: build_source -build_source: current_lang.en +build_source: sphinx-build -nW --keep-going -q -b dirhtml $(DOCS_DIR) $(BUILD_DIR)/en # Build the translated documentation. (Same as source, but with a language configuration setting.) -$(TRANSLATIONS:.%=build.%): build.%: current_lang.% +$(TRANSLATIONS:.%=build.%): build.%: sphinx-build -nW --keep-going -q -b dirhtml $(DOCS_DIR) $(BUILD_DIR)/$* -D language="$*" .PHONY: source -source: build_source clean_current_lang +source: build_source -$(TRANSLATIONS:.%=%): %: build_source compile build.% clean_current_lang +$(TRANSLATIONS:.%=%): %: build_source compile build.% .PHONY: all -all: build_source compile $(TRANSLATIONS:.%=build.%) clean_current_lang +all: build_source compile $(TRANSLATIONS:.%=build.%) ### Development .PHONY: autobuild -autobuild: current_lang.en +autobuild: sphinx-autobuild $(SPHINX_AUTOBUILD_EXTRA_ARGS) -nW -q -b dirhtml $(DOCS_DIR) $(BUILD_DIR)/en .PHONY: update @@ -111,14 +98,14 @@ update: clean_dist # "-" ignores the exit status. Schema files might contain old URLs that redirect, which can only be updated in a new version. .PHONY: linkcheck_source -linkcheck_source: current_lang.en +linkcheck_source: -sphinx-build -q -b linkcheck $(DOCS_DIR) $(BUILD_DIR)/en -$(TRANSLATIONS:.%=linkcheck.%): linkcheck.%: current_lang.% +$(TRANSLATIONS:.%=linkcheck.%): linkcheck.%: -sphinx-build -q -b linkcheck $(DOCS_DIR) $(BUILD_DIR)/$* -D language="$*" .PHONY: linkcheck -linkcheck: linkcheck_source compile $(TRANSLATIONS:.%=linkcheck.%) clean_current_lang +linkcheck: linkcheck_source compile $(TRANSLATIONS:.%=linkcheck.%) ### PDF generation From fd099d45f98eb08f281638cd0d3b1bf67a928beb Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Mon, 21 Sep 2026 21:18:09 -0400 Subject: [PATCH 2/3] build: Compile the schema and codelists catalogs in conf.py, not in the Makefile `setup()` already reads the compiled catalogs through `translate`, and knows which language is being built, so it can compile that language's catalogs first. The Makefile compiled every language's up front. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01UAeUtu5XGYmmSwtyjVU7gL (cherry picked from commit 2437a3b43408225ae87a6e5c2a1a3053c85afc70) (cherry picked from commit 9330aaed88020d6a7f21ccd035a938edcb92835f) --- docs/conf.py | 16 ++++++++++++++++ include/config.mk | 4 +--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index a43601430..a696235db 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,6 +9,8 @@ from glob import glob from pathlib import Path +from babel.messages.mofile import write_mo +from babel.messages.pofile import read_po from docutils.nodes import make_id from ocds_babel.translate import translate from ocdskit.mapping_sheet import mapping_sheet @@ -115,6 +117,16 @@ ] +def compile_catalogs(localedir, language, domains): + """Compile the catalogs that `translate` reads, as `pybabel compile --use-fuzzy` does.""" + for domain in domains: + path = localedir / language / "LC_MESSAGES" / f"{domain}.po" + with path.open() as f: + catalog = read_po(f, locale=language, domain=domain) + with path.with_suffix(".mo").open("wb") as f: + write_mo(f, catalog, use_fuzzy=True) + + def setup(app): # The root of the repository. basedir = Path(__file__).resolve().parents[1] @@ -141,6 +153,10 @@ def setup(app): branch = os.getenv("GITHUB_REF_NAME", "latest") + # English is the source language, and has no catalogs. + if language != "en": + compile_catalogs(localedir, language, (schema_domain, codelists_domain)) + translate( [ # The glob patterns in `babel_ocds_schema.cfg` should match these filenames. diff --git a/include/config.mk b/include/config.mk index 9bca0278f..ee210c975 100644 --- a/include/config.mk +++ b/include/config.mk @@ -32,10 +32,8 @@ PDF_PAGES={,primer/{,what/,how/,releases_and_records/,next/},guidance/{,design/, # be an indication of an iframe taking too long to load." PDF_DELAY=20000 -# Compile PO files for codelists and schema to MO files, so that `translate` succeeds. +# Empty: `docs/conf.py` compiles the schema and codelists catalogs that `translate` reads. .PHONY: compile compile: - pybabel compile --use-fuzzy -d $(LOCALE_DIR) -D $(DOMAIN_PREFIX)schema - pybabel compile --use-fuzzy -d $(LOCALE_DIR) -D $(DOMAIN_PREFIX)codelists # Put local targets below. From 3babaf7b40f1f72e054e673c0e8eb2619458134d Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Fri, 9 Oct 2026 10:50:22 -0400 Subject: [PATCH 3/3] build: Drop the compile hook, now that conf.py compiles the catalogs include/common.mk is synced from standard_profile_template, where the same change is on the `current-lang` branch. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01UAeUtu5XGYmmSwtyjVU7gL --- include/common.mk | 6 +++--- include/config.mk | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/common.mk b/include/common.mk index f66e69026..f82f2f3a3 100644 --- a/include/common.mk +++ b/include/common.mk @@ -78,10 +78,10 @@ $(TRANSLATIONS:.%=build.%): build.%: .PHONY: source source: build_source -$(TRANSLATIONS:.%=%): %: build_source compile build.% +$(TRANSLATIONS:.%=%): %: build_source build.% .PHONY: all -all: build_source compile $(TRANSLATIONS:.%=build.%) +all: build_source $(TRANSLATIONS:.%=build.%) ### Development @@ -105,7 +105,7 @@ $(TRANSLATIONS:.%=linkcheck.%): linkcheck.%: -sphinx-build -q -b linkcheck $(DOCS_DIR) $(BUILD_DIR)/$* -D language="$*" .PHONY: linkcheck -linkcheck: linkcheck_source compile $(TRANSLATIONS:.%=linkcheck.%) +linkcheck: linkcheck_source $(TRANSLATIONS:.%=linkcheck.%) ### PDF generation diff --git a/include/config.mk b/include/config.mk index ee210c975..113f91822 100644 --- a/include/config.mk +++ b/include/config.mk @@ -32,8 +32,4 @@ PDF_PAGES={,primer/{,what/,how/,releases_and_records/,next/},guidance/{,design/, # be an indication of an iframe taking too long to load." PDF_DELAY=20000 -# Empty: `docs/conf.py` compiles the schema and codelists catalogs that `translate` reads. -.PHONY: compile -compile: - # Put local targets below.