From 3b80f019ad1d8c00d525a50b58cd251a175f14c2 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Sat, 31 Oct 2026 07:58:07 -0700 Subject: [PATCH] case 4757 - manual revision stamp and copyright year set automatically when the manuals are built A MkDocs hook (docs/8.0/rev_date.py), used by both manuals, replaces REV-AUTO and YEAR-AUTO in the copyright line with the date of the last commit that changed that manual, or today if it has uncommitted changes or git is not available. A missing placeholder fails the strict build. The customer manual's stamp had not been updated since 2022. The home page sentence about the stamp no longer reads like a placeholder. Release procedure step 2, the docs Dockerfile usage lines and .gitignore (__pycache__) follow. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 2 ++ Dockerfile.docs | 6 +++--- devdocs/build/RELEASE-PROCEDURE.md | 4 +++- docs/8.0/ayanova/docs/index.md | 4 +--- docs/8.0/ayanova/mkdocs.yml | 5 ++++- docs/8.0/customer/mkdocs.yml | 5 ++++- docs/8.0/rev_date.py | 34 ++++++++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 docs/8.0/rev_date.py diff --git a/.gitignore b/.gitignore index 39a1730b..e100385c 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ Desktop.ini /server/AyaNova/wwwroot /logfile build-output.txt +# compiled copy of the manuals' MkDocs hook (docs/8.0/rev_date.py) +__pycache__/ diff --git a/Dockerfile.docs b/Dockerfile.docs index 3f463f90..8fb7618f 100644 --- a/Dockerfile.docs +++ b/Dockerfile.docs @@ -6,11 +6,11 @@ # Build the image: # docker build -f Dockerfile.docs -t ayanova-docs-build . # -# Run a build (mount your docs source and output): -# docker run --rm -v "c:/data/code/raven/docs/8.0/ayanova:/docs" -v "c:/data/code/raven/server/AyaNova/wwwroot/docs:/output" ayanova-docs-build +# Run a build (mount docs/8.0, not only ayanova: mkdocs.yml uses the shared hook ../rev_date.py): +# docker run --rm -v "c:/data/code/raven/docs/8.0:/docs" -w /docs/ayanova -v "c:/data/code/raven/server/AyaNova/wwwroot/docs:/output" ayanova-docs-build # # Serve docs locally for preview (on port 8000): -# docker run --rm -p 8000:8000 -v "c:/data/code/raven/docs/8.0/ayanova:/docs" ayanova-docs-build mkdocs serve -a 0.0.0.0:8000 +# docker run --rm -p 8000:8000 -v "c:/data/code/raven/docs/8.0:/docs" -w /docs/ayanova ayanova-docs-build mkdocs serve -a 0.0.0.0:8000 # FROM python:3.11-slim-bullseye diff --git a/devdocs/build/RELEASE-PROCEDURE.md b/devdocs/build/RELEASE-PROCEDURE.md index 5c93d173..3fb077ed 100644 --- a/devdocs/build/RELEASE-PROCEDURE.md +++ b/devdocs/build/RELEASE-PROCEDURE.md @@ -51,7 +51,9 @@ cd C:\data\code\raven-test\e2e; .\local-run.bat **Often missed: check carefully against the previous release.** - `docs/8.0/ayanova/docs/changelog.md`: the new version's section is complete and reads well; remove "IN PROGRESS". -- `docs/8.0/ayanova/mkdocs.yml`: `copyright` line, year range and `REV-` date. +- Manual revision stamp and copyright year: set automatically when the manuals are built + (`docs/8.0/rev_date.py`, the date of the last commit that changed each manual). After the build, + check the bottom of a page in `server/AyaNova/wwwroot/docs`: `REV-` must be that date. - `dist/latest-version.json`: the new version and its changelog anchor (for example `#ayanova-830`). Set at the version bump; check it here. ## 3. Build diff --git a/docs/8.0/ayanova/docs/index.md b/docs/8.0/ayanova/docs/index.md index ee284397..1afdaca5 100644 --- a/docs/8.0/ayanova/docs/index.md +++ b/docs/8.0/ayanova/docs/index.md @@ -18,9 +18,7 @@ You may be viewing an older local version of this manual that was installed with The most recent manual can always be viewed on our website at [https://www.ayanova.com/docs/](https://www.ayanova.com/docs/) -You can tell which version of the manual you are viewing by look at the revision stamp at the bottom of the page which shows the year month and day that copy of the manual was last updated: - -`REV-YYYY-MM-DD ` +You can tell which version of the manual you are viewing by looking at the revision stamp at the bottom of the page: `REV-` followed by the year, month and day this copy of the manual was last changed. ### Beyond this manual diff --git a/docs/8.0/ayanova/mkdocs.yml b/docs/8.0/ayanova/mkdocs.yml index 0b75b08f..528f0335 100644 --- a/docs/8.0/ayanova/mkdocs.yml +++ b/docs/8.0/ayanova/mkdocs.yml @@ -8,7 +8,10 @@ site_name: AyaNova manual site_dir: "../../../server/AyaNova/wwwroot/docs" site_url: https://ayanova.com/docs/ strict: true -copyright: Copyright © 2022-2026 Ground Zero Tech-Works Inc. REV-2026-10-26 +# YEAR-AUTO and REV-AUTO are set when the manual is built (../rev_date.py) +copyright: Copyright © 2022-YEAR-AUTO Ground Zero Tech-Works Inc. REV-AUTO +hooks: + - ../rev_date.py extra: generator: false # Extensions diff --git a/docs/8.0/customer/mkdocs.yml b/docs/8.0/customer/mkdocs.yml index 32d89007..a1260368 100644 --- a/docs/8.0/customer/mkdocs.yml +++ b/docs/8.0/customer/mkdocs.yml @@ -8,7 +8,10 @@ theme: site_name: AyaNova Customer user manual site_dir: '../../../server/AyaNova/wwwroot/cust' strict: true -copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-07-18 +# YEAR-AUTO and REV-AUTO are set when the manual is built (../rev_date.py) +copyright: Copyright © 2022-YEAR-AUTO Ground Zero Tech-Works Inc. REV-AUTO +hooks: + - ../rev_date.py extra: generator: false # Extensions diff --git a/docs/8.0/rev_date.py b/docs/8.0/rev_date.py new file mode 100644 index 00000000..f640a4e8 --- /dev/null +++ b/docs/8.0/rev_date.py @@ -0,0 +1,34 @@ +# case 4757: the revision stamp and copyright year in the footer are set when a manual is built, never by hand. +# Used by both manuals (hooks: in mkdocs.yml). In the copyright line REV-AUTO becomes REV- and YEAR-AUTO +# becomes that date's year. The date is the last commit that changed this manual (its folder, mkdocs.yml included), +# or today if it has uncommitted changes or git is not available (e.g. a build outside the repo). +# Both manuals build with strict: true, so a warning here fails the build: only a missing placeholder warns. +import datetime +import logging +import os +import subprocess + +log = logging.getLogger("mkdocs.hooks.rev_date") + + +def _git(folder, *args): + return subprocess.run(["git", *args, "--", "."], cwd=folder, capture_output=True, text=True, check=True).stdout.strip() + + +def on_config(config): + folder = os.path.dirname(os.path.abspath(config.config_file_path)) + today = datetime.date.today().isoformat() + try: + rev = today if _git(folder, "status", "--porcelain") else _git(folder, "log", "-1", "--format=%cs") + except (OSError, subprocess.CalledProcessError): + log.info("git not available: revision date set to today") + rev = today + rev = rev or today + + copyright = config.copyright or "" + for placeholder in ("REV-AUTO", "YEAR-AUTO"): + if placeholder not in copyright: + log.warning(f"{placeholder} not found in the copyright line of {config.config_file_path}") + config.copyright = copyright.replace("REV-AUTO", "REV-" + rev).replace("YEAR-AUTO", rev[:4]) + log.info(f"revision stamp: {config.copyright}") + return config