scripts/modules/prerequisites/git/install-git.ps1
# strangeloop Setup - Git Installation Module # Version: 1.0.0 param( [string]$Version = "latest", [switch]$WSLMode, [switch]${test-only}, [switch]$Detailed, [switch]${what-if} ) # Import shared modules $SharedPath = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent | Join-Path -ChildPath "shared" Import-Module "$SharedPath\write-functions.ps1" -Force -DisableNameChecking Import-Module "$SharedPath\test-functions.ps1" -Force -DisableNameChecking Import-Module "$SharedPath\path-functions.ps1" -Force -DisableNameChecking function Test-Git { param( ) try { Write-Info "Testing Git installation..." # Check if Git command is available if (-not (Test-Command "git")) { Write-Warning "Git command 'git' not found" return $false } # Check Git version $gitVersion = Get-ToolVersion "git" if (-not $gitVersion) { Write-Warning "Could not get Git version" return $false } # Test basic functionality $versionOutput = git --version 2>$null if (-not $versionOutput) { Write-Warning "Git functionality test failed" return $false } Write-Success "Git is properly installed: $gitVersion" return $true } catch { Write-Warning "Error testing Git: $($_.Exception.Message)" return $false } } function Install-Git { param( [string]$Version = "latest", [string]$InstallPath = $null, [switch]${test-only}, [switch]${what-if} ) # If test-only mode, just test current installation if (${test-only}) { return Test-Git } # If what-if mode, show what would be done if (${what-if}) { Write-Host "what if: Would test if Git is already installed" -ForegroundColor Yellow Write-Host "what if: Would check internet connection" -ForegroundColor Yellow Write-Host "what if: Would determine Git download URL for version '$Version'" -ForegroundColor Yellow Write-Host "what if: Would download Git installer to temporary directory" -ForegroundColor Yellow Write-Host "what if: Would install Git with silent installation arguments" -ForegroundColor Yellow Write-Host "what if: Would configure Git with safe defaults" -ForegroundColor Yellow return $true } Write-Step "Installing Git..." try { # Check if Git is already installed if (Test-Command "git") { $currentVersion = Get-ToolVersion "git" if ($currentVersion) { Write-Info "Git $currentVersion is already installed" if ($Version -eq "latest") { Write-Success "Git installation confirmed" return $true } } } # Check internet connection if (-not (Test-InternetConnection)) { Write-Error "Internet connection required for Git installation" return $false } Write-Progress "Determining Git download URL..." # Get latest Git version if not specified $downloadUrl = $null if ($Version -eq "latest") { try { $releasesUrl = "https://api.github.com/repos/git-for-windows/git/releases/latest" $releaseInfo = Invoke-RestMethod -Uri $releasesUrl -UseBasicParsing $asset = $releaseInfo.assets | Where-Object { $_.name -like "*64-bit.exe" } | Select-Object -First 1 if ($asset) { $downloadUrl = $asset.browser_download_url $Version = $releaseInfo.tag_name -replace '^v', '' } } catch { Write-Warning "Could not get latest Git version from GitHub API, using fallback URL" $downloadUrl = "https://github.com/git-for-windows/git/releases/latest/download/Git-2.42.0.2-64-bit.exe" } } else { $downloadUrl = "https://github.com/git-for-windows/git/releases/download/v$Version.windows.1/Git-$Version-64-bit.exe" } if (-not $downloadUrl) { Write-Error "Could not determine Git download URL" return $false } Write-Progress "Downloading Git installer..." # Download Git installer $tempDir = Join-Path $env:TEMP "Git-$(Get-Random)" New-Item -ItemType Directory -Path $tempDir -Force | Out-Null if (-not (Test-Path $tempDir)) { Write-Error "Could not create temporary directory" return $false } $installerPath = Join-Path $tempDir "git-installer.exe" try { Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath -UseBasicParsing Write-Success "Git installer downloaded successfully" } catch { Write-Error "Failed to download Git installer: $($_.Exception.Message)" Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue return $false } # Verify download if (-not (Test-Path $installerPath)) { Write-Error "Git installer not found after download" Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue return $false } Write-Progress "Installing Git..." # Prepare installation arguments $installArgs = @( "/VERYSILENT", "/NORESTART", "/NOCANCEL", "/SP-", "/CLOSEAPPLICATIONS", "/RESTARTAPPLICATIONS", "/COMPONENTS=icons,ext\reg\shellhere,assoc,assoc_sh" ) if ($InstallPath) { $installArgs += "/DIR=`"$InstallPath`"" } # Install Git $installResult = Invoke-CommandWithTimeout -ScriptBlock { Start-Process -FilePath $installerPath -ArgumentList $installArgs -Wait -NoNewWindow -PassThru } -TimeoutSeconds 600 -Description "Git installation" # Clean up installer Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue if (-not $installResult.Success) { Write-Error "Git installation failed: $($installResult.Error)" return $false } $exitCode = $installResult.Output.ExitCode if ($exitCode -ne 0) { Write-Error "Git installation failed with exit code: $exitCode" return $false } Write-Success "Git installed successfully" # Update PATH and verify installation Write-Progress "Verifying Git installation..." # Refresh environment variables $env:PATH = [Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [Environment]::GetEnvironmentVariable("PATH", "User") # Wait a moment for installation to complete Start-Sleep -Seconds 3 # Verify installation if (Test-Command "git") { $installedVersion = Get-ToolVersion "git" if ($installedVersion) { Write-Success "Git $installedVersion verified and ready" # Configure Git with safe defaults if not already configured Write-Progress "Configuring Git defaults..." Set-GitDefaults return $true } else { Write-Warning "Git installed but version detection failed" return $true # Still consider it successful } } else { Write-Error "Git installation completed but 'git' command not found" Write-Info "You may need to restart your terminal or reboot your system" return $false } } catch { Write-Error "Git installation failed: $($_.Exception.Message)" return $false } } function Set-GitDefaults { Write-Step "Configuring Git defaults..." try { # Check if global user.name is set $userName = git config --global user.name 2>$null if (-not $userName) { $userName = Read-Host "Enter your Git user.name (required)" while ([string]::IsNullOrWhiteSpace($userName)) { $userName = Read-Host "Git user.name cannot be empty. Please enter your name:" } git config --global user.name "$userName" Write-Info "Set Git user.name to '$userName'" } # Check if global user.email is set $userEmail = git config --global user.email 2>$null if (-not $userEmail) { $userEmail = Read-Host "Enter your Git user.email (required)" while ([string]::IsNullOrWhiteSpace($userEmail)) { $userEmail = Read-Host "Git user.email cannot be empty. Please enter your email:" } git config --global user.email "$userEmail" Write-Info "Set Git user.email to '$userEmail'" } # Set safe directory configuration for WSL compatibility git config --global --add safe.directory '*' Write-Info "Configured Git safe.directory for WSL compatibility" # Set default branch name git config --global init.defaultBranch main Write-Info "Set default branch name to 'main'" # Set pull behavior git config --global pull.rebase false Write-Info "Set Git pull behavior to merge" # Set core autocrlf for Windows git config --global core.autocrlf true Write-Info "Set Git core.autocrlf to true for Windows" Write-Success "Git default configuration completed" } catch { Write-Warning "Could not configure Git defaults: $($_.Exception.Message)" } } # Main execution if ($MyInvocation.InvocationName -ne '.') { $result = Install-Git -Version $Version -InstallPath $InstallPath -test-only:${test-only} -what-if:${what-if} if ($result) { if (${test-only}) { Write-Success "Git test completed successfully" } else { Write-CompletionSummary @{ 'Git Installation' = 'Completed Successfully' 'Version' = (Get-ToolVersion "git") 'Command Available' = if (Test-Command "git") { "Yes" } else { "No" } } -Title "Git Installation Summary" } exit 0 } else { if (${test-only}) { Write-Error "Git test failed" } else { Write-Error "Git installation failed" } exit 1 } } # Export functions for module usage Export-ModuleMember -Function @( 'Install-Git', 'Set-GitDefaults' ) |