install.sh
install.shBrowse 14 files
2,485 tokens
7,581 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1#!/usr/bin/env bash2#3# install.sh - install the ast-grep binary on POSIX systems (macOS, Linux, WSL, Git Bash).4#5# Tries package managers in priority order, then falls back to downloading a6# pinned release binary from GitHub into <skill_root>/bin/sg.7#8# Order:9# 1. Already installed? -> nothing to do10# 2. Homebrew (brew)11# 3. npm (@ast-grep/cli)12# 4. cargo binstall (faster) or cargo install (slower)13# 5. pip (ast-grep-cli)14# 6. nix-env (NixOS / Nix users)15# 7. mise (asdf successor)16# 8. GitHub release tarball -> <skill_root>/bin/sg17#18# Flags:19# --method=<m> Force one method: brew | npm | cargo | pip | nix | mise | github20# --version=<v> Pin a specific version when downloading from GitHub21# --no-fallback Don't fall back to GitHub tarball; fail if all package managers miss22# --quiet, -q Suppress non-error output23#24# Exit codes:25# 0 Installed (or already present)26# 1 Argument error27# 2 All install methods failed28# 3 Network failure during GitHub fallback29 30set -euo pipefail31 32SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"33SKILL_ROOT="$SCRIPT_DIR"34CACHE_BIN_DIR="${OMO_AST_GREP_BIN_DIR:-$SKILL_ROOT/bin}"35 36PINNED_VERSION="0.45.0"37FORCED_METHOD=""38USE_FALLBACK=139QUIET=040 41log() {42 if [ "$QUIET" -eq 0 ]; then43 printf '[install.sh] %s\n' "$*" >&244 fi45}46 47err() {48 printf '[install.sh] error: %s\n' "$*" >&249}50 51usage() {52 sed -n '2,/^set -/p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//;/^set -/d'53 exit "${1:-0}"54}55 56while [ "$#" -gt 0 ]; do57 case "$1" in58 --method=*) FORCED_METHOD="${1#*=}" ;;59 --version=*) PINNED_VERSION="${1#*=}" ;;60 --no-fallback) USE_FALLBACK=0 ;;61 --quiet|-q) QUIET=1 ;;62 --help|-h) usage 0 ;;63 *) err "unknown argument: $1"; usage 1 ;;64 esac65 shift66done67 68# --- detect platform -----------------------------------------------------69 70detect_os() {71 case "$(uname -s)" in72 Darwin) echo "darwin" ;;73 Linux) echo "linux" ;;74 MINGW*|MSYS*|CYGWIN*) echo "windows" ;;75 *) echo "unknown" ;;76 esac77}78 79detect_arch() {80 case "$(uname -m)" in81 arm64|aarch64) echo "aarch64" ;;82 x86_64|amd64) echo "x86_64" ;;83 *) echo "unknown" ;;84 esac85}86 87OS="$(detect_os)"88ARCH="$(detect_arch)"89 90# --- already installed? --------------------------------------------------91 92ast_grep_present() {93 if command -v ast-grep >/dev/null 2>&1; then94 return 095 fi96 if command -v sg >/dev/null 2>&1; then97 if [ "$OS" = "linux" ]; then98 if "$(command -v sg)" --version 2>/dev/null | grep -qi 'ast-grep'; then99 return 0100 fi101 return 1102 fi103 return 0104 fi105 if [ -x "$CACHE_BIN_DIR/sg" ] || [ -x "$CACHE_BIN_DIR/ast-grep" ]; then106 return 0107 fi108 return 1109}110 111if [ -z "$FORCED_METHOD" ] && ast_grep_present; then112 log "ast-grep already installed: $(command -v ast-grep 2>/dev/null || command -v sg)"113 exit 0114fi115 116# --- per-method installers -----------------------------------------------117 118try_brew() {119 command -v brew >/dev/null 2>&1 || return 1120 log "trying: brew install ast-grep"121 brew install ast-grep && return 0 || return 1122}123 124try_npm() {125 command -v npm >/dev/null 2>&1 || return 1126 log "trying: npm install -g @ast-grep/cli"127 npm install -g @ast-grep/cli && return 0 || return 1128}129 130try_cargo() {131 if command -v cargo-binstall >/dev/null 2>&1; then132 log "trying: cargo binstall ast-grep"133 cargo binstall -y ast-grep && return 0 || true134 fi135 if command -v cargo >/dev/null 2>&1; then136 log "trying: cargo install ast-grep --locked"137 cargo install ast-grep --locked && return 0 || return 1138 fi139 return 1140}141 142try_pip() {143 if command -v pipx >/dev/null 2>&1; then144 log "trying: pipx install ast-grep-cli"145 pipx install ast-grep-cli && return 0 || true146 fi147 command -v pip3 >/dev/null 2>&1 || command -v pip >/dev/null 2>&1 || return 1148 PIP="$(command -v pip3 || command -v pip)"149 log "trying: $PIP install --user ast-grep-cli"150 $PIP install --user ast-grep-cli && return 0 || return 1151}152 153try_nix() {154 command -v nix-env >/dev/null 2>&1 || return 1155 log "trying: nix-env -iA nixpkgs.ast-grep"156 nix-env -iA nixpkgs.ast-grep && return 0 || return 1157}158 159try_mise() {160 command -v mise >/dev/null 2>&1 || return 1161 log "trying: mise use -g ast-grep"162 mise use -g ast-grep && return 0 || return 1163}164 165# Tarball assets are named like:166# app-aarch64-apple-darwin.zip167# app-x86_64-apple-darwin.zip168# app-aarch64-unknown-linux-gnu.zip169# app-x86_64-unknown-linux-gnu.zip170# app-x86_64-pc-windows-msvc.zip (.zip only on windows)171 172triple_for() {173 case "$OS-$ARCH" in174 darwin-aarch64) echo "aarch64-apple-darwin" ;;175 darwin-x86_64) echo "x86_64-apple-darwin" ;;176 linux-aarch64) echo "aarch64-unknown-linux-gnu" ;;177 linux-x86_64) echo "x86_64-unknown-linux-gnu" ;;178 *) echo "" ;;179 esac180}181 182try_github() {183 TRIPLE="$(triple_for)"184 if [ -z "$TRIPLE" ]; then185 err "no GitHub release asset for $OS-$ARCH; install via package manager or build from source."186 return 1187 fi188 189 command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || {190 err "need curl or wget for GitHub fallback"191 return 1192 }193 194 ASSET="app-${TRIPLE}.zip"195 URL="https://github.com/ast-grep/ast-grep/releases/download/${PINNED_VERSION}/${ASSET}"196 TMP="$(mktemp -d -t ast-grep-install-XXXXXX)"197 trap 'rm -rf "$TMP"' RETURN198 199 log "downloading $URL"200 if command -v curl >/dev/null 2>&1; then201 curl -fsSL "$URL" -o "$TMP/$ASSET" || return 3202 else203 wget -q "$URL" -O "$TMP/$ASSET" || return 3204 fi205 206 command -v unzip >/dev/null 2>&1 || {207 err "need 'unzip' to extract GitHub release archives"208 return 1209 }210 211 unzip -q "$TMP/$ASSET" -d "$TMP/extract"212 mkdir -p "$CACHE_BIN_DIR"213 if [ -f "$TMP/extract/ast-grep" ]; then214 mv "$TMP/extract/ast-grep" "$CACHE_BIN_DIR/sg"215 elif [ -f "$TMP/extract/sg" ]; then216 mv "$TMP/extract/sg" "$CACHE_BIN_DIR/sg"217 else218 err "no ast-grep or sg binary found inside $ASSET"219 return 1220 fi221 chmod +x "$CACHE_BIN_DIR/sg"222 223 log "installed cached binary: $CACHE_BIN_DIR/sg"224 log "verify: $CACHE_BIN_DIR/sg --version"225 log ""226 log "Add to PATH for direct sg use:"227 log " export PATH=\"$CACHE_BIN_DIR:\$PATH\""228 return 0229}230 231# --- dispatch ------------------------------------------------------------232 233run_method() {234 case "$1" in235 brew) try_brew ;;236 npm) try_npm ;;237 cargo) try_cargo ;;238 pip) try_pip ;;239 nix) try_nix ;;240 mise) try_mise ;;241 github) try_github ;;242 *) err "unknown method: $1"; return 1 ;;243 esac244}245 246if [ -n "$FORCED_METHOD" ]; then247 if run_method "$FORCED_METHOD"; then248 exit 0249 else250 err "method '$FORCED_METHOD' failed"251 exit 2252 fi253fi254 255# Try methods in OS-aware priority order.256case "$OS" in257 darwin) METHODS=(brew npm cargo pip mise) ;;258 linux) METHODS=(npm cargo pip nix mise brew) ;;259 windows) METHODS=(npm cargo pip mise) ;;260 *) METHODS=(npm cargo pip) ;;261esac262 263for m in "${METHODS[@]}"; do264 if run_method "$m"; then265 log "installed via $m"266 exit 0267 fi268 log "$m unavailable or failed; trying next"269done270 271if [ "$USE_FALLBACK" -eq 1 ]; then272 log "all package managers failed; falling back to GitHub release"273 if try_github; then274 exit 0275 fi276fi277 278err "all install methods failed."279err ""280err "Manual options:"281err " brew install ast-grep # macOS / linuxbrew"282err " npm install -g @ast-grep/cli # any OS with Node"283err " cargo install ast-grep --locked # any OS with Rust"284err " pip install ast-grep-cli # any OS with Python"285err " https://github.com/ast-grep/ast-grep/releases # manual binary"286exit 2287 Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 19.SKILL.mdView in source ↗19This skill ships a Python wrapper at `scripts/ast_grep_helper.py` and platform install scripts at `install.sh` (POSIX) and `install.ps1` (Windows). The helper adds offline pattern validation, the two-pass write trick, and binary auto-resolution. Use it as your default entry point.
Source excerpt starting at line 144.SKILL.mdView in source ↗144python scripts/ast_grep_helper.py doctor # check ast-grep binary availability145python scripts/ast_grep_helper.py install # delegate to install.sh / install.ps1146```
Source excerpt starting at line 275.2756. `references/sgconfig.md` — project-level configuration. Read when you set up `sg scan` for a real project.2767. `references/install.md` — per-OS install methods. Read only if `install.sh` / `install.ps1` fail.