#!pwsh #Requires -Version 6.0 <# .SYNOPSIS Installs the set of prerequisites for the macOS CI hosts. .DESCRIPTION Install-Prerequisites.ps1 installs all of the necessary prerequisites to run the vcpkg macOS CI in a vagrant virtual machine, skipping all prerequisites that are already installed and of the right version. .INPUTS None .OUTPUTS None #> [CmdletBinding()] Param() Set-StrictMode -Version 2 if (-not $IsMacOS) { Write-Error 'This script should only be run on a macOS host' throw } Import-Module "$PSScriptRoot/Utilities.psm1" $Installables = Get-Content "$PSScriptRoot/configuration/installables.json" | ConvertFrom-Json $Installables.Applications | ForEach-Object { $VersionCommand = $_.VersionCommand $InstalledVersion = (& $VersionCommand[0] $VersionCommand[1..$VersionCommand.Length]) if (-not $?) { Write-Host "$($_.Name) not installed; installing now" } else { $InstalledVersion = $InstalledVersion -join "`n" if ($InstalledVersion -match $_.VersionRegex) { if ($Matches.Count -ne 2) { Write-Error "$($_.Name) has a malformed version regex ($($_.VersionRegex)); it should have a single capture group (it has $($Matches.Count - 1))" throw } if ($Matches[1] -eq $_.Version) { Write-Host "$($_.Name) already installed and at the correct version ($($Matches[1]))" return } else { Write-Host "$($_.Name) already installed but with the incorrect version installed version: '$($Matches[1])' required version : '$($_.Version)' upgrading now." } } else { Write-Warning "$($_.Name)'s version command ($($VersionCommand -join ' ')) returned a value we did not expect: $InstalledVersion expected a version matching the regex: $($_.VersionRegex) Installing anyways." } } if ($null -ne (Get-Member -InputObject $_ -Name 'DmgUrl')) { $pathToDmg = "~/Downloads/$($_.Name).dmg" Get-RemoteFile -OutFile $pathToDmg -Uri $_.DmgUrl -Sha256 $_.Sha256 hdiutil attach $pathToDmg -mountpoint /Volumes/setup-installer if ($null -ne (Get-Member -InputObject $_ -Name 'InstallationCommands')) { $_.InstallationCommands | % { Write-Host "> $($_ -join ' ')" & $_[0] $_[1..$_.Length] | Write-Host } } elseif ($null -ne (Get-Member -InputObject $_ -Name 'InstallerPath')) { sudo installer -pkg "/Volumes/setup-installer/$($_.InstallerPath)" -target / hdiutil detach /Volumes/setup-installer } else { Write-Error "$($_.Name) installer object has a DmgUrl, but neither an InstallerPath nor an InstallationCommands" throw } } elseif ($null -ne (Get-Member -InputObject $_ -Name 'PkgUrl')) { $pathToPkg = "~/Downloads/$($_.Name).pkg" Get-RemoteFile -OutFile $pathToPkg -Uri $_.PkgUrl -Sha256 $_.Sha256 sudo installer -pkg $pathToPkg -target / } else { Write-Error "$($_.Name) does not have an installer in the configuration file." throw } } $installedVagrantPlugins = @{} vagrant plugin list --machine-readable | ForEach-Object { $timestamp, $target, $type, $data = $_ -split ',' switch ($type) { # these are not important 'ui' { } 'plugin-version-constraint' { } 'plugin-name' { $installedVagrantPlugins[$data] = $Null } 'plugin-version' { $version = $data -replace '%!\(VAGRANT_COMMA\)',',' if ($version -notmatch '^(.*), global') { Write-Error "Invalid version string for plugin ${target}: $version" throw } $installedVagrantPlugins[$target] = $Matches[1] } default { Write-Warning "Unknown plugin list member type $type for plugin $target" } } } $Installables.VagrantPlugins | ForEach-Object { if (-not $installedVagrantPlugins.Contains($_.Name)) { Write-Host "$($_.Name) not installed; installing now" } elseif ($installedVagrantPlugins[$_.Name] -ne $_.Version) { Write-Host "$($_.Name) already installed but with the incorrect version installed version: '$($installedVagrantPlugins[$_.Name])' required version: '$($_.Version)'" } else { Write-Host "$($_.Name) already installed and at the correct version ($($_.Version))" return } vagrant plugin install $_.Name --plugin-version $_.Version }