|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +# Repoint the in-tree Homebrew formula at a released tag's source tarball. |
| 5 | +# |
| 6 | +# WHY THIS EXISTS |
| 7 | +# Formula/claude-usage.rb ships *inside* the repo it installs, so it can never |
| 8 | +# hash its own release tarball — the sha256 would have to be the hash of a file |
| 9 | +# that contains that very hash (self-referential, uncomputable). So the formula |
| 10 | +# must point at an ALREADY-FROZEN tag: the previous release. |
| 11 | +# |
| 12 | +# Brew reads the formula from the tap's default branch (main), never from DEV |
| 13 | +# or a tag. Run this on DEV while prepping a release; the change reaches brew |
| 14 | +# users through the normal DEV -> main release merge. It never touches main |
| 15 | +# directly, so it dodges main's branch protection. Net effect: brew tracks one |
| 16 | +# release behind, and it advances automatically every release instead of being |
| 17 | +# hand-edited (which is how the pin silently rotted at v1.1.0 for months). |
| 18 | +# |
| 19 | +# USAGE |
| 20 | +# scripts/bump-formula.sh [TAG] |
| 21 | +# TAG tag to pin at (e.g. v1.5.2). Defaults to the latest v* tag on origin, |
| 22 | +# which — run during release prep, before the new tag exists — is the |
| 23 | +# previous release. Review the diff, then commit on DEV. |
| 24 | +# |
| 25 | +# See AGENTS.md "Homebrew formula and self-referential SHA". |
| 26 | + |
| 27 | +REPO_SLUG="phuryn/claude-usage" |
| 28 | +REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" |
| 29 | +FORMULA="$REPO_DIR/Formula/claude-usage.rb" |
| 30 | + |
| 31 | +TAG="${1:-}" |
| 32 | +if [ -z "$TAG" ]; then |
| 33 | + echo "🔎 No tag given — finding the latest v* tag on origin..." |
| 34 | + git -C "$REPO_DIR" fetch --tags --quiet origin || true |
| 35 | + TAG="$(git -C "$REPO_DIR" ls-remote --tags --refs origin 'v*' \ |
| 36 | + | awk -F/ '{print $NF}' | sort -V | tail -n1)" |
| 37 | +fi |
| 38 | +[ -n "$TAG" ] || { echo "❌ Could not determine a tag to pin at." >&2; exit 1; } |
| 39 | + |
| 40 | +VERSION="${TAG#v}" |
| 41 | +URL="https://github.com/${REPO_SLUG}/archive/refs/tags/${TAG}.tar.gz" |
| 42 | + |
| 43 | +echo "📌 Pinning formula at ${TAG}" |
| 44 | +echo " ${URL}" |
| 45 | + |
| 46 | +TARBALL="$(mktemp)" |
| 47 | +trap 'rm -f "$TARBALL"' EXIT |
| 48 | +curl -fsSL "$URL" -o "$TARBALL" |
| 49 | + |
| 50 | +if command -v sha256sum >/dev/null 2>&1; then |
| 51 | + SHA="$(sha256sum "$TARBALL" | awk '{print $1}')" |
| 52 | +else |
| 53 | + SHA="$(shasum -a 256 "$TARBALL" | awk '{print $1}')" |
| 54 | +fi |
| 55 | +[ -n "$SHA" ] || { echo "❌ Could not compute sha256." >&2; exit 1; } |
| 56 | +echo "🔑 sha256 ${SHA}" |
| 57 | + |
| 58 | +# Rewrite exactly the three pinned lines. Anchored to `^<ws>url `/`version `/ |
| 59 | +# `sha256 ` so the `head`, `homepage`, and comment lines are left untouched |
| 60 | +# (there is exactly one of each pinned line in the stanza). |
| 61 | +tmp="$(mktemp)" |
| 62 | +sed -E \ |
| 63 | + -e "s|^([[:space:]]*)url .*|\1url \"${URL}\"|" \ |
| 64 | + -e "s|^([[:space:]]*)version .*|\1version \"${VERSION}\"|" \ |
| 65 | + -e "s|^([[:space:]]*)sha256 .*|\1sha256 \"${SHA}\"|" \ |
| 66 | + "$FORMULA" > "$tmp" |
| 67 | +mv "$tmp" "$FORMULA" |
| 68 | + |
| 69 | +echo |
| 70 | +echo "✅ Updated $(git -C "$REPO_DIR" rev-parse --show-prefix 2>/dev/null)Formula/claude-usage.rb:" |
| 71 | +grep -E '^[[:space:]]*(url|version|sha256) ' "$FORMULA" | sed 's/^/ /' |
| 72 | +echo |
| 73 | +echo "➡ Review, then commit on DEV. It ships to brew users at the next DEV -> main release merge." |
0 commit comments