LibreDevOpsHelpers.Tenv/LibreDevOpsHelpers.Tenv.psm1
|
Set-StrictMode -Version Latest function Install-LdoTenv { <# .SYNOPSIS Installs the tenv version manager if it is not already present. .DESCRIPTION Installs tenv via Chocolatey on Windows or Homebrew on other platforms when the tenv command is not found on PATH. .EXAMPLE Install-LdoTenv .OUTPUTS None #> [CmdletBinding()] [OutputType([void])] param() if (Get-Command tenv -ErrorAction SilentlyContinue) { Write-LdoLog -Level INFO -Message 'tenv already installed.' return } $os = Get-LdoOperatingSystem if ($os -eq 'windows') { Assert-LdoChocoPath Write-LdoLog -Level INFO -Message 'Installing tenv via Chocolatey.' choco install tenv -y } else { Assert-LdoHomebrewPath Write-LdoLog -Level INFO -Message 'Installing tenv via Homebrew.' brew install tenv } } function Test-LdoTenv { <# .SYNOPSIS Tests whether tenv is available on PATH. .DESCRIPTION Returns $true when the tenv command is found, otherwise $false. .EXAMPLE if (Test-LdoTenv) { Invoke-LdoTenvTerraformInstall } .OUTPUTS System.Boolean #> [CmdletBinding()] [OutputType([bool])] param() $tenvPath = Get-Command tenv -ErrorAction SilentlyContinue if ($tenvPath) { Write-LdoLog -Level INFO -Message "tenv found at: $($tenvPath.Source)" return $true } Write-LdoLog -Level WARN -Message 'tenv is not installed or not in PATH.' return $false } function Invoke-LdoTenvTerraformInstall { <# .SYNOPSIS Installs and selects a Terraform version via tenv. .DESCRIPTION Uses tenv to install and select Terraform. 'latest' installs the newest release, 'latest-1' installs the latest patch of the previous minor release, and any other value is treated as a version constraint matched against tenv's remote list. .PARAMETER TerraformVersion 'latest', 'latest-1', or a version constraint such as '1.7'. Defaults to 'latest'. .PARAMETER TenvArgs Additional arguments passed through to tenv. .EXAMPLE Invoke-LdoTenvTerraformInstall -TerraformVersion 1.7 .OUTPUTS None #> [CmdletBinding()] [OutputType([void])] param( [string]$TerraformVersion = 'latest', [string[]]$TenvArgs = @() ) $orig = Get-Location try { $tenvPath = Get-Command tenv -ErrorAction Stop Write-LdoLog -Level INFO -Message "tenv found at: $($tenvPath.Source)" if ($TerraformVersion -notin @('latest', 'latest-1')) { Write-LdoLog -Level INFO -Message "Desired Terraform version is $TerraformVersion; installing/switching via tenv." $escapedConstraint = [regex]::Escape($TerraformVersion) $version = tenv tf list-remote | Select-String "^${escapedConstraint}\." | Select-Object -Last 1 | ForEach-Object { $_.ToString().Trim() } $cleanVersion = $version -replace '\s*\(installed\)\s*', '' if ([string]::IsNullOrWhiteSpace($cleanVersion)) { throw "No matching Terraform version for '$TerraformVersion'." } Write-LdoLog -Level INFO -Message "Installing Terraform version $cleanVersion." tenv tf install $cleanVersion tenv tf use $cleanVersion } elseif ($TerraformVersion -eq 'latest') { Write-LdoLog -Level INFO -Message 'Installing latest Terraform via tenv.' tenv tf install latest $TenvArgs tenv tf use latest $TenvArgs } else { Write-LdoLog -Level INFO -Message 'Installing previous minor Terraform release via tenv.' $all = tenv tf list-remote | Select-String '^\d+\.\d+\.\d+$' | ForEach-Object { $_.ToString().Trim() } if (-not $all) { throw 'tenv returned no remote Terraform versions.' } $latest = $all[-1] if ($latest -notmatch '^(\d+)\.(\d+)\.(\d+)$') { throw "Unexpected version format: $latest" } $major, $minor = $matches[1], [int]$matches[2] $previous = $all | Where-Object { $_ -match "^\Q$major\E\.\Q$($minor - 1)\E\.\d+$" } | Select-Object -Last 1 if (-not $previous) { throw 'Cannot install previous minor Terraform version; no previous minor release found.' } Write-LdoLog -Level INFO -Message "Installing Terraform version $previous." tenv tf install $previous $TenvArgs tenv tf use $previous $TenvArgs } } finally { Set-Location $orig } } Export-ModuleMember -Function ` Install-LdoTenv, ` Test-LdoTenv, ` Invoke-LdoTenvTerraformInstall |