rskiller 0.2.1

Find and clean Rust project build artifacts and caches with parallel processing
Documentation
#
# rskiller PowerShell installer script
# This script detects the platform and installs the appropriate binary for Windows
#

param(
    [string]$InstallDir = "$env:ProgramFiles\rskiller",
    [switch]$AddToPath = $true,
    [switch]$Help
)

# Colors for output
$Colors = @{
    Red = "Red"
    Green = "Green" 
    Yellow = "Yellow"
    Blue = "Blue"
    White = "White"
}

# Default values
$Repo = "NakaSato/rskiller"
$GitHubDownload = "https://github.com/$Repo/releases/latest/download"

# Helper functions
function Write-Info {
    param([string]$Message)
    Write-Host "[INFO] $Message" -ForegroundColor $Colors.Blue
}

function Write-Success {
    param([string]$Message)
    Write-Host "[SUCCESS] $Message" -ForegroundColor $Colors.Green
}

function Write-Warn {
    param([string]$Message)
    Write-Host "[WARN] $Message" -ForegroundColor $Colors.Yellow
}

function Write-Error {
    param([string]$Message)
    Write-Host "[ERROR] $Message" -ForegroundColor $Colors.Red
    exit 1
}

# Show help
function Show-Help {
    Write-Host "rskiller PowerShell Installer" -ForegroundColor $Colors.Green
    Write-Host "=============================" -ForegroundColor $Colors.Green
    Write-Host ""
    Write-Host "Usage: .\install.ps1 [parameters]"
    Write-Host ""
    Write-Host "Parameters:"
    Write-Host "  -InstallDir <path>    Installation directory (default: $env:ProgramFiles\rskiller)"
    Write-Host "  -AddToPath           Add installation directory to PATH (default: true)"
    Write-Host "  -Help                Show this help message"
    Write-Host ""
    Write-Host "Examples:"
    Write-Host "  .\install.ps1                           # Default installation"
    Write-Host "  .\install.ps1 -InstallDir C:\Tools      # Custom install directory"
    Write-Host "  .\install.ps1 -AddToPath:`$false         # Don't modify PATH"
    exit 0
}

# Detect architecture
function Get-Architecture {
    $arch = $env:PROCESSOR_ARCHITECTURE
    switch ($arch) {
        "AMD64" { return "x64" }
        "ARM64" { return "arm64" }
        default { Write-Error "Unsupported architecture: $arch" }
    }
}

# Check if running as administrator
function Test-IsAdmin {
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

# Add directory to PATH
function Add-ToPath {
    param([string]$Directory)
    
    if (-not $AddToPath) {
        Write-Info "Skipping PATH modification (disabled)"
        return
    }
    
    $currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
    if ($currentPath -like "*$Directory*") {
        Write-Info "Directory already in PATH: $Directory"
        return
    }
    
    try {
        Write-Info "Adding to system PATH: $Directory"
        $newPath = "$currentPath;$Directory"
        [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine")
        Write-Success "Added to PATH successfully"
        Write-Warn "You may need to restart your terminal for PATH changes to take effect"
    }
    catch {
        Write-Warn "Failed to add to system PATH: $_"
        Write-Info "You can manually add '$Directory' to your PATH"
    }
}

# Download and install binary
function Install-Binary {
    param([string]$Architecture)
    
    $filename = "rskiller-windows-$Architecture.zip"
    $url = "$GitHubDownload/$filename"
    $tempPath = "$env:TEMP\rskiller-installer"
    $zipPath = "$tempPath\$filename"
    
    Write-Info "Detected architecture: $Architecture"
    Write-Info "Download URL: $url"
    
    # Create temporary directory
    if (Test-Path $tempPath) {
        Remove-Item $tempPath -Recurse -Force
    }
    New-Item -ItemType Directory -Path $tempPath -Force | Out-Null
    
    try {
        # Download binary
        Write-Info "Downloading rskiller..."
        Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing
        
        # Extract binary
        Write-Info "Extracting binary..."
        Expand-Archive -Path $zipPath -DestinationPath $tempPath -Force
        
        # Create installation directory
        Write-Info "Installing to $InstallDir..."
        if (-not (Test-Path $InstallDir)) {
            New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
        }
        
        # Copy binary
        $exePath = "$InstallDir\rskiller.exe"
        Copy-Item "$tempPath\rskiller.exe" $exePath -Force
        
        Write-Success "rskiller installed successfully!"
        
        # Add to PATH
        Add-ToPath $InstallDir
        
    }
    catch {
        Write-Error "Installation failed: $_"
    }
    finally {
        # Cleanup
        if (Test-Path $tempPath) {
            Remove-Item $tempPath -Recurse -Force -ErrorAction SilentlyContinue
        }
    }
}

# Verify installation
function Test-Installation {
    $exePath = "$InstallDir\rskiller.exe"
    
    if (Test-Path $exePath) {
        try {
            $version = & $exePath --version 2>$null
            Write-Success "Installation verified: $version"
            Write-Info "You can now run 'rskiller' from your terminal"
        }
        catch {
            Write-Success "Binary installed at: $exePath"
            Write-Info "You may need to restart your terminal or add '$InstallDir' to your PATH"
        }
    }
    else {
        Write-Error "Installation verification failed: binary not found"
    }
}

# Check for existing installation
function Test-ExistingInstallation {
    $exePath = "$InstallDir\rskiller.exe"
    
    if (Test-Path $exePath) {
        try {
            $currentVersion = & $exePath --version 2>$null
            Write-Warn "rskiller is already installed: $currentVersion"
        }
        catch {
            Write-Warn "rskiller binary found at: $exePath"
        }
        
        $response = Read-Host "Do you want to update/reinstall? [y/N]"
        if ($response -notmatch "^[Yy]$") {
            Write-Info "Installation cancelled"
            exit 0
        }
    }
}

# Main installation function
function Main {
    if ($Help) {
        Show-Help
    }
    
    Write-Host "🦀 rskiller installer" -ForegroundColor $Colors.Green
    Write-Host "=====================" -ForegroundColor $Colors.Green
    Write-Host ""
    
    # Check if we need admin privileges for default install location
    if ($InstallDir.StartsWith($env:ProgramFiles) -and -not (Test-IsAdmin)) {
        Write-Warn "Installing to Program Files requires administrator privileges"
        Write-Info "Please run PowerShell as Administrator, or use a different install directory:"
        Write-Info "  .\install.ps1 -InstallDir `"$env:LOCALAPPDATA\rskiller`""
        exit 1
    }
    
    # Check for existing installation
    Test-ExistingInstallation
    
    # Detect architecture and install
    $architecture = Get-Architecture
    Install-Binary $architecture
    
    # Verify installation
    Test-Installation
    
    Write-Host ""
    Write-Success "🎉 Installation complete!"
    Write-Info "Run 'rskiller --help' to get started"
}

# Run main function
Main