Skip to content

Instantly share code, notes, and snippets.

@bew
Created January 17, 2024 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bew/ac0aa9ade8dfa88c1f9ed5f4ae91db28 to your computer and use it in GitHub Desktop.
Save bew/ac0aa9ade8dfa88c1f9ed5f4ae91db28 to your computer and use it in GitHub Desktop.
Set of 'package manager' like functions to help setup a powershell testing env
# This module defines helper functions to help with local/CI testing PowerShell code,
# like checking pwsh version, installing up necessary modules..
function Assert-PowerShellVersion {
param(
[Parameter(Mandatory)]
[string]$MinimumVersion
)
if ($PSVersionTable.PSVersion -le [System.Version]$MinimumVersion) {
throw "PowerShell minimum version $MinimumVersion is required, current version is: $($PSVersionTable.PSVersion)"
}
}
function Check-VersionAgainstConstraints {
param(
[Parameter(Mandatory, Position = 0)]
[System.Version]$givenVersion,
[Parameter(Mandatory, Position = 1)]
[hashtable]$VersionConstraints
)
Set-StrictMode -Off # Disabled locally, to ease check for missing properties
[System.Version]$min = $VersionConstraints.MinimumVersion ?? "0.0.0"
[System.Version]$max = $VersionConstraints.MaximumVersion # allow $null
if (!$max) {
$min -le $givenVersion
}
else {
$min -le $givenVersion -and $givenVersion -le $max
}
}
function Ensure-AllModulesAvailable {
param(
[Parameter(Mandatory, Position = 0)]
[hashtable]$modulesToCheck
)
foreach ($moduleName in $modulesToCheck.Keys) {
# Wrap the loop body with a re-throwing try-catch, to ensure an error in the loop is
# correctly propagated and stops the script.
# (In PowerShell7 (@2024-01), a cmd failing with an error in a loop will just print the
# error and ignore it, continuing as normal :/)
try {
Ensure-ModuleAvailable $moduleName -VersionConstraints $modulesToCheck[$moduleName]
}
catch {
throw $_
}
}
}
function Ensure-ModuleAvailable {
param(
[Parameter(Mandatory, Position = 0)]
[string]$Name,
[Parameter(Mandatory, HelpMessage = "Version constraints with fields like `MinimumVersion`, `MaximumVersion`. Must be compatible to being passed to 'Install-Module' & 'Import-Module'")]
[hashtable]$VersionConstraints
)
# Check the module is installed, and the version constraints are respected
Write-Host "Checking module '$Name'"
# NOTE: since there is no way to easily check that a package following version constraints is installed
# we have to get all versions of a given package and check the versions ourselves..
$module = (
Get-Module -Name $Name -ListAvailable
| Where-Object { Check-VersionAgainstConstraints $_.Version $VersionConstraints }
| Select-Object -Last 1
)
if ($module) {
Write-Host " 👍 Module '$Name' is already installed"
}
else {
Write-Host " ❌ Module '$Name' is not installed or not at correct version"
Write-Host " 👉 Installing module '$Name' with version constraints: $($VersionConstraints | ConvertTo-Json -Compress -Depth 10)"
Install-Module -Name $Name -Force -Scope CurrentUser -SkipPublisherCheck @VersionConstraints
}
}
Set-StrictMode -Version 3.0; $ErrorActionPreference = "Stop" # Ensure sane behavior
Import-Module $PSScriptRoot\..\..\powershell-modules\Pwsh-Testing-Utils.ps1 -force
# Require PowerShell 7 (version 5 is OLD!)
Assert-PowerShellVersion -MinimumVersion "7.0.0"
# Ensure required modules are installed for tests
Ensure-AllModulesAvailable @{
"Pester" = @{ MinimumVersion = "5.2.0" }
"Az" = @{ MinimumVersion = "11.2.0" }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment