From dec9e82ee9783931c6774609508af12620cdc38c Mon Sep 17 00:00:00 2001 From: Reinier Criel Date: Mon, 13 Apr 2026 11:32:51 -0700 Subject: [PATCH] Some more improvements --- install-scripts/install-safe-chain.ps1 | 89 ++++++++------- install-scripts/install-safe-chain.sh | 109 +++++++++++------- install-scripts/uninstall-safe-chain.ps1 | 135 +++++++++++++---------- install-scripts/uninstall-safe-chain.sh | 88 +++++++++++---- 4 files changed, 257 insertions(+), 164 deletions(-) diff --git a/install-scripts/install-safe-chain.ps1 b/install-scripts/install-safe-chain.ps1 index ec0dcd6..3c43861 100644 --- a/install-scripts/install-safe-chain.ps1 +++ b/install-scripts/install-safe-chain.ps1 @@ -137,6 +137,53 @@ function Get-Architecture { } } +function Write-VersionDeprecationWarning { + if ([string]::IsNullOrWhiteSpace($env:SAFE_CHAIN_VERSION)) { + return + } + + Write-Warn "SAFE_CHAIN_VERSION environment variable is deprecated." + Write-Warn "" + Write-Warn "Please use direct download URLs for version pinning instead:" + Write-Warn "" + if ($ci) { + Write-Warn " iex `"& { `$(iwr 'https://github.com/AikidoSec/safe-chain/releases/download/$env:SAFE_CHAIN_VERSION/install-safe-chain.ps1' -UseBasicParsing) } -ci`"" + } else { + Write-Warn " iex (iwr `"https://github.com/AikidoSec/safe-chain/releases/download/$env:SAFE_CHAIN_VERSION/install-safe-chain.ps1`" -UseBasicParsing)" + } + Write-Warn "" +} + +function Get-BinaryName { + param([string]$Architecture) + + return "safe-chain-win-$Architecture.exe" +} + +function Invoke-SafeChainSetup { + param( + [string]$BinaryPath, + [string]$InstallDirectory + ) + + $setupCmd = if ($ci) { "setup-ci" } else { "setup" } + + Write-Info "Running safe-chain $setupCmd..." + try { + $env:Path = "$env:Path;$InstallDirectory" + & $BinaryPath $setupCmd + + if ($LASTEXITCODE -ne 0) { + Write-Warn "safe-chain was installed but setup encountered issues." + Write-Warn "You can run 'safe-chain $setupCmd' manually later." + } + } + catch { + Write-Warn "safe-chain was installed but setup encountered issues: $_" + Write-Warn "You can run 'safe-chain $setupCmd' manually later." + } +} + # Check and uninstall npm global package if present function Remove-NpmInstallation { # Check if npm is available @@ -188,19 +235,7 @@ function Remove-VoltaInstallation { # Main installation function Install-SafeChain { - # Show deprecation warning if SAFE_CHAIN_VERSION is set - if (-not [string]::IsNullOrWhiteSpace($env:SAFE_CHAIN_VERSION)) { - Write-Warn "SAFE_CHAIN_VERSION environment variable is deprecated." - Write-Warn "" - Write-Warn "Please use direct download URLs for version pinning instead:" - Write-Warn "" - if ($ci) { - Write-Warn " iex `"& { `$(iwr 'https://github.com/AikidoSec/safe-chain/releases/download/$env:SAFE_CHAIN_VERSION/install-safe-chain.ps1' -UseBasicParsing) } -ci`"" - } else { - Write-Warn " iex (iwr `"https://github.com/AikidoSec/safe-chain/releases/download/$env:SAFE_CHAIN_VERSION/install-safe-chain.ps1`" -UseBasicParsing)" - } - Write-Warn "" - } + Write-VersionDeprecationWarning # Fetch latest version if VERSION is not set if ([string]::IsNullOrWhiteSpace($Version)) { @@ -231,7 +266,7 @@ function Install-SafeChain { # Detect platform $arch = Get-Architecture - $binaryName = "safe-chain-win-$arch.exe" + $binaryName = Get-BinaryName -Architecture $arch Write-Info "Detected architecture: $arch" @@ -277,31 +312,7 @@ function Install-SafeChain { Write-Info "Binary installed to: $finalFile" - # Build setup command based on parameters - $setupCmd = if ($ci) { "setup-ci" } else { "setup" } - $setupArgs = @() - - # Execute safe-chain setup - Write-Info "Running safe-chain $setupCmd $(if ($setupArgs) { $setupArgs -join ' ' })..." - try { - $env:Path = "$env:Path;$InstallDir" - - if ($setupArgs) { - & $finalFile $setupCmd $setupArgs - } - else { - & $finalFile $setupCmd - } - - if ($LASTEXITCODE -ne 0) { - Write-Warn "safe-chain was installed but setup encountered issues." - Write-Warn "You can run 'safe-chain $setupCmd $(if ($setupArgs) { $setupArgs -join ' ' })' manually later." - } - } - catch { - Write-Warn "safe-chain was installed but setup encountered issues: $_" - Write-Warn "You can run 'safe-chain $setupCmd $(if ($setupArgs) { $setupArgs -join ' ' })' manually later." - } + Invoke-SafeChainSetup -BinaryPath $finalFile -InstallDirectory $InstallDir } # Run installation diff --git a/install-scripts/install-safe-chain.sh b/install-scripts/install-safe-chain.sh index 6a586e7..242dcf2 100755 --- a/install-scripts/install-safe-chain.sh +++ b/install-scripts/install-safe-chain.sh @@ -168,6 +168,68 @@ download() { fi } +warn_deprecated_version_env() { + if [ -z "$SAFE_CHAIN_VERSION" ]; then + return + fi + + warn "SAFE_CHAIN_VERSION environment variable is deprecated." + warn "" + warn "Please use direct download URLs for version pinning instead:" + warn "" + if [ "$USE_CI_SETUP" = "true" ]; then + warn " curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/${SAFE_CHAIN_VERSION}/install-safe-chain.sh | sh -s -- --ci" + else + warn " curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/${SAFE_CHAIN_VERSION}/install-safe-chain.sh | sh" + fi + warn "" +} + +ensure_version() { + if [ -n "$VERSION" ]; then + return + fi + + info "Fetching latest release version..." + VERSION=$(fetch_latest_version) +} + +get_binary_name() { + os="$1" + arch="$2" + + if [ "$os" = "win" ]; then + printf 'safe-chain-%s-%s.exe\n' "$os" "$arch" + else + printf 'safe-chain-%s-%s\n' "$os" "$arch" + fi +} + +get_final_binary_path() { + os="$1" + + if [ "$os" = "win" ]; then + printf '%s/safe-chain.exe\n' "$INSTALL_DIR" + else + printf '%s/safe-chain\n' "$INSTALL_DIR" + fi +} + +run_setup_command() { + final_file="$1" + + setup_cmd="setup" + if [ "$USE_CI_SETUP" = "true" ]; then + setup_cmd="setup-ci" + fi + + info "Running safe-chain $setup_cmd..." + if ! "$final_file" "$setup_cmd"; then + warn "safe-chain was installed but setup encountered issues." + warn "You can run 'safe-chain $setup_cmd' manually later." + fi +} + # Check and uninstall npm global package if present remove_npm_installation() { if ! command_exists npm; then @@ -308,25 +370,9 @@ main() { # Parse command-line arguments parse_arguments "$@" - # Show deprecation warning if SAFE_CHAIN_VERSION is set - if [ -n "$SAFE_CHAIN_VERSION" ]; then - warn "SAFE_CHAIN_VERSION environment variable is deprecated." - warn "" - warn "Please use direct download URLs for version pinning instead:" - warn "" - if [ "$USE_CI_SETUP" = "true" ]; then - warn " curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/${SAFE_CHAIN_VERSION}/install-safe-chain.sh | sh -s -- --ci" - else - warn " curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/${SAFE_CHAIN_VERSION}/install-safe-chain.sh | sh" - fi - warn "" - fi + warn_deprecated_version_env - # Fetch latest version if VERSION is not set - if [ -z "$VERSION" ]; then - info "Fetching latest release version..." - VERSION=$(fetch_latest_version) - fi + ensure_version # Check if the requested version is already installed if is_version_installed "$VERSION"; then @@ -350,11 +396,7 @@ main() { # Detect platform OS=$(detect_os) ARCH=$(detect_arch) - if [ "$OS" = "win" ]; then - BINARY_NAME="safe-chain-${OS}-${ARCH}.exe" - else - BINARY_NAME="safe-chain-${OS}-${ARCH}" - fi + BINARY_NAME=$(get_binary_name "$OS" "$ARCH") info "Detected platform: ${OS}-${ARCH}" @@ -372,11 +414,7 @@ main() { download "$DOWNLOAD_URL" "$TEMP_FILE" # Rename and make executable - if [ "$OS" = "win" ]; then - FINAL_FILE="${INSTALL_DIR}/safe-chain.exe" - else - FINAL_FILE="${INSTALL_DIR}/safe-chain" - fi + FINAL_FILE=$(get_final_binary_path "$OS") mv "$TEMP_FILE" "$FINAL_FILE" || error "Failed to move binary to $FINAL_FILE" if [ "$OS" != "win" ]; then chmod +x "$FINAL_FILE" || error "Failed to make binary executable" @@ -384,20 +422,7 @@ main() { info "Binary installed to: $FINAL_FILE" - # Build setup command based on arguments - SETUP_CMD="setup" - SETUP_ARGS="" - - if [ "$USE_CI_SETUP" = "true" ]; then - SETUP_CMD="setup-ci" - fi - - # Execute safe-chain setup - info "Running safe-chain $SETUP_CMD $SETUP_ARGS..." - if ! "$FINAL_FILE" $SETUP_CMD $SETUP_ARGS; then - warn "safe-chain was installed but setup encountered issues." - warn "You can run 'safe-chain $SETUP_CMD $SETUP_ARGS' manually later." - fi + run_setup_command "$FINAL_FILE" } main "$@" diff --git a/install-scripts/uninstall-safe-chain.ps1 b/install-scripts/uninstall-safe-chain.ps1 index 2aa3798..fea98f2 100644 --- a/install-scripts/uninstall-safe-chain.ps1 +++ b/install-scripts/uninstall-safe-chain.ps1 @@ -53,23 +53,39 @@ function Get-InstallDirFromBinaryPath { return (Split-Path -Parent $binDir) } -function Get-SafeChainInstallDir { - $command = Get-Command safe-chain -ErrorAction SilentlyContinue | Select-Object -First 1 - if ($command) { - try { - $reportedInstallDir = & safe-chain get-install-dir 2>$null | Select-Object -First 1 - if ($reportedInstallDir) { - $reportedInstallDir = $reportedInstallDir.Trim() - } - if ($reportedInstallDir) { - return $reportedInstallDir - } - } - catch { - # Fall back to deriving the install dir from the discovered command path - } +function Get-SafeChainCommand { + return Get-Command safe-chain -ErrorAction SilentlyContinue | Select-Object -First 1 +} + +function Get-ReportedInstallDir { + $command = Get-SafeChainCommand + if (-not $command) { + return $null } + try { + $reportedInstallDir = & safe-chain get-install-dir 2>$null | Select-Object -First 1 + if ($reportedInstallDir) { + $reportedInstallDir = $reportedInstallDir.Trim() + } + if ($reportedInstallDir) { + return $reportedInstallDir + } + } + catch { + return $null + } + + return $null +} + +function Get-SafeChainInstallDir { + $reportedInstallDir = Get-ReportedInstallDir + if ($reportedInstallDir) { + return $reportedInstallDir + } + + $command = Get-SafeChainCommand if ($command -and $command.Path) { $discoveredInstallDir = Get-InstallDirFromBinaryPath -BinaryPath $command.Path if ($discoveredInstallDir) { @@ -80,6 +96,49 @@ function Get-SafeChainInstallDir { return (Join-Path $HomeDir ".safe-chain") } +function Find-SafeChainBinary { + param([string]$DotSafeChain) + + $safeChainExe = Join-Path $DotSafeChain "bin/safe-chain.exe" + $safeChainBin = Join-Path $DotSafeChain "bin/safe-chain" + + if (Test-Path $safeChainExe) { + return $safeChainExe + } + + if (Test-Path $safeChainBin) { + return $safeChainBin + } + + $command = Get-SafeChainCommand + if ($command) { + return $command.Source + } + + return $null +} + +function Invoke-SafeChainTeardown { + param([string]$SafeChainPath) + + if (-not $SafeChainPath) { + Write-Warn "safe-chain command not found. Proceeding with uninstallation." + return + } + + Write-Info "Running safe-chain teardown..." + try { + & $SafeChainPath teardown + if ($LASTEXITCODE -ne 0) { + Write-Warn "safe-chain teardown encountered issues, continuing with uninstallation..." + } + } + catch { + Write-Warn "safe-chain teardown encountered issues: $_" + Write-Warn "Continuing with uninstallation..." + } +} + # Check and uninstall npm global package if present function Remove-NpmInstallation { # Check if npm is available @@ -133,50 +192,8 @@ function Remove-VoltaInstallation { function Uninstall-SafeChain { Write-Info "Uninstalling safe-chain..." $DotSafeChain = Get-SafeChainInstallDir - $InstallDir = Join-Path $DotSafeChain "bin" - - # Run teardown if safe-chain is available - # Check for both safe-chain.exe (Windows) and safe-chain (Unix) since PowerShell Core runs on all platforms - $safeChainExe = Join-Path $InstallDir "safe-chain.exe" - $safeChainBin = Join-Path $InstallDir "safe-chain" - - $safeChainPath = $null - if (Test-Path $safeChainExe) { - $safeChainPath = $safeChainExe - } - elseif (Test-Path $safeChainBin) { - $safeChainPath = $safeChainBin - } - - if ($safeChainPath) { - Write-Info "Running safe-chain teardown..." - try { - & $safeChainPath teardown - if ($LASTEXITCODE -ne 0) { - Write-Warn "safe-chain teardown encountered issues, continuing with uninstallation..." - } - } - catch { - Write-Warn "safe-chain teardown encountered issues: $_" - Write-Warn "Continuing with uninstallation..." - } - } - elseif (Get-Command safe-chain -ErrorAction SilentlyContinue) { - Write-Info "Running safe-chain teardown..." - try { - safe-chain teardown - if ($LASTEXITCODE -ne 0) { - Write-Warn "safe-chain teardown encountered issues, continuing with uninstallation..." - } - } - catch { - Write-Warn "safe-chain teardown encountered issues: $_" - Write-Warn "Continuing with uninstallation..." - } - } - else { - Write-Warn "safe-chain command not found. Proceeding with uninstallation." - } + $safeChainPath = Find-SafeChainBinary -DotSafeChain $DotSafeChain + Invoke-SafeChainTeardown -SafeChainPath $safeChainPath # Remove npm and Volta installations Remove-NpmInstallation diff --git a/install-scripts/uninstall-safe-chain.sh b/install-scripts/uninstall-safe-chain.sh index 4169e1e..89bb270 100755 --- a/install-scripts/uninstall-safe-chain.sh +++ b/install-scripts/uninstall-safe-chain.sh @@ -87,24 +87,74 @@ derive_install_dir_from_binary() { } get_install_dir() { - if command_exists safe-chain; then - install_dir=$(safe-chain get-install-dir 2>/dev/null || true) - if [ -n "$install_dir" ]; then - printf '%s\n' "$install_dir" - return 0 - fi + reported_install_dir=$(get_reported_install_dir) + if [ -n "$reported_install_dir" ]; then + printf '%s\n' "$reported_install_dir" + return 0 + fi - command_path=$(command -v safe-chain) - install_dir=$(derive_install_dir_from_binary "$command_path" || true) - if [ -n "$install_dir" ]; then - printf '%s\n' "$install_dir" - return 0 - fi + command_path=$(get_safe_chain_command_path) + install_dir=$(derive_install_dir_from_binary "$command_path" || true) + if [ -n "$install_dir" ]; then + printf '%s\n' "$install_dir" + return 0 fi printf '%s\n' "${HOME}/.safe-chain" } +get_safe_chain_command_path() { + if ! command_exists safe-chain; then + return 1 + fi + + command -v safe-chain +} + +get_reported_install_dir() { + if ! command_exists safe-chain; then + return 1 + fi + + install_dir=$(safe-chain get-install-dir 2>/dev/null || true) + if [ -n "$install_dir" ]; then + printf '%s\n' "$install_dir" + return 0 + fi + + return 1 +} + +find_installed_safe_chain_binary() { + dot_safe_chain="$1" + + safe_chain_location="$dot_safe_chain/bin/safe-chain" + if [ -x "$safe_chain_location" ]; then + printf '%s\n' "$safe_chain_location" + return 0 + fi + + command_path=$(get_safe_chain_command_path || true) + if [ -n "$command_path" ]; then + printf '%s\n' "$command_path" + return 0 + fi + + return 1 +} + +run_safe_chain_teardown() { + safe_chain_command="$1" + + if [ -z "$safe_chain_command" ]; then + warn "safe-chain command not found. Proceeding with uninstallation." + return + fi + + info "Running safe-chain teardown..." + "$safe_chain_command" teardown || warn "safe-chain teardown encountered issues, continuing with uninstallation..." +} + # Check and uninstall npm global package if present remove_npm_installation() { if ! command_exists npm; then @@ -211,17 +261,8 @@ remove_nvm_installation() { # Main uninstallation main() { DOT_SAFE_CHAIN=$(get_install_dir) - SAFE_CHAIN_LOCATION="$DOT_SAFE_CHAIN/bin/safe-chain" - - if [ -x "$SAFE_CHAIN_LOCATION" ]; then - info "Running safe-chain teardown..." - "$SAFE_CHAIN_LOCATION" teardown || warn "safe-chain teardown encountered issues, continuing with uninstallation..." - elif command_exists safe-chain; then - info "Running safe-chain teardown..." - safe-chain teardown || warn "safe-chain teardown encountered issues, continuing with uninstallation..." - else - warn "safe-chain command not found. Proceeding with uninstallation." - fi + SAFE_CHAIN_COMMAND=$(find_installed_safe_chain_binary "$DOT_SAFE_CHAIN" || true) + run_safe_chain_teardown "$SAFE_CHAIN_COMMAND" # Check for existing safe-chain installation through nvm, volta, or npm remove_npm_installation @@ -235,7 +276,6 @@ main() { else info "Installation directory $DOT_SAFE_CHAIN does not exist. Nothing to remove." fi - } main "$@"