syncable-cli 0.11.1

A Rust-based CLI that analyzes code repositories and generates Infrastructure as Code configurations
Documentation
# PowerShell Installation Script for Syncable CLI on Windows
# Usage: powershell -ExecutionPolicy Bypass -File install.ps1

param(
    [string]$Version = "latest",
    [string]$InstallDir = "$env:USERPROFILE\.local\bin",
    [switch]$Force = $false,
    [switch]$Help = $false
)

# Color functions for better output
function Write-Success {
    param([string]$Message)
    Write-Host "✅ $Message" -ForegroundColor Green
}

function Write-Info {
    param([string]$Message)
    Write-Host "ℹ️  $Message" -ForegroundColor Blue
}

function Write-Warning {
    param([string]$Message)
    Write-Host "⚠️  $Message" -ForegroundColor Yellow
}

function Write-Error {
    param([string]$Message)
    Write-Host "❌ $Message" -ForegroundColor Red
}

function Write-Step {
    param([string]$Message)
    Write-Host "🔧 $Message" -ForegroundColor Cyan
}

# Help function
function Show-Help {
    Write-Host @"
Syncable CLI Installer for Windows

Usage: powershell -ExecutionPolicy Bypass -File install.ps1 [OPTIONS]

Options:
  -Version <version>     Install specific version (default: latest)
  -InstallDir <path>     Installation directory (default: %USERPROFILE%\.local\bin)
  -Force                 Force installation even if already installed
  -Help                  Show this help message

Examples:
  .\install.ps1                          # Install latest version
  .\install.ps1 -Version "0.9.0"         # Install specific version
  .\install.ps1 -Force                   # Force reinstall
  .\install.ps1 -InstallDir "C:\tools"   # Custom installation directory

"@
}

# Check if help is requested
if ($Help) {
    Show-Help
    exit 0
}

Write-Host @"
🚀 Syncable CLI Installer for Windows
====================================
"@ -ForegroundColor Magenta

# Check if running as administrator (optional, for system-wide installs)
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
if ($isAdmin) {
    Write-Info "Running as Administrator - can install system-wide"
} else {
    Write-Info "Running as regular user - installing to user directory"
}

# Check if cargo is available
Write-Step "Checking for Rust/Cargo installation..."
try {
    $cargoVersion = cargo --version 2>$null
    if ($LASTEXITCODE -eq 0) {
        Write-Success "Found Cargo: $cargoVersion"
        $hasRust = $true
    } else {
        $hasRust = $false
    }
} catch {
    $hasRust = $false
}

if (-not $hasRust) {
    Write-Warning "Rust/Cargo not found. Installing via cargo is not available."
    Write-Info "To install Rust, visit: https://rustup.rs/"
    Write-Info "Or download pre-built binaries from: https://github.com/syncable-dev/syncable-cli/releases"
    
    # Offer to open browser
    $response = Read-Host "Would you like to open the Rust installation page? (y/N)"
    if ($response -eq "y" -or $response -eq "Y") {
        Start-Process "https://rustup.rs/"
    }
    exit 1
}

# Check if sync-ctl is already installed
Write-Step "Checking for existing installation..."
try {
    $existingVersion = sync-ctl --version 2>$null
    if ($LASTEXITCODE -eq 0) {
        Write-Info "Found existing installation: $existingVersion"
        if (-not $Force) {
            $response = Read-Host "sync-ctl is already installed. Reinstall? (y/N)"
            if ($response -ne "y" -and $response -ne "Y") {
                Write-Info "Installation cancelled."
                exit 0
            }
        }
    }
} catch {
    Write-Info "No existing installation found."
}

# Install via cargo
Write-Step "Installing Syncable CLI via Cargo..."
Write-Info "This may take a few minutes..."

try {
    if ($Version -eq "latest") {
        Write-Info "Installing latest version from crates.io..."
        $installResult = cargo install syncable-cli 2>&1
    } else {
        Write-Info "Installing version $Version from crates.io..."
        $installResult = cargo install syncable-cli --version $Version 2>&1
    }
    
    if ($LASTEXITCODE -eq 0) {
        Write-Success "Syncable CLI installed successfully!"
    } else {
        Write-Error "Installation failed. Cargo output:"
        Write-Host $installResult -ForegroundColor Red
        exit 1
    }
} catch {
    Write-Error "Installation failed: $_"
    exit 1
}

