asm_book/.github
Perry Kivolowitz 3144bc6dbb Enforce macro canonical-vs-chapter-copy identity via sync script and CI
The repository ships a copy of apple-linux-convergence.S in each
chapter directory that demonstrates assembly (11 copies at last count,
plus the canonical one in macros/) so that readers browsing or
downloading a single chapter from GitHub have the macros sitting
right next to the sources that use them. That self-containment is
worth keeping. Manual synchronization of 12 copies on every macro
edit is not: all 11 are currently byte-identical to the canonical,
but the first drift is a matter of when, not if, and diagnosing
"which chapter broke when I added a new macro" after the fact is
a bad time.

This commit turns "the copies are in sync" from a hope into a
machine-enforced invariant:

- scripts/sync-macros.sh: walks macros/*.S, finds every file with
  the same basename anywhere else in the repo (excluding .git/ and
  macros/ itself), and overwrites any copy that differs. Idempotent;
  prints only the files it actually changed plus a summary. Uses
  only POSIX tools (find, cmp, cp, basename) plus bash builtins
  under a #!/usr/bin/env bash shebang. Verified working under both
  macOS bash 3.2.57 and zsh 5.9 on clean-tree and drift-repair
  paths.

- .github/workflows/check-macros.yml: runs the sync script on every
  push and pull request, then fails the job if git diff --exit-code
  shows the script produced any uncommitted change. The failure
  message tells the author exactly what to do (run the script
  locally, commit the result).

- macros/README.md: new "Source of truth" section marking the
  chapter copies as derived artifacts, pointing editors at the
  sync script, and stating that CI enforces the invariant.

Rejected alternatives:

- Symlinking each chapter copy to macros/apple-linux-convergence.S.
  Cheapest option (zero infrastructure) and git handles symlinks
  natively, but Windows checkouts without Developer Mode replace
  the symlink with a plain-text file containing the target path.
  This book's audience is overwhelmingly Linux and Apple Silicon,
  so the Windows hazard is mostly theoretical, but a sync-and-check
  approach works in every clone environment and makes the
  source-of-truth relationship explicit rather than implicit in a
  filesystem feature.

- Having each chapter .include the canonical file via a relative
  path. Breaks the "self-contained chapter" property the copies
  exist to preserve; a reader who downloads one chapter gets a
  broken build because macros/ is not beside it.

- Making the copies build-time artifacts (generated by make, not
  committed). Same problem: a reader browsing one chapter on
  GitHub no longer sees the macro file they need.

Tests:

- ./scripts/sync-macros.sh run on the current tree reports
  "macros already in sync (11 chapter copies checked)" and exits 0.
- Injecting a trailing-line perturbation into a chapter copy and
  re-running the script: detects the drift, reports "synced: <path>",
  and restores the file to canonical. Verified under both bash and
  zsh, both paths.
2026-04-19 02:20:34 -05:00
..
workflows Enforce macro canonical-vs-chapter-copy identity via sync script and CI 2026-04-19 02:20:34 -05:00