diff --git a/install/bash/install.sh b/install/bash/install.sh index 72b55a93..dfd371e2 100755 --- a/install/bash/install.sh +++ b/install/bash/install.sh @@ -42,6 +42,38 @@ install_uv() { export PATH="$HOME/.local/bin:$PATH" } +# A stale shim can make git resolvable without a working git behind it, so +# verify git actually runs rather than trusting command -v alone. +git_available() { + command -v git &> /dev/null && git --version &> /dev/null +} + +# Print install instructions for the current platform and exit. codeplain uses +# git to checkpoint the code it renders, and GitPython fails at import time +# when the git executable is missing, so 'codeplain --status' would die with a +# raw traceback that says nothing about the actual cause. +require_git() { + echo -e " ${YELLOW}${BOLD}Git is required to continue, but it doesn't appear to be installed.${NC}" + echo "" + echo -e " Please install Git by following the instructions on the official Git website:" + echo "" + case "$OSTYPE" in + darwin*) + echo -e " ${WHITE}${BOLD}https://git-scm.com/install/mac${NC}" + ;; + msys* | cygwin* | win32*) + echo -e " ${WHITE}${BOLD}https://git-scm.com/install/win${NC}" + ;; + *) + echo -e " ${WHITE}${BOLD}https://git-scm.com/install/linux${NC}" + ;; + esac + echo "" + echo -e " ${GRAY}Once Git is installed, restart your terminal and run this installer again.${NC}" + echo "" + exit 1 +} + # Trim leading/trailing whitespace (spaces, tabs, newlines, carriage returns). # Users often copy the API key with surrounding whitespace or newlines. trim_whitespace() { @@ -77,6 +109,15 @@ fi echo -e "${GREEN}✓${NC} uv detected" echo -e "" +# Checked here, alongside uv, so a missing prerequisite stops the installer +# before the user answers any prompts rather than at the --status check below. +if ! git_available; then + require_git +fi + +echo -e "${GREEN}✓${NC} git detected" +echo -e "" + # Install or upgrade codeplain using uv tool if uv tool list 2>/dev/null | grep -q "^codeplain"; then CURRENT_VERSION=$(uv tool list 2>/dev/null | grep "^codeplain" | sed 's/codeplain v//') diff --git a/install/powershell/install.ps1 b/install/powershell/install.ps1 index 0ac18e80..a466cc59 100644 --- a/install/powershell/install.ps1 +++ b/install/powershell/install.ps1 @@ -61,6 +61,40 @@ function Install-Uv { } } +# A stale shim can make git resolvable without a working git behind it, so +# verify git actually runs rather than trusting Get-Command alone. +function Test-GitAvailable { + if (-not (Get-Command git -ErrorAction SilentlyContinue)) { return $false } + try { + & git --version *> $null + return ($LASTEXITCODE -eq 0) + } catch { + return $false + } +} + +# Print install instructions for the current platform and exit. codeplain uses +# git to checkpoint the code it renders, and GitPython fails at import time +# when the git executable is missing, so 'codeplain --status' would die with a +# raw traceback that says nothing about the actual cause. +function Assert-Git { + Write-Host " ${YELLOW}${BOLD}Git is required to continue, but it doesn't appear to be installed.${NC}" + Write-Host "" + Write-Host " Please install Git by following the instructions on the official Git website:" + Write-Host "" + if ($IsWindows -or ($env:OS -eq "Windows_NT")) { + Write-Host " ${WHITE}${BOLD}https://git-scm.com/install/win${NC}" + } elseif ($IsMacOS) { + Write-Host " ${WHITE}${BOLD}https://git-scm.com/install/mac${NC}" + } else { + Write-Host " ${WHITE}${BOLD}https://git-scm.com/install/linux${NC}" + } + Write-Host "" + Write-Host " ${GRAY}Once Git is installed, restart your terminal and run this installer again.${NC}" + Write-Host "" + exit 1 +} + # Verify an API key against the Codeplain API's /status endpoint. # Returns a status string: "valid" (HTTP 200), "invalid" (HTTP 401), or # "error" (could not reach the API). This checks only the API key. @@ -99,6 +133,15 @@ if (-not (Get-Command uv -ErrorAction SilentlyContinue)) { Write-Host "${GREEN}✓${NC} uv detected" Write-Host "" +# Checked here, alongside uv, so a missing prerequisite stops the installer +# before the user answers any prompts rather than at the --status check below. +if (-not (Test-GitAvailable)) { + Assert-Git +} + +Write-Host "${GREEN}✓${NC} git detected" +Write-Host "" + try { $uvOutput = uv tool list 2>$null } catch {