max / audiofiles
| 1 | #!/bin/bash |
| 2 | # Canonical pre-push gate. Two gates, and they answer different questions: |
| 3 | # |
| 4 | # internal deps does every in-house `version` requirement in the tree still |
| 5 | # resolve against the crate it names? Runs in EVERY repo. |
| 6 | # test targets do this repo's test targets build? Runs where there is a |
| 7 | # root Cargo.toml to run one command in. |
| 8 | # |
| 9 | # DO NOT EDIT IN PLACE. The master is _private/infra/bootstrap/githooks/pre-push. |
| 10 | # |
| 11 | # Bypass for a work-in-progress push: git push --no-verify |
| 12 | # |
| 13 | # WHY THE FIRST GATE EXISTS. Every cross-repo dependency carries a `version` |
| 14 | # alongside its `git` URL, so cargo refuses a sibling it was not written against |
| 15 | # instead of compiling something surprising. That requirement is the protection |
| 16 | # and it is also the maintenance: bumping a library's minor breaks every consumer |
| 17 | # whose requirement excludes it, and CLAUDE.md's rule is that the bump and the |
| 18 | # forward fix are one pass. Nothing enforced the rule, so quasi went 0.11 -> 0.14 |
| 19 | # over two evenings and MNW's server could not resolve at all for a day. The |
| 20 | # nightly sweep found it and a red cell in a grid is not the same as being told. |
| 21 | # |
| 22 | # This gate is that rule, mechanised, at the moment it is broken: the push that |
| 23 | # would leave a consumer unable to build is the push that is refused. It reads |
| 24 | # the WORKING COPIES in the tree, not the remotes, because `~/Code/.cargo/config.toml` |
| 25 | # redirects every one of these dependencies to the working copy -- so a local bump |
| 26 | # breaks a consumer's build here whether or not it has been pushed anywhere. |
| 27 | # |
| 28 | # `cargo check` and `cargo clippy` both compile only the lib and bin targets, so a |
| 29 | # break confined to `tests/` or a `#[cfg(test)]` module is clean under both and |
| 30 | # lands unnoticed (goingson's sqlx 0.9 upgrade shipped exactly that way). |
| 31 | # `--no-run` builds every test target without running them, which is the cheap |
| 32 | # half of the suite and enough to catch a compile break. Tests still run |
| 33 | # separately. |
| 34 | # |
| 35 | # `--workspace` is load-bearing wherever default-members is narrower than the |
| 36 | # workspace: goingson's is src-tauri alone, so a bare `cargo test --no-run` would |
| 37 | # skip core, db-sqlite, go-mcp and got. |
| 38 | |
| 39 | |
| 40 | ROOT="" |
| 41 | |
| 42 | |
| 43 | # See the canonical pre-commit: a hook run from an editor or a cron job does not |
| 44 | # get the profile's PATH, and a hook that cannot find cargo is worse than none. |
| 45 | |
| 46 | |
| 47 | # Refs arrive on stdin as "<local ref> <local sha> <remote ref> <remote sha>". |
| 48 | # A branch deletion has an all-zero local sha and no tree to push. Read once, |
| 49 | # ahead of both gates: stdin is not seekable and a second reader gets nothing. |
| 50 | pushing=0 |
| 51 | while ; do |
| 52 | case "" in |
| 53 | *[!0]*) pushing=1 ;; |
| 54 | esac |
| 55 | done |
| 56 | [ || |
| 57 | |
| 58 | # ── gate 1: internal dependency coherence ────────────────────────────────── |
| 59 | # |
| 60 | # Deliberately no cargo: this reads manifests and answers in well under a second, |
| 61 | # where `cargo metadata` on the server is tens of seconds and fails outright on |
| 62 | # exactly the state being detected. |
| 63 | CODE_ROOT="" |
| 64 | if [ && ; then |
| 65 | if ! ; then |
| 66 | |
| 67 | |
| 68 | fi |
| 69 | fi |
| 70 | |
| 71 | # ── gate 2: test targets build ───────────────────────────────────────────── |
| 72 | # |
| 73 | # MNW and synckit have no root Cargo.toml by design (standalone crates, no root |
| 74 | # workspace), so there is no one command to run and they get gate 1 only. |
| 75 | [ || |
| 76 | |
| 77 | |
| 78 | if ! ; then |
| 79 | |
| 80 | |
| 81 | |
| 82 | fi |
| 83 | |
| 84 | |
| 85 |