diff --git a/.claude/skills/release-docs/SKILL.md b/.claude/skills/release-docs/SKILL.md index 73c1561a198..886aad544f9 100644 --- a/.claude/skills/release-docs/SKILL.md +++ b/.claude/skills/release-docs/SKILL.md @@ -1055,10 +1055,25 @@ instead of 57/2). Then: add, rename or change a public API. Grep the new snapshot for each symbol. 2. **`<` commits are in the release only.** Step 8b's sweep covers their breaking changes; check that every `!:` one was swept. -3. **Adjudicate every hit against `$AZTEC_NODE_DIR`**, the tag, as in Step 8b item 3. Fix +3. **Pages whose `references` changed between the two pins.** The old pin is the + destination's (the line's in a line cut); the script reads the cut's main paths: + + ```bash + . ~/.cache/aztec-docs-cut//env.sh && cd "$CUT" + old=$(git -C "$DEST_ROOT" show "$DEST:docs/${LINE:+lines/$LINE/}aztec-node.json" | + node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).commit') && + docs/scripts/pin_doc_references.sh "$old" + ``` + + For each listed page, read its references' diff and decide as the + `update-doc-references` skill's Step 4 does, against the page's snapshot copy: + `docs/docs-developers/` is `docs/developer_versioned_docs/version-v/`, + `docs/docs-operate/` is `docs/network_versioned_docs/version-v/`. + A `docs/docs-participate/` page has no snapshot and follows the destination's pin: skip it. +4. **Adjudicate every hit against `$AZTEC_NODE_DIR`**, the tag, as in Step 8b item 3. Fix the snapshot only: the source follows the destination's pin, so these fixes are release-only (Step 17). -4. Present what was found, fixed and skipped, for user confirmation. +5. Present what was found, fixed and skipped, for user confirmation. ### Step 13: Build and Fix Issues diff --git a/.claude/skills/release-network-docs/SKILL.md b/.claude/skills/release-network-docs/SKILL.md index 38cdb2296f0..87492d4babe 100644 --- a/.claude/skills/release-network-docs/SKILL.md +++ b/.claude/skills/release-network-docs/SKILL.md @@ -524,6 +524,20 @@ a failed count check work as in `/release-docs` Step 12. So do hand backports: o to its line (`v6`) is not patch-equivalent, so `--cherry-pick` keeps it on both sides; judge it against `$AZTEC_NODE_DIR`, the tag. +Then list the pages whose `references` changed between the two pins. The old pin is the +destination's (the line's in a line cut); the script reads the cut's main paths: + +```bash +. ~/.cache/aztec-docs-cut//env.sh && cd "$CUT" +old=$(git -C "$DEST_ROOT" show "$DEST:docs/${LINE:+lines/$LINE/}aztec-node.json" | + node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).commit') && + docs/scripts/pin_doc_references.sh "$old" +``` + +Take its `docs/docs-operate/` entries. For each, read its references' diff and decide +as the `update-doc-references` skill's Step 4 does, against the snapshot copy +`docs/network_versioned_docs/version-v/`; fix it under the rule below. + `>` commits are in the destination's pin but not in the release. Start with the operator pages the second log names (aztec-node held the docs until they moved here, so a code change and its doc edit landed in one commit) and revert those hunks in the snapshot, diff --git a/.claude/skills/update-doc-references/SKILL.md b/.claude/skills/update-doc-references/SKILL.md index a08351cfca1..ba2e5456ab5 100644 --- a/.claude/skills/update-doc-references/SKILL.md +++ b/.claude/skills/update-doc-references/SKILL.md @@ -64,22 +64,25 @@ checkouts, and edit each copy whose checkout has it (Step 5): a `main` PR can fi shares, and a page that is wrong about code both lines have is wrong in both copies. When the change is a move of a pin rather than a PR (`node docs/scripts/aztec_node.mts -[--line ] pin `), take it from the two pin commits, fetched into that line's -checkout. A two-commit diff needs no history between them. For main: +[--line ] pin `), the pages it reaches come from the line's two pin commits. Run +this once per line whose pin moved, after `check` passes: ```bash cd "$(git rev-parse --show-toplevel)" -pinfile=docs/aztec-node.json lineopt= # the v6 line's: pinfile=docs/lines/v6/aztec-node.json lineopt="--line v6" -old=$(git show "$(git merge-base origin/next HEAD):$pinfile" | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).commit') -new=$(node -p "require('./$pinfile').commit") -node docs/scripts/aztec_node.mts $lineopt fetch && pin=$(node docs/scripts/aztec_node.mts $lineopt env) || exit 1 -eval "$pin" -git -C "$AZTEC_NODE_DIR" fetch --depth 1 --no-tags origin "$old" "$new" -git -C "$AZTEC_NODE_DIR" diff --name-only "$old" "$new" | sed 's|^|labs/|' -git -C "$AZTEC_NODE_DIR" diff "$old" "$new" -- +docs/scripts/pin_doc_references.sh # the v6 line's: docs/scripts/pin_doc_references.sh --line v6 ``` -The pin file also names the toolchain: when `bb`, `noir` or `l1Artifacts` moved, say so in +It prints ` -> , ` for each `labs/` reference whose files differ +between the line's pin at `git merge-base origin/next HEAD` and its pin now. Pass the old +commit as an argument when the base is another (a release cut does). That list is Step 3's +mapping. stderr names both commits and the checkout, so read one reference's change with: + +```bash +git -C "$AZTEC_NODE_DIR" diff -- +``` + +`AZTEC_NODE_DIR` is the line's checkout: `eval "$(node docs/scripts/aztec_node.mts [--line +v6] env)"` exports it. The pin file also names the toolchain: when `bb`, `noir` or `l1Artifacts` moved, say so in the report, since the examples and the Solidity snippets follow them. ### Step 3: Identify Affected Documentation @@ -97,16 +100,14 @@ gh pr view --repo aztec-labs-eng/aztec-node --json files -q '.files[ sed 's|^|labs/|' >"$changed" for root in docs docs/lines/*; do extract_references_mapping "$root" "$map" - awk -F'|' 'NR == FNR {changed[$0]; next} - {ref = $1; dir = sub(/\/\*$/, "/", ref) - for (f in changed) if (dir ? index(f, ref) == 1 : f == ref) print f " -> " $2}' \ - "$changed" "$map" | sort -u + changed_references "$map" "$changed" done ``` -For a PR of this repository drop the `sed`; for a pin move write Step 2's `--name-only` -list to `"$changed"` instead. Report any pair the prompt lists that this does not produce, -and the reverse: the dispatcher's mapping is then stale. +Each line is ` -> , `, as `pin_doc_references.sh` prints for a pin +move, which needs no other mapping. For a PR of this repository drop the `sed`. Report any +pair the prompt lists that this does not produce, and the reverse: the dispatcher's mapping +is then stale. ### Step 4: Analyze Changes @@ -163,7 +164,11 @@ pass. ### Step 6: Commit on a Branch -If changes were made, commit them on a branch from `next`: +For a pin move, commit the edits on the branch that moves the pin, so they ship in its PR, +naming each file as below; skip the new branch and Step 7, and list the pages you checked in +that PR's description. + +Otherwise, if changes were made, commit them on a branch from `next`: ```bash git fetch origin next diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index 415ed57ac69..df67801b1ff 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -78,6 +78,7 @@ The aztec-node (Labs) code the docs quote is the commit `aztec-node.json` pins, - Snippet and `references:` paths keep their `labs/` prefix, which names the checkout: `labs/yarn-project/...` reads `.aztec-node/tree/yarn-project/...`, and source links name aztec-node at the pinned commit. - `node scripts/aztec_node.mts check` fails on any drift: a checkout at another commit or with edited files, toolchain versions that differ from the tag's, or an l1-artifacts version in `package.json` that differs from the pin. - Move the pin with `node scripts/aztec_node.mts pin ` (a release or nightly tag), never by hand; then set `@aztec-foundation/l1-artifacts` to the version `check` names, run `yarn install`, and commit `aztec-node.json` with `package.json` and `yarn.lock`. +- In the same PR, update the pages the move reaches, for each line whose pin moved. Once `check` passes, `scripts/pin_doc_references.sh [--line ]` prints ` -> ` for each `labs/` reference whose files differ between the pin at `git merge-base origin/next HEAD` and the new one; run the `update-doc-references` skill on that list. Then read `node:` in `https://install.aztec.network//versions` for the new pin, and if it changed, update `node_ver` on that line's `getting_started_on_local_network.md` (a release cut does this in `/release-docs` Step 10). - `pin` needs `gh` logged in: it records the sha256 of each noir release archive in `noirArchives` once `gh attestation verify` proves noir's publish workflow built it, and `provision` refuses a nargo archive whose sha256 differs. Never edit `noirArchives` to get past a mismatch: it means the release archive changed after the pin. - Tools that need nargo, bb or the aztec CLI use the pinned published ones: `node scripts/aztec_node.mts provision nargo bb cli`, then `eval "$(node scripts/aztec_node.mts env)"` exports `NARGO`, `BB`, `AZTEC` and the versions. Never run nargo inside `docs/` or the checkout: it takes `docs/Nargo.toml` as its workspace. - Each line's pin follows its own aztec-node branch (see "Two dev lines: change both"): `aztec-node.json` follows `main` (v7 from 2026-11-04), and `lines//aztec-node.json` follows ``. Move a line's pin with `node scripts/aztec_node.mts --line pin `: it installs the line's l1-artifacts into `lines//.aztec-node/`, so `package.json` does not change. A line's `pin` and `check` refuse a tag of another major. After moving any pin, check that the recorded commit is on its branch: `gh api "repos/aztec-labs-eng/aztec-node/compare/..." --jq .status` prints `behind` or `identical`. diff --git a/docs/README.md b/docs/README.md index 392a0d8c373..933a21280ac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -635,7 +635,9 @@ Documentation pages can declare which source files they document via a `referenc 2. **Validation**: During CI builds (`bootstrap.sh`), the system extracts all referenced paths from documentation frontmatter and fails the build if any of them no longer exist; update the `references` frontmatter in the affected doc. -**Implementation**: The check is `scripts/check_doc_references.sh` (with `scripts/lib/extract_doc_references.sh` for frontmatter parsing), which runs as part of the docs CI pipeline. +3. **Pin moves**: aztec-node changes reach the docs only when a line's pin moves, so the PR that moves it also updates the pages it reaches. `scripts/pin_doc_references.sh [--line ] []` lists them as ` -> `: every reference whose files differ between the old pin (by default the line's pin at `git merge-base origin/next HEAD`) and the new one. The `update-doc-references` skill under `.claude/skills/` takes that list. + +**Implementation**: The check is `scripts/check_doc_references.sh` (with `scripts/lib/extract_doc_references.sh` for frontmatter parsing), which runs as part of the docs CI pipeline. `scripts/pin_doc_references.sh` uses the same library. **Path Format**: diff --git a/docs/scripts/__tests__/pin_doc_references.test.mts b/docs/scripts/__tests__/pin_doc_references.test.mts new file mode 100644 index 00000000000..876878dad31 --- /dev/null +++ b/docs/scripts/__tests__/pin_doc_references.test.mts @@ -0,0 +1,130 @@ +import assert from "node:assert/strict"; +import { execFileSync, spawnSync } from "node:child_process"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { after, before, test } from "node:test"; + +const scripts = path.resolve(import.meta.dirname, ".."); +const SCRIPTS = ["pin_doc_references.sh", "lib/extract_doc_references.sh", "lib/aztec_node.sh", "aztec_node.mts"]; +const git = (cwd: string, ...args: string[]) => + execFileSync("git", ["-C", cwd, "-c", "commit.gpgsign=false", "-c", "user.name=t", "-c", "user.email=t@t", ...args], { encoding: "utf8" }).trim(); + +function write(file: string, text: string) { + fs.mkdirSync(path.dirname(file), { recursive: true }); + fs.writeFileSync(file, text); +} + +// An aztec-node stand-in with one commit per step (a null content deletes the file); returns the commits. +function upstream(dir: string, steps: Record[]): string[] { + fs.mkdirSync(dir, { recursive: true }); + git(dir, "init", "-q"); + git(dir, "config", "uploadpack.allowAnySHA1InWant", "true"); + write(path.join(dir, "labs-aztec-toolchain/bootstrap.sh"), "BB_VERSION=1.0.0\nNOIR_VERSION=0.1.0\n"); + return steps.map((step, i) => { + for (const [file, text] of Object.entries(step)) { + if (text === null) fs.rmSync(path.join(dir, file)); + else write(path.join(dir, file), text); + } + git(dir, "add", "-A"); + git(dir, "commit", "-q", "-m", `step ${i}`); + return git(dir, "rev-parse", "HEAD"); + }); +} + +const pin = (ref: string, commit: string) => + JSON.stringify({ + repository: "https://github.com/aztec-labs-eng/aztec-node", + ref, + commit, + toolchain: { aztec: ref.slice(1), bb: "1.0.0", noir: "0.1.0", l1Artifacts: "1.0.0" }, + noirArchives: { "x86_64-unknown-linux-gnu": `sha256:${"0".repeat(64)}` }, + }); + +const page = (refs: string[]) => `---\ntitle: p\nreferences: [${refs.map((r) => `"${r}"`).join(", ")}]\n---\n`; + +// The repository's docs/, whose branch moved main's pin from mainOld to mainNew and the v1 line's +// from lineOld to lineNew since origin/next; each checkout is a depth-1 clone of the new pin. +let base: string, root: string, mainOld: string, mainNew: string; +before(() => { + base = fs.mkdtempSync(path.join(os.tmpdir(), "pin-doc-references-")); + root = path.join(base, "repo"); + const docs = path.join(root, "docs"); + const line = path.join(docs, "lines/v1"); + fs.mkdirSync(root); + git(root, "init", "-q"); + for (const script of SCRIPTS) write(path.join(docs, "scripts", script), fs.readFileSync(path.join(scripts, script), "utf8")); + write(path.join(docs, ".gitignore"), ".aztec-node/\n"); + write(path.join(docs, "package.json"), JSON.stringify({ devDependencies: { "@aztec-foundation/l1-artifacts": "1.0.0" } })); + + [mainOld, mainNew] = upstream(path.join(base, "main"), [ + { "yarn-project/a.ts": "1", "yarn-project/same.ts": "s", "yarn-project/dir/x.ts": "1", "yarn-project/old_name.ts": "renamed\n".repeat(20), "yarn-project/gone.ts": "g", 'yarn-project/q/a"b.ts': "1" }, + { "yarn-project/a.ts": "2", "yarn-project/dir/x.ts": "2", "yarn-project/old_name.ts": null, "yarn-project/new_name.ts": "renamed\n".repeat(20), "yarn-project/gone.ts": null, "yarn-project/same.ts.orig": "o", 'yarn-project/q/a"b.ts': "2" }, + ]); + const [lineOld, lineNew] = upstream(path.join(base, "v1"), [ + { "yarn-project/a.ts": "1", "yarn-project/v1.ts": "1" }, + { "yarn-project/v1.ts": "2" }, + ]); + + write(path.join(docs, "docs-developers/a.md"), page(["labs/yarn-project/a.ts", "labs/yarn-project/same.ts"])); + write(path.join(docs, "docs-developers/b.md"), "---\ntitle: b\nreferences:\n [\n \"labs/yarn-project/dir/*\",\n \"labs/yarn-project/q/*\",\n ]\n---\n"); + write(path.join(docs, "docs-developers/d.md"), page(["labs/yarn-project/same.ts", "labs/yarn-project/di/*", "docs/examples/x.ts"])); + write(path.join(docs, "docs-developers/e.md"), page(["labs/yarn-project/a.ts"])); + write(path.join(docs, "docs-operate/c.md"), page(["labs/yarn-project/old_name.ts", "labs/yarn-project/gone.ts"])); + write(path.join(line, "docs-developers/a.md"), page(["labs/yarn-project/a.ts", "labs/yarn-project/v1.ts"])); + + write(path.join(docs, "aztec-node.json"), pin("v1.1.0", mainOld)); + write(path.join(line, "aztec-node.json"), pin("v1.0.0", lineOld)); + git(root, "add", "-A"); + git(root, "commit", "-q", "-m", "base"); + git(root, "update-ref", "refs/remotes/origin/next", "HEAD"); + write(path.join(docs, "aztec-node.json"), pin("v1.1.0", mainNew)); + write(path.join(line, "aztec-node.json"), pin("v1.0.0", lineNew)); + git(root, "commit", "-q", "-am", "move the pins"); + + for (const [up, state] of [["main", docs], ["v1", line]]) { + execFileSync("git", ["clone", "-q", "--depth", "1", "--no-tags", `file://${path.join(base, up)}`, path.join(state, ".aztec-node/tree")]); + } + write(path.join(line, ".aztec-node/l1-artifacts/package.json"), '{"version":"1.0.0"}'); +}); +after(() => fs.rmSync(base, { recursive: true, force: true })); + +function run(...args: string[]) { + const env = { ...process.env }; + delete env.AZTEC_NODE_DIR; + return spawnSync("bash", [path.join(root, "docs/scripts/pin_doc_references.sh"), ...args], { cwd: root, env, encoding: "utf8" }); +} + +const MAIN = [ + "labs/yarn-project/a.ts -> docs/docs-developers/a.md, docs/docs-developers/e.md", + "labs/yarn-project/dir/* -> docs/docs-developers/b.md", + "labs/yarn-project/gone.ts -> docs/docs-operate/c.md", + "labs/yarn-project/old_name.ts -> docs/docs-operate/c.md", + "labs/yarn-project/q/* -> docs/docs-developers/b.md", + "", +].join("\n"); + +test("lists each reference whose files changed, fetching the old commit the checkout lacks", () => { + const tree = path.join(root, "docs/.aztec-node/tree"); + assert.notEqual(spawnSync("git", ["-C", tree, "cat-file", "-e", `${mainOld}^{commit}`]).status, 0, "the old commit starts outside the checkout"); + + const r = run(mainOld); + assert.equal(r.status, 0, r.stderr); + assert.equal(r.stdout, MAIN); +}); + +test("defaults to each line's pin at the merge base with origin/next", () => { + const main = run(); + assert.equal(main.status, 0, main.stderr); + assert.equal(main.stdout, MAIN); + + const line = run("--line", "v1"); + assert.equal(line.status, 0, line.stderr); + assert.equal(line.stdout, "labs/yarn-project/v1.ts -> docs/lines/v1/docs-developers/a.md\n"); + + const unmoved = run(mainNew); + assert.equal(unmoved.status, 0, unmoved.stderr); + assert.equal(unmoved.stdout, ""); + + assert.equal(run("HEAD").status, 2); +}); diff --git a/docs/scripts/lib/extract_doc_references.sh b/docs/scripts/lib/extract_doc_references.sh old mode 100755 new mode 100644 index 8f7044e7de9..549d9dae653 --- a/docs/scripts/lib/extract_doc_references.sh +++ b/docs/scripts/lib/extract_doc_references.sh @@ -14,8 +14,8 @@ extract_references_mapping() { local docs_dir="$1" local output_file="$2" - # Clear output file - > "$output_file" + # Not a bare `> file`: zsh runs that as `cat > file`, which blocks on an open stdin. + : >"$output_file" # Scan docs-developers, docs-operate, and docs-participate subdirectories for docs_subdir in docs-developers docs-operate docs-participate; do @@ -76,65 +76,27 @@ _extract_from_directory() { done >> "$output_file" } -# Get unique reference files from a mapping file +# Print ` -> , ` for each reference that names a changed path: the path itself, +# or a directory holding it (`/*` or ``). One line per reference, sorted. # Arguments: -# $1 - mapping_file: Path to the mapping file -get_unique_references() { +# $1 - mapping_file: from extract_references_mapping ("ref_file|doc_file") +# $2 - changed_file: changed paths from the repository root, one per line +changed_references() { local mapping_file="$1" - cut -d'|' -f1 "$mapping_file" | sort -u -} - -# Find which docs reference a given file pattern -# Arguments: -# $1 - mapping_file: Path to the mapping file -# $2 - pattern: The file pattern to search for -find_docs_for_reference() { - local mapping_file="$1" - local pattern="$2" - grep -F "$pattern" "$mapping_file" | cut -d'|' -f2 | sort -u -} - -# Build associative arrays for file-to-docs and docs-to-files mappings -# Arguments: -# $1 - mapping_file: Path to the mapping file -# $2 - changed_files: Newline-separated list of changed files -# Sets global variables: -# FILE_TO_DOCS_MAP - associative array -# DOC_TO_FILES_MAP - associative array -# CHANGED_REFERENCES - newline-separated list of changed reference files -build_change_mappings() { - local mapping_file="$1" - local changed_files="$2" - - # Initialize global associative arrays - declare -gA FILE_TO_DOCS_MAP - declare -gA DOC_TO_FILES_MAP - CHANGED_REFERENCES="" - - local reference_files=$(get_unique_references "$mapping_file") - - while IFS= read -r ref_file; do - [[ -z "$ref_file" ]] && continue - local match_pattern="${ref_file%/\*}" + local changed_file="$2" - if echo "$changed_files" | grep -qF "$match_pattern"; then - CHANGED_REFERENCES="${CHANGED_REFERENCES}${ref_file}\n" - - while IFS='|' read -r src_file doc_file; do - if [[ "$src_file" == "$ref_file" ]]; then - if [[ -n "${FILE_TO_DOCS_MAP[$ref_file]:-}" ]]; then - FILE_TO_DOCS_MAP[$ref_file]="${FILE_TO_DOCS_MAP[$ref_file]}|${doc_file}" - else - FILE_TO_DOCS_MAP[$ref_file]="$doc_file" - fi - - if [[ -n "${DOC_TO_FILES_MAP[$doc_file]:-}" ]]; then - DOC_TO_FILES_MAP[$doc_file]="${DOC_TO_FILES_MAP[$doc_file]}|${ref_file}" - else - DOC_TO_FILES_MAP[$doc_file]="$ref_file" - fi - fi - done < "$mapping_file" - fi - done <<< "$reference_files" + # FILENAME, not NR == FNR: an empty changed file would otherwise read the mapping as changes. + awk -F'|' -v changed_file="$changed_file" ' + FILENAME == changed_file { changed[$0]; next } + { + dir = $1 + sub(/\/\*$/, "", dir) + if (dir in changed) { print $1 "|" $2; next } + for (path in changed) if (index(path, dir "/") == 1) { print $1 "|" $2; next } + } + ' "$changed_file" "$mapping_file" | LC_ALL=C sort -u | awk -F'|' ' + $1 != ref { if (NR > 1) print ""; ref = $1; printf "%s -> %s", ref, $2; next } + { printf ", %s", $2 } + END { if (NR) print "" } + ' } diff --git a/docs/scripts/pin_doc_references.sh b/docs/scripts/pin_doc_references.sh new file mode 100755 index 00000000000..ac4ecb27489 --- /dev/null +++ b/docs/scripts/pin_doc_references.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# pin_doc_references - The docs pages a pin move reaches +# +# Prints ` -> , ` for each labs/ reference in a line's pages whose files differ +# between an older aztec-node commit and the line's pinned one: the pages to review with the +# update-doc-references skill in the change that moves the pin. +# +# Usage: pin_doc_references.sh [--line ] [] +# +# --line a dev line (docs/lines//: its pages, pin and checkout); default: main's +# the aztec-node commit the pin moved from, 40 hex characters; default: the one the +# line's pin file names at `git merge-base origin/next HEAD`. A release cut passes it, +# since a line cut moves the line into main's paths. +# +# Reads the checkout `aztec_node.mts fetch` keeps, fetching into it at depth 1 when absent. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$(git rev-parse --show-toplevel)" +# shellcheck source-path=SCRIPTDIR source=lib/extract_doc_references.sh +source "$SCRIPT_DIR/lib/extract_doc_references.sh" +# shellcheck source-path=SCRIPTDIR source=lib/aztec_node.sh +source "$SCRIPT_DIR/lib/aztec_node.sh" + +function usage { + sed -n '2,/^set -e/p' "$SCRIPT_DIR/pin_doc_references.sh" | sed '$d; s/^# \{0,1\}//' >&2 + exit 2 +} + +function die { + echo "pin_doc_references: $*" >&2 + exit 1 +} + +function pin_commit { + node -e 'process.stdout.write(JSON.parse(require("fs").readFileSync(0, "utf8")).commit)' +} + +COMMIT='^[0-9a-f]{40}$' +LINE= +if [[ ${1:-} == --line ]]; then + [[ ${2:-} =~ ^v[0-9]+$ ]] || usage + LINE=$2 + shift 2 +fi +[[ $# -le 1 ]] || usage +[[ $# -eq 0 || $1 =~ $COMMIT ]] || usage +DOCS_DIR=docs${LINE:+/lines/$LINE} +PIN_FILE=$DOCS_DIR/aztec-node.json + +require_aztec_node "$LINE" +new=$(pin_commit <"$PIN_FILE") +if [[ $# -eq 1 ]]; then + old=$1 +else + base=$(git merge-base origin/next HEAD) || die "no merge base with origin/next: run git fetch origin next, or pass the old commit" + pinned=$(git show "$base:$PIN_FILE" 2>/dev/null) || die "$PIN_FILE does not exist at $base: pass the old commit" + old=$(pin_commit <<<"$pinned") + [[ $old =~ $COMMIT ]] || die "$PIN_FILE at $base names no commit" +fi +if [[ $old == "$new" ]]; then + echo "pin_doc_references: $PIN_FILE still pins $new" >&2 + exit 0 +fi + +git -C "$AZTEC_NODE_DIR" cat-file -e "$old^{commit}" 2>/dev/null || + git -C "$AZTEC_NODE_DIR" fetch -q --depth 1 --no-tags origin --end-of-options "$old" || + die "cannot fetch $old from $(git -C "$AZTEC_NODE_DIR" remote get-url origin): pass an aztec-node commit" + +changed=$(mktemp) +mapping=$(mktemp) +trap 'rm -f "$changed" "$mapping"' EXIT +# --no-renames: a rename would list only the new path, and pages reference the old one. -z: git +# C-quotes a name holding `"` or `\` even with core.quotePath=false. +git -C "$AZTEC_NODE_DIR" diff -z --no-renames --name-only "$old" "$new" -- | tr '\0' '\n' | sed 's|^|labs/|' >"$changed" +extract_references_mapping "$DOCS_DIR" "$mapping" +found=$(changed_references "$mapping" "$changed") +[[ -z $found ]] || printf '%s\n' "$found" +echo "pin_doc_references: $(grep -c . <<<"$found" || true) reference(s) reached between $old and $new;" \ + "diff one with: git -C $AZTEC_NODE_DIR diff $old $new -- " >&2