# Verify installation
Write-Step "Verifying installation..."
try {
    $version = sync-ctl --version 2>$null
    if ($LASTEXITCODE -eq 0) {
        Write-Success "Installation verified: $version"
    } else {
        Write-Warning "Installation may have issues. sync-ctl command not found."
    }
} catch {
    Write-Warning "Could not verify installation."
}

# Check PATH
Write-Step "Checking PATH configuration..."
$cargoPath = "$env:USERPROFILE\.cargo\bin"
$currentPath = $env:PATH
if ($currentPath -like "*$cargoPath*") {
    Write-Success "Cargo bin directory is already in PATH"
} else {
    Write-Warning "Cargo bin directory ($cargoPath) is not in your PATH"
    Write-Info "To add it permanently:"
    Write-Info "1. Open System Properties > Advanced > Environment Variables"
    Write-Info "2. Add '$cargoPath' to your PATH variable"
    Write-Info "3. Restart your terminal/PowerShell session"
    Write-Info ""
    Write-Info "Or run this command in an elevated PowerShell:"
    Write-Info "[Environment]::SetEnvironmentVariable('PATH', `$env:PATH + ';$cargoPath', 'User')"
    
    # Offer to add to PATH automatically
    $response = Read-Host "Would you like to add it to PATH now? (y/N)"
    if ($response -eq "y" -or $response -eq "Y") {
        try {
            [Environment]::SetEnvironmentVariable('PATH', $env:PATH + ";$cargoPath", 'User')
            $env:PATH += ";$cargoPath"  # Update current session
            Write-Success "Added to PATH. Restart PowerShell to ensure it takes effect."
        } catch {
            Write-Error "Failed to add to PATH: $_"
            Write-Info "Please add manually as described above."
        }
    }
}

# Install vulnerability scanning tools
Write-Step "Setting up vulnerability scanning tools..."
Write-Info "Installing common security tools for better analysis..."

# Install tools that work well on Windows
$tools = @(
    @{Name="cargo-audit"; Command="cargo install cargo-audit"; Check="cargo audit --version"},
    @{Name="pip-audit"; Command="pip install --user pip-audit"; Check="pip-audit --version"}
)

foreach ($tool in $tools) {
    Write-Info "Installing $($tool.Name)..."
    try {
        # Check if already installed
        $checkResult = Invoke-Expression $tool.Check 2>$null
        if ($LASTEXITCODE -eq 0) {
            Write-Success "$($tool.Name) is already installed"
            continue
        }
        
        # Install the tool
        $installResult = Invoke-Expression $tool.Command 2>&1
        if ($LASTEXITCODE -eq 0) {
            Write-Success "$($tool.Name) installed successfully"
        } else {
            Write-Warning "Failed to install $($tool.Name): $installResult"
        }
    } catch {
        Write-Warning "Error installing $($tool.Name): $_"
    }
}

# Additional Windows-specific tools
Write-Info "For additional security tools on Windows, consider:"
Write-Info "  • Scoop: scoop install grype"
Write-Info "  • Chocolatey: choco install grype"
Write-Info "  • Manual downloads from GitHub releases"

# Final instructions
Write-Host @"

🎉 Installation Complete!
========================
"@ -ForegroundColor Green

Write-Success "Syncable CLI is now installed and ready to use!"
Write-Info ""
Write-Info "Quick Start:"
Write-Info "  sync-ctl analyze .              # Analyze current directory"
Write-Info "  sync-ctl generate --all .       # Generate all IaC files"
Write-Info "  sync-ctl security .             # Run security analysis"
Write-Info "  sync-ctl tools status           # Check security tools"
Write-Info ""
Write-Info "For help: sync-ctl --help"
Write-Info "Documentation: https://github.com/syncable-dev/syncable-cli"
Write-Info ""
Write-Warning "Remember to restart your PowerShell session if PATH was modified!"