|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | # dogfood-build.sh — Build claw from current checkout and verify provenance. |
3 | | -# Usage: bash scripts/dogfood-build.sh |
4 | | -# On success: prints the verified binary path. Use as: |
5 | | -# CLAW=$(bash scripts/dogfood-build.sh) && $CLAW version --output-format json |
| 3 | +# |
| 4 | +# Injects GIT_SHA at build time so version JSON is non-null. |
| 5 | +# Suppresses Cargo compile noise on stderr. |
| 6 | +# Prints the verified binary path on success. Use as: |
| 7 | +# |
| 8 | +# CLAW=$(bash scripts/dogfood-build.sh) |
| 9 | +# |
| 10 | +# Then dogfood with config isolation (avoids real user config bleeding in): |
| 11 | +# |
| 12 | +# CLAW_CONFIG_HOME=$(mktemp -d) $CLAW plugins list --output-format json |
| 13 | +# |
6 | 14 | set -euo pipefail |
7 | 15 |
|
8 | 16 | REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
9 | 17 | RUST_DIR="$REPO_ROOT/rust" |
10 | 18 | BINARY="$RUST_DIR/target/debug/claw" |
11 | 19 | EXPECTED_SHA="$(git -C "$REPO_ROOT" rev-parse --short HEAD)" |
12 | 20 |
|
13 | | -echo "▶ Building claw from $REPO_ROOT ($(git -C "$REPO_ROOT" log --oneline -1))..." >&2 |
14 | | -cargo build --manifest-path "$RUST_DIR/Cargo.toml" -p rusty-claude-cli -q |
| 21 | +echo "▶ Building claw from $REPO_ROOT" >&2 |
| 22 | +echo " Commit: $(git -C "$REPO_ROOT" log --oneline -1)" >&2 |
| 23 | + |
| 24 | +# Inject GIT_SHA so version JSON returns a non-null sha. |
| 25 | +# Redirect cargo stderr to /dev/null to suppress compile noise; |
| 26 | +# on build failure cargo exits non-zero and set -e aborts. |
| 27 | +if ! GIT_SHA="$EXPECTED_SHA" cargo build \ |
| 28 | + --manifest-path "$RUST_DIR/Cargo.toml" \ |
| 29 | + -p rusty-claude-cli -q 2>/dev/null; then |
| 30 | + # Re-run with visible output so the user sees the error |
| 31 | + echo "✗ Build failed — rerunning with output:" >&2 |
| 32 | + GIT_SHA="$EXPECTED_SHA" cargo build \ |
| 33 | + --manifest-path "$RUST_DIR/Cargo.toml" \ |
| 34 | + -p rusty-claude-cli 2>&1 | sed 's/^/ /' >&2 |
| 35 | + exit 1 |
| 36 | +fi |
15 | 37 |
|
16 | 38 | if [[ ! -x "$BINARY" ]]; then |
17 | | - echo "✗ Build succeeded but binary not found at $BINARY" >&2 |
| 39 | + echo "✗ Binary not found at $BINARY" >&2 |
18 | 40 | exit 1 |
19 | 41 | fi |
20 | 42 |
|
21 | 43 | BINARY_SHA=$("$BINARY" version --output-format json 2>/dev/null \ |
22 | | - | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('git_sha','null'))" 2>/dev/null || echo "null") |
| 44 | + | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('git_sha') or 'null')" 2>/dev/null \ |
| 45 | + || echo "null") |
23 | 46 |
|
24 | 47 | if [[ "$BINARY_SHA" == "null" || -z "$BINARY_SHA" ]]; then |
25 | 48 | echo "✗ Provenance check failed: binary reports git_sha: null" >&2 |
26 | | - echo " Binary: $BINARY" >&2 |
27 | 49 | exit 1 |
28 | 50 | fi |
29 | 51 |
|
30 | 52 | if [[ "$BINARY_SHA" != "$EXPECTED_SHA" ]]; then |
31 | 53 | echo "✗ Provenance mismatch: binary=$BINARY_SHA, HEAD=$EXPECTED_SHA" >&2 |
32 | | - echo " Rerun after 'git pull' or check for uncommitted changes." >&2 |
33 | 54 | exit 1 |
34 | 55 | fi |
35 | 56 |
|
36 | | -echo "✓ Binary verified: $BINARY_SHA == HEAD ($EXPECTED_SHA)" >&2 |
37 | | -echo " To dogfood: export CLAW=$BINARY" >&2 |
| 57 | +echo "✓ Binary verified: $BINARY_SHA == HEAD" >&2 |
| 58 | +echo "" >&2 |
| 59 | +echo " export CLAW=$BINARY" >&2 |
| 60 | +echo "" >&2 |
| 61 | +echo " Dogfood with isolated config (no real user config on stderr):" >&2 |
| 62 | +echo " CLAW_ISOLATED=\$(mktemp -d)" >&2 |
| 63 | +echo " CLAW_CONFIG_HOME=\$CLAW_ISOLATED \$CLAW plugins list --output-format json" >&2 |
| 64 | +echo " rm -rf \$CLAW_ISOLATED" >&2 |
| 65 | +echo "" >&2 |
| 66 | +echo " cargo run overhead: ~1s/invocation vs 7ms for pre-built binary." >&2 |
| 67 | +echo " Prefer pre-built binary (\$CLAW) for dogfood loops." >&2 |
38 | 68 | echo "$BINARY" |
0 commit comments