#!/usr/bin/env pwsh <# .SYNOPSIS Installs all prerequisites for the Git Workshop using winget. .DESCRIPTION This script automates the installation of required tools for the Git Workshop: - PowerShell 7 (cross-platform PowerShell) - Git 2.23+ (version control system) - Visual Studio Code (code editor with Git integration) Optional tools (with user prompts): - Python 3.12 (for Module 08: Multiplayer Git) - Windows Terminal (modern terminal experience) The script checks for existing installations, shows clear progress, and verifies each installation succeeded. At the end, it displays Git configuration instructions. .EXAMPLE PS> .\install-prerequisites.ps1 Runs the installation script with interactive prompts. .NOTES Requires Windows 11 with winget (App Installer) available. Some installations may require administrator privileges. #> [CmdletBinding()] param() Set-StrictMode -Version Latest $ErrorActionPreference = 'Continue' # Continue on errors to show all results #region Helper Functions function Write-ColorMessage { param( [string]$Message, [string]$Color = 'White' ) Write-Host $Message -ForegroundColor $Color } function Write-Step { param([string]$Message) Write-ColorMessage "`n=== $Message ===" -Color Cyan } function Write-Success { param([string]$Message) Write-ColorMessage " ✓ $Message" -Color Green } function Write-Warning { param([string]$Message) Write-ColorMessage " ⚠ $Message" -Color Yellow } function Write-Error { param([string]$Message) Write-ColorMessage " ✗ $Message" -Color Red } function Test-CommandExists { param([string]$Command) $oldPreference = $ErrorActionPreference $ErrorActionPreference = 'SilentlyContinue' try { if (Get-Command $Command -ErrorAction SilentlyContinue) { return $true } return $false } finally { $ErrorActionPreference = $oldPreference } } function Get-InstalledVersion { param( [string]$Command, [string]$VersionArg = '--version' ) try { $output = & $Command $VersionArg 2>&1 | Select-Object -First 1 return $output.ToString().Trim() } catch { return $null } } function Test-WingetAvailable { if (-not (Test-CommandExists 'winget')) { Write-Error "winget is not available on this system." Write-Host "`nTo fix this:" -ForegroundColor Yellow Write-Host " 1. Update Windows 11 to the latest version (Settings → Windows Update)" -ForegroundColor White Write-Host " 2. Install 'App Installer' from the Microsoft Store" -ForegroundColor White Write-Host " 3. Restart your computer and run this script again" -ForegroundColor White return $false } return $true } function Install-Package { param( [string]$Name, [string]$WingetId, [string]$CheckCommand, [string]$MinVersion = $null, [string]$AdditionalArgs = '' ) Write-Step "Installing $Name" # Check if already installed if (Test-CommandExists $CheckCommand) { $version = Get-InstalledVersion $CheckCommand Write-Success "$Name is already installed: $version" if ($MinVersion -and $version) { # Basic version check (not perfect but good enough for common cases) if ($version -match '(\d+\.[\d.]+)') { $installedVersion = $matches[1] if ([version]$installedVersion -lt [version]$MinVersion) { Write-Warning "Version $installedVersion is below minimum required version $MinVersion" Write-Host " Attempting to upgrade..." -ForegroundColor Cyan } else { return $true } } } else { return $true } } # Install using winget Write-Host " Installing via winget: $WingetId" -ForegroundColor Cyan $installCmd = "winget install --id $WingetId --source winget --silent $AdditionalArgs".Trim() Write-Host " Running: $installCmd" -ForegroundColor Gray try { # Show progress during installation Write-Progress -Activity "Installing $Name" -Status "Downloading and installing..." -PercentComplete 25 $result = Invoke-Expression $installCmd 2>&1 Write-Progress -Activity "Installing $Name" -Status "Verifying installation..." -PercentComplete 75 # Check if installation succeeded Start-Sleep -Seconds 2 # Give the system time to register the new command # Refresh environment variables in current session $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") if (Test-CommandExists $CheckCommand) { $version = Get-InstalledVersion $CheckCommand Write-Success "$Name installed successfully: $version" Write-Progress -Activity "Installing $Name" -Completed return $true } else { Write-Warning "$Name installation completed, but command '$CheckCommand' not found." Write-Host " You may need to restart your terminal or computer." -ForegroundColor Yellow Write-Progress -Activity "Installing $Name" -Completed return $false } } catch { Write-Error "Failed to install $Name`: $_" Write-Progress -Activity "Installing $Name" -Completed return $false } } function Test-GitVersion { if (-not (Test-CommandExists 'git')) { return $false } $version = Get-InstalledVersion 'git' if ($version -match 'git version (\d+\.\d+)') { $versionNumber = [decimal]$matches[1] if ($versionNumber -ge 2.23) { return $true } else { Write-Warning "Git version $versionNumber is below required version 2.23" return $false } } return $false } function Get-UserConfirmation { param([string]$Prompt) while ($true) { $response = Read-Host "$Prompt (y/n)" $response = $response.Trim().ToLower() if ($response -eq 'y' -or $response -eq 'yes') { return $true } elseif ($response -eq 'n' -or $response -eq 'no') { return $false } else { Write-Host "Please enter 'y' or 'n'" -ForegroundColor Yellow } } } #endregion #region Main Script Write-Host @" ╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ Git Workshop - Prerequisites Installation Script ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝ "@ -ForegroundColor Cyan Write-Host "This script will install the required tools for the Git Workshop:" -ForegroundColor White Write-Host " • PowerShell 7 (cross-platform PowerShell)" -ForegroundColor White Write-Host " • Git 2.23+ (version control system)" -ForegroundColor White Write-Host " • Visual Studio Code (code editor)" -ForegroundColor White Write-Host "" Write-Host "You will be prompted for optional tools:" -ForegroundColor White Write-Host " • Python 3.12 (for Module 08: Multiplayer Git)" -ForegroundColor White Write-Host " • Windows Terminal (modern terminal experience)" -ForegroundColor White Write-Host "" # Check for winget Write-Step "Checking Prerequisites" if (-not (Test-WingetAvailable)) { Write-Host "`nInstallation cannot continue without winget." -ForegroundColor Red exit 1 } Write-Success "winget is available" # Track installation results $results = @{ PowerShell = $false Git = $false VSCode = $false VSCodeExtensions = $false Python = $null # null = not attempted, true = success, false = failed WindowsTerminal = $null } # Progress tracking $totalSteps = 4 # Required installations + extensions $currentStep = 0 Write-Host "`nStarting installation..." -ForegroundColor Cyan Write-Host "Note: Some installations may take a few minutes." -ForegroundColor Gray Write-Host "" # Progress bar helper function Write-ProgressIndicator { param( [string]$Activity, [string]$Status, [int]$PercentComplete ) Write-Progress -Activity $Activity -Status $Status -PercentComplete $PercentComplete } function Install-VSCodeExtension { param( [string]$ExtensionId, [string]$ExtensionName ) Write-Host " Installing VSCode extension: $ExtensionName" -ForegroundColor Cyan try { # Refresh environment to ensure code command is available $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") $result = & code --install-extension $ExtensionId 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "VSCode extension '$ExtensionName' installed successfully" return $true } else { Write-Warning "Failed to install VSCode extension '$ExtensionName'" Write-Host " You can install it manually later: Ctrl+Shift+X → Search '$ExtensionName'" -ForegroundColor Gray return $false } } catch { Write-Warning "Could not install VSCode extension '$ExtensionName`: $_" Write-Host " You can install it manually later: Ctrl+Shift+X → Search '$ExtensionName'" -ForegroundColor Gray return $false } } function Set-VSCodePowerShellIntegration { Write-Host " Configuring PowerShell 7 integration with VSCode..." -ForegroundColor Cyan try { # Set PowerShell 7 as the default terminal in VSCode $vscodeSettingsPath = Join-Path $env:APPDATA "Code\User\settings.json" $vscodeSettingsDir = Split-Path $vscodeSettingsPath -Parent # Create directory if it doesn't exist if (-not (Test-Path $vscodeSettingsDir)) { New-Item -Path $vscodeSettingsDir -ItemType Directory -Force | Out-Null } # Read existing settings or create new if (Test-Path $vscodeSettingsPath) { $settings = Get-Content $vscodeSettingsPath -Raw | ConvertFrom-Json } else { $settings = @{} } # Set PowerShell 7 as default terminal if (-not $settings.PSObject.Properties.Name -contains "terminal.integrated.defaultProfile.windows") { $settings | Add-Member -NotePropertyName "terminal.integrated.defaultProfile.windows" -NotePropertyValue "PowerShell" } else { $settings."terminal.integrated.defaultProfile.windows" = "PowerShell" } # Add terminal profiles if not present if (-not $settings.PSObject.Properties.Name -contains "terminal.integrated.profiles.windows") { $profiles = @{ "PowerShell" = @{ "source" = "PowerShell" "icon" = "terminal-powershell" "path" = "pwsh.exe" } } $settings | Add-Member -NotePropertyName "terminal.integrated.profiles.windows" -NotePropertyValue $profiles } # Save settings $settings | ConvertTo-Json -Depth 10 | Set-Content $vscodeSettingsPath Write-Success "VSCode configured to use PowerShell 7 as default terminal" return $true } catch { Write-Warning "Could not configure VSCode PowerShell integration automatically" Write-Host " You can configure it manually in VSCode: Ctrl+Shift+P → Terminal: Select Default Profile → PowerShell" -ForegroundColor Gray return $false } } #region Required Installations # Install PowerShell 7 $currentStep++ Write-ProgressIndicator -Activity "Installing Required Tools" -Status "Installing PowerShell 7 (1/3)" -PercentComplete (($currentStep / $totalSteps) * 100) $results.PowerShell = Install-Package ` -Name "PowerShell 7" ` -WingetId "Microsoft.PowerShell" ` -CheckCommand "pwsh" # Install Git $currentStep++ Write-ProgressIndicator -Activity "Installing Required Tools" -Status "Installing Git (2/3)" -PercentComplete (($currentStep / $totalSteps) * 100) $results.Git = Install-Package ` -Name "Git" ` -WingetId "Git.Git" ` -CheckCommand "git" ` -MinVersion "2.23" ` -AdditionalArgs "-e" # Verify Git version specifically if ($results.Git) { if (-not (Test-GitVersion)) { Write-Warning "Git is installed but version may be below 2.23" $results.Git = $false } } # Install Visual Studio Code $currentStep++ Write-ProgressIndicator -Activity "Installing Required Tools" -Status "Installing Visual Studio Code (3/4)" -PercentComplete (($currentStep / $totalSteps) * 100) $results.VSCode = Install-Package ` -Name "Visual Studio Code" ` -WingetId "Microsoft.VisualStudioCode" ` -CheckCommand "code" # Install VSCode Extensions and configure PowerShell integration if ($results.VSCode) { $currentStep++ Write-ProgressIndicator -Activity "Installing Required Tools" -Status "Installing VSCode Extensions (4/4)" -PercentComplete (($currentStep / $totalSteps) * 100) Write-Host "" Write-Step "Configuring VSCode" # Install PowerShell extension $powershellExtensionResult = Install-VSCodeExtension -ExtensionId "ms-vscode.PowerShell" -ExtensionName "PowerShell" # Install other recommended extensions $gitLensResult = Install-VSCodeExtension -ExtensionId "eamodio.gitlens" -ExtensionName "GitLens" $gitGraphResult = Install-VSCodeExtension -ExtensionId "mhutchie.git-graph" -ExtensionName "Git Graph" # Configure PowerShell 7 integration $powershellIntegrationResult = Set-VSCodePowerShellIntegration $results.VSCodeExtensions = $powershellExtensionResult -or $gitLensResult -or $gitGraphResult } else { $results.VSCodeExtensions = $false } # Clear progress bar Write-Progress -Activity "Installing Required Tools" -Completed #endregion #region Optional Installations # Python 3.12 (optional) Write-Host "" if (Get-UserConfirmation "Do you want to install Python 3.12? (Required for Module 08: Multiplayer Git)") { Write-ProgressIndicator -Activity "Installing Optional Tools" -Status "Installing Python 3.12" -PercentComplete 50 $results.Python = Install-Package ` -Name "Python 3.12" ` -WingetId "Python.Python.3.12" ` -CheckCommand "python" Write-Progress -Activity "Installing Optional Tools" -Completed } else { Write-Host " Skipping Python installation." -ForegroundColor Gray $results.Python = $null } # Windows Terminal (optional) Write-Host "" if (Get-UserConfirmation "Do you want to install Windows Terminal? (Highly recommended for better terminal experience)") { Write-ProgressIndicator -Activity "Installing Optional Tools" -Status "Installing Windows Terminal" -PercentComplete 50 $results.WindowsTerminal = Install-Package ` -Name "Windows Terminal" ` -WingetId "Microsoft.WindowsTerminal" ` -CheckCommand "wt" Write-Progress -Activity "Installing Optional Tools" -Completed } else { Write-Host " Skipping Windows Terminal installation." -ForegroundColor Gray $results.WindowsTerminal = $null } #endregion #region Installation Summary Write-Step "Installation Summary" $allRequired = $results.PowerShell -and $results.Git -and $results.VSCode Write-Host "" Write-Host "Required Tools:" -ForegroundColor White if ($results.PowerShell) { Write-Success "PowerShell 7" } else { Write-Error "PowerShell 7 - Installation failed or needs restart" } if ($results.Git) { Write-Success "Git 2.23+" } else { Write-Error "Git 2.23+ - Installation failed or needs restart" } if ($results.VSCode) { Write-Success "Visual Studio Code" if ($results.VSCodeExtensions) { Write-Success " • PowerShell extension" Write-Success " • GitLens extension" Write-Success " • Git Graph extension" Write-Success " • PowerShell 7 terminal integration" } else { Write-Warning " • Some VSCode extensions may need manual installation" } } else { Write-Error "Visual Studio Code - Installation failed or needs restart" } if ($results.Python -ne $null) { Write-Host "" Write-Host "Optional Tools:" -ForegroundColor White if ($results.Python) { Write-Success "Python 3.12" } else { Write-Error "Python 3.12 - Installation failed or needs restart" } } if ($results.WindowsTerminal -ne $null) { if ($results.Python -eq $null) { Write-Host "" Write-Host "Optional Tools:" -ForegroundColor White } if ($results.WindowsTerminal) { Write-Success "Windows Terminal" } else { Write-Error "Windows Terminal - Installation failed or needs restart" } } #endregion #region Next Steps Write-Step "Next Steps" if ($allRequired) { Write-Host "" Write-Success "All required tools installed successfully!" Write-Host "" Write-Host "IMPORTANT: Configure Git before your first commit:" -ForegroundColor Yellow Write-Host "" Write-Host " git config --global user.name `"Your Name`"" -ForegroundColor White Write-Host " git config --global user.email `"your.email@example.com`"" -ForegroundColor White Write-Host "" Write-Host "Optional: Set VS Code as Git's default editor:" -ForegroundColor Cyan Write-Host " git config --global core.editor `"code --wait`"" -ForegroundColor White Write-Host "" Write-Host "Verify your installation:" -ForegroundColor Cyan Write-Host " pwsh --version" -ForegroundColor White Write-Host " git --version" -ForegroundColor White Write-Host " code --version" -ForegroundColor White if ($results.Python) { Write-Host " python --version" -ForegroundColor White } Write-Host "" Write-Host "Set PowerShell execution policy (if needed):" -ForegroundColor Cyan Write-Host " Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser" -ForegroundColor White Write-Host "" Write-Host "Recommended VS Code Extensions:" -ForegroundColor Cyan Write-Host " • GitLens - Supercharge Git capabilities" -ForegroundColor White Write-Host " • Git Graph - View Git history visually" -ForegroundColor White Write-Host " • PowerShell - Better PowerShell support (from Microsoft)" -ForegroundColor White Write-Host "" Write-Host " Install via: Ctrl+Shift+X in VS Code" -ForegroundColor Gray Write-Host "" Write-Host "You're ready to start the workshop!" -ForegroundColor Green Write-Host " cd path\to\git-workshop" -ForegroundColor White Write-Host " cd 01-essentials\01-basics" -ForegroundColor White Write-Host " .\setup.ps1" -ForegroundColor White Write-Host "" } else { Write-Host "" Write-Warning "Some required installations failed or need verification." Write-Host "" Write-Host "Troubleshooting steps:" -ForegroundColor Yellow Write-Host " 1. Close and reopen your terminal (or restart your computer)" -ForegroundColor White Write-Host " 2. Run this script again: .\install-prerequisites.ps1" -ForegroundColor White Write-Host " 3. If issues persist, try manual installation:" -ForegroundColor White Write-Host " See INSTALLATION.md for detailed instructions" -ForegroundColor White Write-Host "" if (-not $results.Git) { Write-Host "For Git issues:" -ForegroundColor Yellow Write-Host " • Restart terminal after installation (PATH needs to refresh)" -ForegroundColor White Write-Host " • Manual download: https://git-scm.com/downloads" -ForegroundColor White Write-Host "" } if (-not $results.VSCode) { Write-Host "For VS Code issues:" -ForegroundColor Yellow Write-Host " • Ensure 'Add to PATH' option is enabled during installation" -ForegroundColor White Write-Host " • Manual download: https://code.visualstudio.com/" -ForegroundColor White Write-Host "" } if (-not $results.PowerShell) { Write-Host "For PowerShell 7 issues:" -ForegroundColor Yellow Write-Host " • Manual download: https://github.com/PowerShell/PowerShell/releases/latest" -ForegroundColor White Write-Host " • Download the file ending in '-win-x64.msi'" -ForegroundColor White Write-Host "" } exit 1 } #endregion exit 0