Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <computer> -m <g|c>` 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 <UUID>` 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
Expand Down
2 changes: 1 addition & 1 deletion docs/documentation/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
21 changes: 15 additions & 6 deletions toolchain/mfc/lint_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
Loading