962 lines
35 KiB
PowerShell
962 lines
35 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
<#
|
|
.SYNOPSIS
|
|
Installs all prerequisites for Git Workshop using winget and clones the repository.
|
|
|
|
.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):
|
|
- Windows Terminal (modern terminal experience)
|
|
|
|
The script checks for existing installations, shows clear progress, and verifies
|
|
each installation succeeded. At the end, it clones the repository and can
|
|
open it in VSCode for immediate workshop access.
|
|
|
|
One-shot installation:
|
|
Invoke-RestMethod -Uri https://git.frod.dk/floppydiscen/git-workshop/raw/branch/main/install.ps1 | Invoke-Expression
|
|
|
|
.EXAMPLE
|
|
PS> Invoke-RestMethod -Uri https://git.frod.dk/floppydiscen/git-workshop/raw/branch/main/install.ps1 | Invoke-Expression
|
|
Runs the complete installation and setup in one command.
|
|
|
|
.EXAMPLE
|
|
PS> .\install.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) {
|
|
# Extract semantic version numbers only - stop before any non-digit/non-dot characters
|
|
# This extracts "2.52.0" from "2.52.0.windows.1"
|
|
if ($version -match '(\d+)(?:\.(\d+))?(?:\.(\d+))?') {
|
|
$installedVersion = $matches[1] + "." +$matches[2]
|
|
try {
|
|
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
|
|
}
|
|
}
|
|
catch {
|
|
Write-Warning "Version comparison failed - assuming sufficient version"
|
|
return $true
|
|
}
|
|
}
|
|
else {
|
|
Write-Warning "Could not parse version from: $version"
|
|
Write-Host " Assuming installed version is sufficient..." -ForegroundColor Cyan
|
|
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'
|
|
|
|
# Parse Git version from various formats:
|
|
# "git version 2.52.0", "git version 2.52.0.windows.1", etc.
|
|
if ($version -match 'git version (\d+)(?:\.(\d+))?(?:\.(\d+))?') {
|
|
$majorVersion = [int]$matches[1]
|
|
$minorVersion = [int]$matches[2]
|
|
|
|
# Check if version is 2.23 or higher
|
|
if ($majorVersion -gt 2 -or ($majorVersion -eq 2 -and $minorVersion -ge 23)) {
|
|
return $true
|
|
}
|
|
else {
|
|
Write-Warning "Git version $majorVersion.$minorVersion is below required version 2.23"
|
|
return $false
|
|
}
|
|
}
|
|
|
|
Write-Warning "Could not parse Git version from: $version"
|
|
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 Prerequisites Check Function
|
|
|
|
function Get-SystemPrerequisites {
|
|
<#
|
|
.SYNOPSIS
|
|
Checks which required tools are installed and their versions.
|
|
|
|
.DESCRIPTION
|
|
Scans the system for PowerShell 7, Git 2.23+, and Visual Studio Code.
|
|
Returns a hashtable with installation status and version information.
|
|
#>
|
|
|
|
$prereqs = @{
|
|
PowerShell = @{
|
|
Installed = $false
|
|
Version = $null
|
|
Command = "pwsh"
|
|
MinVersion = "7.0"
|
|
Name = "PowerShell 7"
|
|
Sufficient = $false
|
|
}
|
|
Git = @{
|
|
Installed = $false
|
|
Version = $null
|
|
Command = "git"
|
|
MinVersion = "2.23"
|
|
Name = "Git"
|
|
Sufficient = $false
|
|
}
|
|
VSCode = @{
|
|
Installed = $false
|
|
Version = $null
|
|
Command = "code"
|
|
MinVersion = $null
|
|
Name = "Visual Studio Code"
|
|
Sufficient = $false
|
|
}
|
|
WindowsTerminal = @{
|
|
Installed = $false
|
|
Version = $null
|
|
Command = "wt"
|
|
MinVersion = $null
|
|
Name = "Windows Terminal"
|
|
Sufficient = $false
|
|
}
|
|
}
|
|
|
|
Write-Host "Checking system for installed tools..." -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
foreach ($key in $prereqs.Keys) {
|
|
$tool = $prereqs[$key]
|
|
|
|
if (Test-CommandExists $tool.Command) {
|
|
$tool.Installed = $true
|
|
$tool.Version = Get-InstalledVersion $tool.Command
|
|
|
|
if ($tool.MinVersion -and $tool.Version) {
|
|
# Extract semantic version for comparison
|
|
if ($tool.Version -match '(\d+)(?:\.(\d+))?(?:\.(\d+))?') {
|
|
$major = [int]$matches[1]
|
|
$minor = if ($matches[2]) { [int]$matches[2] } else { 0 }
|
|
$patch = if ($matches[3]) { [int]$matches[3] } else { 0 }
|
|
$installedVersion = "$major.$minor.$patch"
|
|
|
|
$minParts = $tool.MinVersion.Split('.')
|
|
$minMajor = [int]$minParts[0]
|
|
$minMinor = if ($minParts[1]) { [int]$minParts[1] } else { 0 }
|
|
$minPatch = if ($minParts[2]) { [int]$minParts[2] } else { 0 }
|
|
$minVersion = "$minMajor.$minMinor.$minPatch"
|
|
|
|
if ([version]$installedVersion -lt [version]$minVersion) {
|
|
Write-Host " ✓ $($tool.Name): $($tool.Version) (⚠ below required $($tool.MinVersion))" -ForegroundColor Yellow
|
|
$tool.Sufficient = $false
|
|
} else {
|
|
Write-Host " ✓ $($tool.Name): $($tool.Version)" -ForegroundColor Green
|
|
$tool.Sufficient = $true
|
|
}
|
|
} else {
|
|
Write-Host " ✓ $($tool.Name): $($tool.Version) (⚠ cannot parse version)" -ForegroundColor Yellow
|
|
$tool.Sufficient = $true # Assume sufficient if we can't parse
|
|
}
|
|
} else {
|
|
Write-Host " ✓ $($tool.Name): $($tool.Version)" -ForegroundColor Green
|
|
$tool.Sufficient = $true
|
|
}
|
|
} else {
|
|
Write-Host " ✗ $($tool.Name): Not installed" -ForegroundColor Red
|
|
$tool.Sufficient = $false
|
|
}
|
|
}
|
|
|
|
return $prereqs
|
|
}
|
|
|
|
function Show-PrerequisitesSummary {
|
|
param([hashtable]$Prereqs)
|
|
|
|
Write-Host ""
|
|
Write-Step "Prerequisites Summary"
|
|
|
|
$requiredTools = @("PowerShell", "Git", "VSCode")
|
|
$allRequiredInstalled = $true
|
|
$allRequiredSufficient = $true
|
|
|
|
Write-Host ""
|
|
Write-Host "Required Tools:" -ForegroundColor White
|
|
|
|
foreach ($toolName in $requiredTools) {
|
|
$tool = $Prereqs[$toolName]
|
|
if ($tool.Installed -and $tool.Sufficient) {
|
|
Write-Success " $($tool.Name): $($tool.Version)"
|
|
} elseif ($tool.Installed) {
|
|
Write-Warning " $($tool.Name): $($tool.Version) (needs upgrade)"
|
|
$allRequiredSufficient = $false
|
|
} else {
|
|
Write-Error " $($tool.Name): Not installed"
|
|
$allRequiredInstalled = $false
|
|
$allRequiredSufficient = $false
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Optional Tools:" -ForegroundColor White
|
|
|
|
$wt = $Prereqs.WindowsTerminal
|
|
if ($wt.Installed) {
|
|
Write-Success " $($wt.Name): $($wt.Version)"
|
|
} else {
|
|
Write-Host " $($wt.Name): Not installed" -ForegroundColor Gray
|
|
}
|
|
|
|
return @{
|
|
AllRequiredInstalled = $allRequiredInstalled -and $allRequiredSufficient
|
|
AnyMissing = -not $allRequiredInstalled
|
|
AnyInsufficient = -not $allRequiredSufficient
|
|
}
|
|
}
|
|
|
|
function Get-UserChoice {
|
|
param([hashtable]$PrereqStatus)
|
|
|
|
Write-Host ""
|
|
Write-Step "Choose Your Action"
|
|
|
|
if ($PrereqStatus.AllRequiredInstalled) {
|
|
Write-Host "All required tools are already installed!" -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "What would you like to do?" -ForegroundColor White
|
|
Write-Host " 1) Just clone the workshop repository" -ForegroundColor Cyan
|
|
Write-Host " 2) Install/update missing optional tools" -ForegroundColor Cyan
|
|
Write-Host " 3) Reinstall all tools (fresh installation)" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
|
|
while ($true) {
|
|
$choice = Read-Host "Enter your choice (1-3)"
|
|
switch ($choice.Trim()) {
|
|
"1" { return "CloneOnly" }
|
|
"2" { return "OptionalOnly" }
|
|
"3" { return "InstallAll" }
|
|
default { Write-Host "Please enter 1, 2, or 3" -ForegroundColor Yellow }
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "Some required tools are missing or need updates." -ForegroundColor Yellow
|
|
Write-Host ""
|
|
Write-Host "What would you like to do?" -ForegroundColor White
|
|
Write-Host " 1) Install missing/insufficient tools only" -ForegroundColor Green
|
|
Write-Host " 2) Install all required tools" -ForegroundColor Cyan
|
|
Write-Host " 3) Just clone the workshop repository (not recommended)" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
|
|
while ($true) {
|
|
$choice = Read-Host "Enter your choice (1-3)"
|
|
switch ($choice.Trim()) {
|
|
"1" { return "InstallMissing" }
|
|
"2" { return "InstallAll" }
|
|
"3" { return "CloneOnly" }
|
|
default { Write-Host "Please enter 1, 2, or 3" -ForegroundColor Yellow }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Main Script
|
|
|
|
Write-Host @"
|
|
|
|
╔═══════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ Git Workshop - Prerequisites Installation Script ║
|
|
║ ║
|
|
╚═══════════════════════════════════════════════════════════╝
|
|
|
|
"@ -ForegroundColor Cyan
|
|
|
|
# Check for winget first
|
|
Write-Step "Checking System Requirements"
|
|
|
|
if (-not (Test-WingetAvailable)) {
|
|
Write-Host "`nInstallation cannot continue without winget." -ForegroundColor Red
|
|
return
|
|
}
|
|
|
|
Write-Success "winget is available"
|
|
|
|
# Check system prerequisites
|
|
$prereqs = Get-SystemPrerequisites
|
|
$prereqStatus = Show-PrerequisitesSummary $prereqs
|
|
$userChoice = Get-UserChoice $prereqStatus
|
|
|
|
Write-Host ""
|
|
Write-Step "User Choice: $userChoice"
|
|
|
|
# Track installation results
|
|
$results = @{
|
|
PowerShell = $prereqs.PowerShell.Installed -and $prereqs.PowerShell.Sufficient
|
|
Git = $prereqs.Git.Installed -and $prereqs.Git.Sufficient
|
|
VSCode = $prereqs.VSCode.Installed -and $prereqs.VSCode.Sufficient
|
|
VSCodeExtensions = $false
|
|
VSCodePowerShellIntegration = $null # null = not asked, true = configured, false = skipped/failed
|
|
WindowsTerminal = $null
|
|
}
|
|
|
|
# Progress tracking
|
|
$totalSteps = 4 # Required installations + extensions
|
|
$currentStep = 0
|
|
|
|
function Write-ProgressIndicator {
|
|
param(
|
|
[string]$Activity,
|
|
[string]$Status,
|
|
[int]$PercentComplete
|
|
)
|
|
|
|
Write-Progress -Activity $Activity -Status $Status -PercentComplete $PercentComplete
|
|
}
|
|
|
|
function Should-Install {
|
|
param(
|
|
[string]$ToolName,
|
|
[string]$UserChoice,
|
|
[hashtable]$Prereqs
|
|
)
|
|
|
|
$tool = $Prereqs[$ToolName]
|
|
|
|
switch ($UserChoice) {
|
|
"CloneOnly" {
|
|
return $false
|
|
}
|
|
"OptionalOnly" {
|
|
return $ToolName -eq "WindowsTerminal"
|
|
}
|
|
"InstallMissing" {
|
|
return -not ($tool.Installed -and $tool.Sufficient)
|
|
}
|
|
"InstallAll" {
|
|
return $true
|
|
}
|
|
default {
|
|
return -not ($tool.Installed -and $tool.Sufficient)
|
|
}
|
|
}
|
|
}
|
|
|
|
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 {
|
|
# Ask user if they want to set PowerShell 7 as default terminal
|
|
$setAsDefault = Get-UserConfirmation "Set PowerShell 7 as the default terminal in VSCode? (Recommended for this workshop)"
|
|
|
|
if (-not $setAsDefault) {
|
|
Write-Host " Skipping PowerShell 7 terminal configuration." -ForegroundColor Gray
|
|
return $false
|
|
}
|
|
|
|
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 Installation Based on User Choice
|
|
|
|
if ($userChoice -ne "CloneOnly") {
|
|
Write-Host "`nStarting installation based on your choice..." -ForegroundColor Cyan
|
|
Write-Host "Note: Some installations may take a few minutes." -ForegroundColor Gray
|
|
Write-Host ""
|
|
|
|
# Calculate steps needed
|
|
$neededSteps = 0
|
|
if (Should-Install -ToolName "PowerShell" -UserChoice $userChoice -Prereqs $prereqs) { $neededSteps++ }
|
|
if (Should-Install -ToolName "Git" -UserChoice $userChoice -Prereqs $prereqs) { $neededSteps++ }
|
|
if (Should-Install -ToolName "VSCode" -UserChoice $userChoice -Prereqs $prereqs) { $neededSteps++ }
|
|
if (Should-Install -ToolName "WindowsTerminal" -UserChoice $userChoice -Prereqs $prereqs) { $neededSteps++ }
|
|
if ($neededSteps -eq 0) { $neededSteps = 1 } # At least for progress bar
|
|
if ($prereqs.VSCode.Installed -or (Should-Install -ToolName "VSCode" -UserChoice $userChoice -Prereqs $prereqs)) { $neededSteps++ } # For VSCode extensions
|
|
|
|
$currentStep = 0
|
|
$totalSteps = $neededSteps
|
|
|
|
#region Required Installations
|
|
|
|
# Install PowerShell 7
|
|
if (Should-Install -ToolName "PowerShell" -UserChoice $userChoice -Prereqs $prereqs) {
|
|
$currentStep++
|
|
Write-ProgressIndicator -Activity "Installing Tools" -Status "Installing PowerShell 7 ($currentStep/$totalSteps)" -PercentComplete (($currentStep / $totalSteps) * 100)
|
|
$results.PowerShell = Install-Package `
|
|
-Name "PowerShell 7" `
|
|
-WingetId "Microsoft.PowerShell" `
|
|
-CheckCommand "pwsh"
|
|
} else {
|
|
Write-Success "PowerShell 7 already installed and sufficient"
|
|
}
|
|
|
|
# Install Git
|
|
if (Should-Install -ToolName "Git" -UserChoice $userChoice -Prereqs $prereqs) {
|
|
$currentStep++
|
|
Write-ProgressIndicator -Activity "Installing Tools" -Status "Installing Git ($currentStep/$totalSteps)" -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
|
|
}
|
|
}
|
|
} else {
|
|
Write-Success "Git already installed and sufficient"
|
|
}
|
|
|
|
# Install Visual Studio Code
|
|
if (Should-Install -ToolName "VSCode" -UserChoice $userChoice -Prereqs $prereqs) {
|
|
$currentStep++
|
|
Write-ProgressIndicator -Activity "Installing Tools" -Status "Installing Visual Studio Code ($currentStep/$totalSteps)" -PercentComplete (($currentStep / $totalSteps) * 100)
|
|
$results.VSCode = Install-Package `
|
|
-Name "Visual Studio Code" `
|
|
-WingetId "Microsoft.VisualStudioCode" `
|
|
-CheckCommand "code"
|
|
} else {
|
|
Write-Success "Visual Studio Code already installed"
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VSCode Extensions and Configuration
|
|
|
|
if (($prereqs.VSCode.Installed -or $results.VSCode) -and $userChoice -ne "CloneOnly") {
|
|
$currentStep++
|
|
Write-ProgressIndicator -Activity "Installing Tools" -Status "Installing VSCode Extensions ($currentStep/$totalSteps)" -PercentComplete (($currentStep / $totalSteps) * 100)
|
|
|
|
Write-Host ""
|
|
Write-Step "Configuring VSCode"
|
|
|
|
# Install PowerShell extension
|
|
$powershellExtensionResult = Install-VSCodeExtension -ExtensionId "ms-vscode.PowerShell" -ExtensionName "PowerShell"
|
|
|
|
# Configure PowerShell 7 integration (optional but recommended)
|
|
if ($userChoice -eq "InstallAll" -or $userChoice -eq "InstallMissing") {
|
|
$powershellIntegrationResult = Set-VSCodePowerShellIntegration
|
|
$results.VSCodePowerShellIntegration = $powershellIntegrationResult
|
|
} else {
|
|
$results.VSCodePowerShellIntegration = $null
|
|
}
|
|
|
|
$results.VSCodeExtensions = $powershellExtensionResult
|
|
}
|
|
|
|
# Clear progress bar
|
|
Write-Progress -Activity "Installing Tools" -Completed
|
|
|
|
#endregion
|
|
|
|
#region Optional Installations
|
|
|
|
# Windows Terminal (optional)
|
|
if (Should-Install -ToolName "WindowsTerminal" -UserChoice $userChoice -Prereqs $prereqs) {
|
|
Write-Host ""
|
|
if ($userChoice -eq "OptionalOnly" -or (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
|
|
}
|
|
} elseif ($prereqs.WindowsTerminal.Installed) {
|
|
Write-Success "Windows Terminal already installed"
|
|
}
|
|
|
|
#endregion
|
|
} else {
|
|
Write-Host "`nSkipping tool installation as requested." -ForegroundColor Gray
|
|
Write-Host "Proceeding directly to workshop repository setup..." -ForegroundColor Cyan
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Installation Summary
|
|
|
|
Write-Step "Installation Summary"
|
|
|
|
# For CloneOnly, check if tools were already installed
|
|
if ($userChoice -eq "CloneOnly") {
|
|
$allRequired = $prereqs.PowerShell.Installed -and $prereqs.PowerShell.Sufficient -and
|
|
$prereqs.Git.Installed -and $prereqs.Git.Sufficient -and
|
|
$prereqs.VSCode.Installed -and $prereqs.VSCode.Sufficient
|
|
} else {
|
|
$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"
|
|
}
|
|
else {
|
|
Write-Warning " • VSCode PowerShell extension may need manual installation"
|
|
}
|
|
|
|
if ($results.VSCodePowerShellIntegration -eq $true) {
|
|
Write-Success " • PowerShell 7 terminal integration"
|
|
}
|
|
elseif ($results.VSCodePowerShellIntegration -eq $false) {
|
|
Write-Host " • PowerShell 7 terminal integration: Skipped" -ForegroundColor Gray
|
|
}
|
|
}
|
|
else {
|
|
Write-Error "Visual Studio Code - Installation failed or needs restart"
|
|
}
|
|
|
|
if ($results.WindowsTerminal -ne $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
|
|
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 " • 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 ""
|
|
|
|
# Ask user if they want to clone the workshop repository
|
|
Write-Step "Workshop Setup"
|
|
|
|
if (Get-UserConfirmation "Clone the Git Workshop repository to Documents\git-workshop and open in VSCode?") {
|
|
try {
|
|
$documentsPath = [System.Environment]::GetFolderPath("MyDocuments")
|
|
$workshopPath = Join-Path $documentsPath "git-workshop"
|
|
|
|
Write-Host " Cloning to: $workshopPath" -ForegroundColor Gray
|
|
|
|
# Create directory if it doesn't exist
|
|
$documentsDir = Split-Path $workshopPath -Parent
|
|
if (-not (Test-Path $documentsDir)) {
|
|
New-Item -Path $documentsDir -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Clone or update the repository
|
|
if (Test-Path $workshopPath) {
|
|
Write-Host " Directory already exists. Checking if it's a git repository..." -ForegroundColor Yellow
|
|
Push-Location $workshopPath
|
|
if (Get-Command git -ErrorAction SilentlyContinue) {
|
|
$remoteResult = git remote get-url origin 2>$null
|
|
if ($LASTEXITCODE -eq 0 -and $remoteResult -like "*git-workshop*") {
|
|
Write-Host " Repository already exists. Updating..." -ForegroundColor Cyan
|
|
git pull origin main
|
|
} else {
|
|
Write-Warning " Directory exists but is not the git-workshop repository"
|
|
Write-Host " Please remove the directory manually and run again" -ForegroundColor Yellow
|
|
Pop-Location
|
|
return
|
|
}
|
|
}
|
|
Pop-Location
|
|
} else {
|
|
git clone "https://git.frod.dk/floppydiscen/git-workshop.git" $workshopPath
|
|
Write-Success "Repository cloned successfully!"
|
|
}
|
|
|
|
Write-Host " Opening in VSCode..." -ForegroundColor Cyan
|
|
if (Get-Command code -ErrorAction SilentlyContinue) {
|
|
& code $workshopPath
|
|
Write-Success "VSCode opened with the workshop repository"
|
|
Write-Host ""
|
|
Write-Host "=== IMPORTANT: Terminal Instructions ===" -ForegroundColor Yellow
|
|
Write-Host "Once VSCode opens, you MUST open the integrated terminal:" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "Option 1 (Recommended): Press Ctrl+` (backtick key)" -ForegroundColor Cyan
|
|
Write-Host "Option 2: Use menu: View → Terminal" -ForegroundColor Cyan
|
|
Write-Host "Option 3: Use Command Palette: Ctrl+Shift+P → 'Terminal: Create New Terminal'" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host "=== Quick Start (run in VSCode terminal) ===" -ForegroundColor Yellow
|
|
Write-Host " cd 01-essentials\01-basics" -ForegroundColor White
|
|
Write-Host " .\setup.ps1" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "The terminal should show 'PowerShell' and open to the correct directory." -ForegroundColor Green
|
|
Write-Host ""
|
|
} else {
|
|
Write-Warning "VSCode command not found. Please open manually:"
|
|
Write-Host " code '$workshopPath'" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "=== Manual Instructions ===" -ForegroundColor Yellow
|
|
Write-Host "1. Open VSCode manually" -ForegroundColor White
|
|
Write-Host "2. Open integrated terminal (Ctrl+` or View → Terminal)" -ForegroundColor White
|
|
Write-Host "3. Navigate: cd 01-essentials\01-basics" -ForegroundColor White
|
|
Write-Host "4. Run: .\setup.ps1" -ForegroundColor White
|
|
Write-Host ""
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Quick start commands (run in VSCode terminal):" -ForegroundColor Cyan
|
|
Write-Host " cd 01-essentials\01-basics" -ForegroundColor White
|
|
Write-Host " .\setup.ps1" -ForegroundColor White
|
|
Write-Host ""
|
|
|
|
} catch {
|
|
Write-Error "Failed to clone repository: $_"
|
|
Write-Host ""
|
|
Write-Host "You can clone manually:" -ForegroundColor Yellow
|
|
Write-Host " git clone https://git.frod.dk/floppydiscen/git-workshop.git ~/Documents/git-workshop" -ForegroundColor White
|
|
Write-Host " code ~/Documents/git-workshop" -ForegroundColor White
|
|
}
|
|
} else {
|
|
Write-Host " Skipping repository clone." -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host "Manual setup:" -ForegroundColor Cyan
|
|
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.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 ""
|
|
}
|
|
|
|
}
|