Some more improvements

This commit is contained in:
Reinier Criel 2026-04-13 11:32:51 -07:00
parent 72dc7dcf3a
commit dec9e82ee9
4 changed files with 257 additions and 164 deletions

View file

@ -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 # Check and uninstall npm global package if present
function Remove-NpmInstallation { function Remove-NpmInstallation {
# Check if npm is available # Check if npm is available
@ -188,19 +235,7 @@ function Remove-VoltaInstallation {
# Main installation # Main installation
function Install-SafeChain { function Install-SafeChain {
# Show deprecation warning if SAFE_CHAIN_VERSION is set Write-VersionDeprecationWarning
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 ""
}
# Fetch latest version if VERSION is not set # Fetch latest version if VERSION is not set
if ([string]::IsNullOrWhiteSpace($Version)) { if ([string]::IsNullOrWhiteSpace($Version)) {
@ -231,7 +266,7 @@ function Install-SafeChain {
# Detect platform # Detect platform
$arch = Get-Architecture $arch = Get-Architecture
$binaryName = "safe-chain-win-$arch.exe" $binaryName = Get-BinaryName -Architecture $arch
Write-Info "Detected architecture: $arch" Write-Info "Detected architecture: $arch"
@ -277,31 +312,7 @@ function Install-SafeChain {
Write-Info "Binary installed to: $finalFile" Write-Info "Binary installed to: $finalFile"
# Build setup command based on parameters Invoke-SafeChainSetup -BinaryPath $finalFile -InstallDirectory $InstallDir
$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."
}
} }
# Run installation # Run installation

View file

@ -168,6 +168,68 @@ download() {
fi 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 # Check and uninstall npm global package if present
remove_npm_installation() { remove_npm_installation() {
if ! command_exists npm; then if ! command_exists npm; then
@ -308,25 +370,9 @@ main() {
# Parse command-line arguments # Parse command-line arguments
parse_arguments "$@" parse_arguments "$@"
# Show deprecation warning if SAFE_CHAIN_VERSION is set warn_deprecated_version_env
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
# Fetch latest version if VERSION is not set ensure_version
if [ -z "$VERSION" ]; then
info "Fetching latest release version..."
VERSION=$(fetch_latest_version)
fi
# Check if the requested version is already installed # Check if the requested version is already installed
if is_version_installed "$VERSION"; then if is_version_installed "$VERSION"; then
@ -350,11 +396,7 @@ main() {
# Detect platform # Detect platform
OS=$(detect_os) OS=$(detect_os)
ARCH=$(detect_arch) ARCH=$(detect_arch)
if [ "$OS" = "win" ]; then BINARY_NAME=$(get_binary_name "$OS" "$ARCH")
BINARY_NAME="safe-chain-${OS}-${ARCH}.exe"
else
BINARY_NAME="safe-chain-${OS}-${ARCH}"
fi
info "Detected platform: ${OS}-${ARCH}" info "Detected platform: ${OS}-${ARCH}"
@ -372,11 +414,7 @@ main() {
download "$DOWNLOAD_URL" "$TEMP_FILE" download "$DOWNLOAD_URL" "$TEMP_FILE"
# Rename and make executable # Rename and make executable
if [ "$OS" = "win" ]; then FINAL_FILE=$(get_final_binary_path "$OS")
FINAL_FILE="${INSTALL_DIR}/safe-chain.exe"
else
FINAL_FILE="${INSTALL_DIR}/safe-chain"
fi
mv "$TEMP_FILE" "$FINAL_FILE" || error "Failed to move binary to $FINAL_FILE" mv "$TEMP_FILE" "$FINAL_FILE" || error "Failed to move binary to $FINAL_FILE"
if [ "$OS" != "win" ]; then if [ "$OS" != "win" ]; then
chmod +x "$FINAL_FILE" || error "Failed to make binary executable" chmod +x "$FINAL_FILE" || error "Failed to make binary executable"
@ -384,20 +422,7 @@ main() {
info "Binary installed to: $FINAL_FILE" info "Binary installed to: $FINAL_FILE"
# Build setup command based on arguments run_setup_command "$FINAL_FILE"
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
} }
main "$@" main "$@"

View file

@ -53,9 +53,16 @@ function Get-InstallDirFromBinaryPath {
return (Split-Path -Parent $binDir) return (Split-Path -Parent $binDir)
} }
function Get-SafeChainInstallDir { function Get-SafeChainCommand {
$command = Get-Command safe-chain -ErrorAction SilentlyContinue | Select-Object -First 1 return Get-Command safe-chain -ErrorAction SilentlyContinue | Select-Object -First 1
if ($command) { }
function Get-ReportedInstallDir {
$command = Get-SafeChainCommand
if (-not $command) {
return $null
}
try { try {
$reportedInstallDir = & safe-chain get-install-dir 2>$null | Select-Object -First 1 $reportedInstallDir = & safe-chain get-install-dir 2>$null | Select-Object -First 1
if ($reportedInstallDir) { if ($reportedInstallDir) {
@ -66,10 +73,19 @@ function Get-SafeChainInstallDir {
} }
} }
catch { catch {
# Fall back to deriving the install dir from the discovered command path return $null
}
} }
return $null
}
function Get-SafeChainInstallDir {
$reportedInstallDir = Get-ReportedInstallDir
if ($reportedInstallDir) {
return $reportedInstallDir
}
$command = Get-SafeChainCommand
if ($command -and $command.Path) { if ($command -and $command.Path) {
$discoveredInstallDir = Get-InstallDirFromBinaryPath -BinaryPath $command.Path $discoveredInstallDir = Get-InstallDirFromBinaryPath -BinaryPath $command.Path
if ($discoveredInstallDir) { if ($discoveredInstallDir) {
@ -80,6 +96,49 @@ function Get-SafeChainInstallDir {
return (Join-Path $HomeDir ".safe-chain") 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 # Check and uninstall npm global package if present
function Remove-NpmInstallation { function Remove-NpmInstallation {
# Check if npm is available # Check if npm is available
@ -133,50 +192,8 @@ function Remove-VoltaInstallation {
function Uninstall-SafeChain { function Uninstall-SafeChain {
Write-Info "Uninstalling safe-chain..." Write-Info "Uninstalling safe-chain..."
$DotSafeChain = Get-SafeChainInstallDir $DotSafeChain = Get-SafeChainInstallDir
$InstallDir = Join-Path $DotSafeChain "bin" $safeChainPath = Find-SafeChainBinary -DotSafeChain $DotSafeChain
Invoke-SafeChainTeardown -SafeChainPath $safeChainPath
# 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."
}
# Remove npm and Volta installations # Remove npm and Volta installations
Remove-NpmInstallation Remove-NpmInstallation

View file

@ -87,22 +87,72 @@ derive_install_dir_from_binary() {
} }
get_install_dir() { get_install_dir() {
if command_exists safe-chain; then reported_install_dir=$(get_reported_install_dir)
if [ -n "$reported_install_dir" ]; then
printf '%s\n' "$reported_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) install_dir=$(safe-chain get-install-dir 2>/dev/null || true)
if [ -n "$install_dir" ]; then if [ -n "$install_dir" ]; then
printf '%s\n' "$install_dir" printf '%s\n' "$install_dir"
return 0 return 0
fi fi
command_path=$(command -v safe-chain) return 1
install_dir=$(derive_install_dir_from_binary "$command_path" || true) }
if [ -n "$install_dir" ]; then
printf '%s\n' "$install_dir" 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 return 0
fi fi
command_path=$(get_safe_chain_command_path || true)
if [ -n "$command_path" ]; then
printf '%s\n' "$command_path"
return 0
fi fi
printf '%s\n' "${HOME}/.safe-chain" 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 # Check and uninstall npm global package if present
@ -211,17 +261,8 @@ remove_nvm_installation() {
# Main uninstallation # Main uninstallation
main() { main() {
DOT_SAFE_CHAIN=$(get_install_dir) DOT_SAFE_CHAIN=$(get_install_dir)
SAFE_CHAIN_LOCATION="$DOT_SAFE_CHAIN/bin/safe-chain" SAFE_CHAIN_COMMAND=$(find_installed_safe_chain_binary "$DOT_SAFE_CHAIN" || true)
run_safe_chain_teardown "$SAFE_CHAIN_COMMAND"
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
# Check for existing safe-chain installation through nvm, volta, or npm # Check for existing safe-chain installation through nvm, volta, or npm
remove_npm_installation remove_npm_installation
@ -235,7 +276,6 @@ main() {
else else
info "Installation directory $DOT_SAFE_CHAIN does not exist. Nothing to remove." info "Installation directory $DOT_SAFE_CHAIN does not exist. Nothing to remove."
fi fi
} }
main "$@" main "$@"