diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b1321dcbc..5523423f4 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -12,7 +12,7 @@ It holds policy and pointers only; facts live in the linked docs, and `./mfc.sh * Load a compiler and MPI before building. On a supported cluster, `source ./mfc.sh load -c -m ` loads a known-working module set. Pass both flags; omitting either waits for interactive input. Computer slugs are the first column of `toolchain/modules`; elsewhere, `module load` the equivalents * Agent shell tools run each command in a fresh shell, so a one-off `module load` or `source ./mfc.sh load` is gone by the next command. Chain it (`source ./mfc.sh load -c p -m g && ./mfc.sh build -j 8`) or put the steps in a script * Running mfc.sh commands can create a lock file in build/ that is sticky, be careful (`toolchain/mfc/lock.py`) - * Run `./mfc.sh precheck` before pushing; it runs the same lint gate as CI + * Run `./mfc.sh precheck` before pushing; it runs the CI lint gate except the slow rendering and Fortran-compile unit tests * Iterate small: `./mfc.sh build -t simulation` builds one target; `./mfc.sh test --only ` runs one test; `./mfc.sh test --select-enforce` runs only the tests whose coverage touches your changed files * Programming and Design: * New code should follow the DRY principle and also make side-effect code DRY as well diff --git a/docs/documentation/contributing.md b/docs/documentation/contributing.md index 5230abe94..d86d61fef 100644 --- a/docs/documentation/contributing.md +++ b/docs/documentation/contributing.md @@ -802,7 +802,7 @@ Every push to a PR triggers CI. Understanding the pipeline helps you fix failure ### Lint Gate (runs first, blocks the build and test jobs) -All six checks must pass before any builds start (`./mfc.sh precheck` runs them locally, plus example-case validation): +All six checks must pass before any builds start. `./mfc.sh precheck` runs them locally, plus example-case validation, but skips the slow rendering and Fortran-compile unit tests in the toolchain lint: 1. **Formatting** — `./mfc.sh format` must leave no diff 2. **Spelling** — `./mfc.sh spelling` diff --git a/toolchain/mfc/lint_docs.py b/toolchain/mfc/lint_docs.py index 56c598281..e86b24d1d 100644 --- a/toolchain/mfc/lint_docs.py +++ b/toolchain/mfc/lint_docs.py @@ -847,13 +847,22 @@ def check_module_categories(repo_root: Path) -> list[str]: def check_page_date_footers(repo_root: Path) -> list[str]: - """Check that no doc carries a committed last-updated footer (docs/inject-dates.py adds it at build time).""" - doc_dir = repo_root / "docs" / "documentation" + """Check that no tracked doc is staged with a last-updated footer (docs/inject-dates.py adds it at build time). + + Reads the index, not the working tree: a local docs build writes footers into every page, and only a staged one + would freeze its date. + """ + import subprocess + + try: + tracked = subprocess.run(["git", "ls-files", "docs/documentation/*.md"], capture_output=True, text=True, cwd=repo_root, check=True).stdout.split() + except (FileNotFoundError, subprocess.CalledProcessError): + return [] errors = [] - for md_file in sorted(doc_dir.glob("*.md")): - if "Page last updated:" in md_file.read_text(encoding="utf-8"): - rel = md_file.relative_to(repo_root) - errors.append(f" {rel} contains a 'Page last updated' footer, which freezes its date. Fix: remove it (the docs build adds it from git history)") + for rel in tracked: + staged = subprocess.run(["git", "show", f":{rel}"], capture_output=True, text=True, cwd=repo_root, check=False).stdout + if "Page last updated:" in staged: + errors.append(f" {rel} is staged with a 'Page last updated' footer, which freezes its date. Fix: drop the footer (the docs build adds it from git history)") return errors