diff --git a/README.md b/README.md index 87234eb2f..584784e74 100644 --- a/README.md +++ b/README.md @@ -48,10 +48,25 @@ By default, the installer uses bun if available, otherwise downloads the prebuil Options: - `--source` / `-Source`: Install via bun (installs bun first if needed) - `--binary` / `-Binary`: Always use prebuilt binary +- `--ref ` / `-Ref `: Install a tag/commit/branch (defaults to source install) ```bash # Force bun installation curl -fsSL .../install.sh | sh -s -- --source + +# Install a tag via binary +curl -fsSL .../install.sh | sh -s -- --binary --ref v3.20.1 + +# Install a branch or commit via source +curl -fsSL .../install.sh | sh -s -- --source --ref main +``` + +```powershell +# Install a tag via binary +& ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Binary -Ref v3.20.1 + +# Install a branch or commit via source +& ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source -Ref main ``` ### Manual download diff --git a/scripts/install.ps1 b/scripts/install.ps1 index b48e04c42..13a14edba 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -4,10 +4,14 @@ # Or with options: # & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source # & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Binary +# & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source -Ref v3.20.1 +# & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source -Ref main +# & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Binary -Ref v3.20.1 param( [switch]$Source, - [switch]$Binary + [switch]$Binary, + [string]$Ref ) $ErrorActionPreference = "Stop" @@ -26,6 +30,15 @@ function Test-BunInstalled { } } +function Test-GitInstalled { + try { + $null = Get-Command git -ErrorAction Stop + return $true + } catch { + return $false + } +} + function Install-Bun { Write-Host "Installing bun..." irm bun.sh/install.ps1 | iex @@ -35,18 +48,70 @@ function Install-Bun { function Install-ViaBun { Write-Host "Installing via bun..." - bun install -g $Package + if ($Ref) { + if (-not (Test-GitInstalled)) { + throw "git is required for -Ref when installing from source" + } + + $tmpRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("omp-install-" + [System.Guid]::NewGuid().ToString("N")) + New-Item -ItemType Directory -Force -Path $tmpRoot | Out-Null + + try { + $repoUrl = "https://github.com/$Repo.git" + $cloneOk = $false + try { + git clone --depth 1 --branch $Ref $repoUrl $tmpRoot | Out-Null + $cloneOk = $true + } catch { + $cloneOk = $false + } + + if (-not $cloneOk) { + git clone $repoUrl $tmpRoot | Out-Null + Push-Location $tmpRoot + try { + git checkout $Ref | Out-Null + } finally { + Pop-Location + } + } + + $packagePath = Join-Path $tmpRoot "packages\coding-agent" + if (-not (Test-Path $packagePath)) { + throw "Expected package at $packagePath" + } + + bun install -g $packagePath + } finally { + Remove-Item -Recurse -Force $tmpRoot -ErrorAction SilentlyContinue + } + } else { + bun install -g $Package + } + Write-Host "" Write-Host "✓ Installed omp via bun" -ForegroundColor Green Write-Host "Run 'omp' to get started!" } function Install-Binary { - # Get latest release - Write-Host "Fetching latest release..." - $Release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest" + if ($Ref) { + Write-Host "Fetching release $Ref..." + try { + $Release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/tags/$Ref" + } catch { + throw "Release tag not found: $Ref`nFor branch/commit installs, use -Source with -Ref." + } + } else { + Write-Host "Fetching latest release..." + $Release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest" + } + $Latest = $Release.tag_name - Write-Host "Latest version: $Latest" + if (-not $Latest) { + throw "Failed to fetch release tag" + } + Write-Host "Using version: $Latest" # Download binary $Url = "https://github.com/$Repo/releases/download/$Latest/$BinaryName" @@ -71,6 +136,10 @@ function Install-Binary { } # Main logic +if ($Ref -and -not $Source -and -not $Binary) { + $Source = $true +} + if ($Source) { if (-not (Test-BunInstalled)) { Install-Bun diff --git a/scripts/install.sh b/scripts/install.sh index c37153b88..4af49e0fb 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -5,8 +5,10 @@ set -e # Usage: curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh # # Options: -# --source Install via bun (installs bun if needed) -# --binary Always install prebuilt binary +# --source Install via bun (installs bun if needed) +# --binary Always install prebuilt binary +# --ref Install specific tag/commit/branch +# -r Shorthand for --ref REPO="can1357/oh-my-pi" PACKAGE="@oh-my-pi/omp-coding-agent" @@ -14,18 +16,60 @@ INSTALL_DIR="${OMP_INSTALL_DIR:-$HOME/.local/bin}" # Parse arguments MODE="" -for arg in "$@"; do - case "$arg" in - --source) MODE="source" ;; - --binary) MODE="binary" ;; +REF="" +while [ $# -gt 0 ]; do + case "$1" in + --source) + MODE="source" + shift + ;; + --binary) + MODE="binary" + shift + ;; + --ref) + shift + if [ -z "$1" ]; then + echo "Missing value for --ref" + exit 1 + fi + REF="$1" + shift + ;; + --ref=*) + REF="${1#*=}" + shift + ;; + -r) + shift + if [ -z "$1" ]; then + echo "Missing value for -r" + exit 1 + fi + REF="$1" + shift + ;; + *) + shift + ;; esac done +# If a ref is provided, default to source install +if [ -n "$REF" ] && [ -z "$MODE" ]; then + MODE="source" +fi + # Check if bun is available has_bun() { command -v bun >/dev/null 2>&1 } +# Check if git is available +has_git() { + command -v git >/dev/null 2>&1 +} + # Install bun install_bun() { echo "Installing bun..." @@ -37,7 +81,31 @@ install_bun() { # Install via bun install_via_bun() { echo "Installing via bun..." - bun install -g "$PACKAGE" + if [ -n "$REF" ]; then + if ! has_git; then + echo "git is required for --ref when installing from source" + exit 1 + fi + + TMP_DIR="$(mktemp -d)" + trap 'rm -rf "$TMP_DIR"' EXIT + + if git clone --depth 1 --branch "$REF" "https://github.com/${REPO}.git" "$TMP_DIR" >/dev/null 2>&1; then + : + else + git clone "https://github.com/${REPO}.git" "$TMP_DIR" + (cd "$TMP_DIR" && git checkout "$REF") + fi + + if [ ! -d "$TMP_DIR/packages/coding-agent" ]; then + echo "Expected package at ${TMP_DIR}/packages/coding-agent" + exit 1 + fi + + bun install -g "$TMP_DIR/packages/coding-agent" + else + bun install -g "$PACKAGE" + fi echo "" echo "✓ Installed omp via bun" echo "Run 'omp' to get started!" @@ -63,14 +131,26 @@ install_binary() { BINARY="omp-${PLATFORM}-${ARCH}" - # Get latest release tag - echo "Fetching latest release..." - LATEST=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + # Get release tag + if [ -n "$REF" ]; then + echo "Fetching release $REF..." + if RELEASE_JSON=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/tags/${REF}"); then + LATEST=$(echo "$RELEASE_JSON" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + else + echo "Release tag not found: $REF" + echo "For branch/commit installs, use --source with --ref." + exit 1 + fi + else + echo "Fetching latest release..." + RELEASE_JSON=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest") + LATEST=$(echo "$RELEASE_JSON" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + fi if [ -z "$LATEST" ]; then - echo "Failed to fetch latest release" + echo "Failed to fetch release tag" exit 1 fi - echo "Latest version: $LATEST" + echo "Using version: $LATEST" # Download binary URL="https://github.com/${REPO}/releases/download/${LATEST}/${BINARY}"