PSTerraformEnv.psm1


if ([string]::IsNullOrEmpty($env:TFENV_ROOT)) { $env:TFENV_ROOT = "$HOME/.config/tfenv" }
if ([string]::IsNullOrEmpty($env:TFENV_REMOTE)) { $env:TFENV_REMOTE = "https://releases.hashicorp.com" }

$VersionPath = "$env:TFENV_ROOT/versions"

$Arch = ((arch) -match "x86_64") ? "amd64" : "386"

Test-Path $VersionPath || throw 'No versions of terraform installed. Install one with: Install-TerraformVersion'

# Support for Linux, and maybe macOS, but I don't have a Windows machine to test this on. Sorry Windows users.
if ($IsLinux) {
  $Platform = "linux"
} elseif ($IsMacOS) {
  $Platform = "darwin"
} else {
  throw "OS not supported"
}

Function Get-InstalledTerraformVersion() {
  [CmdletBinding()]
  Param(
    [Parameter(Position=0)]
    $Version = "",
    $Path = "$VersionPath"
  )
  $LocalVersions = (Get-ChildItem -Path $Path terraform-*).Name
  [regex]::Matches($LocalVersions, "\d+\.\d+\.\d+(-(rc|beta|alpha|oci)\d*)?").Value | Sort-Object -Unique -Stable | where { $_ -match $Version }
}
Set-Alias gitfv Get-InstalledTerraformVersion


Function Remove-TerraformVersion() {
  [CmdletBinding()]
  Param(
    [Parameter(Position=0,mandatory=$true)]
    $Version
  )
  if ([string]::IsNullOrEmpty($Version)) { throw "You must specify a version number to remove. 'Remove-TerraformVersion 1.0.1'" }
  Get-ChildItem "$VersionPath/terraform-${Version}" | Sort-Object -Bottom 1 -Descending | Remove-Item -Verbose -Confirm
}
Set-Alias rtfv Remove-TerraformVersion

Function Install-TerraformVersion() {
  [CmdletBinding()]
  Param(
    [Parameter(Position=0)]
    $Version = $(Get-Content "$PWD/.terraform-version"),
    $DownloadPath = "/tmp",
    $InstallPath = "$env:TFENV_ROOT/versions"
  )

  $ArchiveFileName = "terraform_${Version}_${Platform}_${Arch}.zip"
  $DownloadFile = "$DownloadPath/$ArchiveFileName"
  $TempFile = "$DownloadPath/terraform"

  $VersionUri = "${env:TFENV_REMOTE}/terraform/${Version}"

  $Uri = "${VersionUri}/$ArchiveFileName"
  Invoke-WebRequest -Uri "$Uri" -OutFile "$DownloadFile"
  Expand-Archive -Force -Path "$DownloadFile" -DestinationPath $DownloadPath
  Move-Item -Force -Path "$TempFile" -Destination "$InstallPath/terraform-${Version}" && Remove-Item "$DownloadFile"
  (Test-Path "$InstallPath/terraform-${Version}" | Out-Null) && chmod 700 "$InstallPath/terraform-${Version}"
}
Set-Alias itfv Install-TerraformVersion

Function Switch-TerraformVersion() {
  [CmdletBinding()]
  Param(
    [Parameter(Position=0)]
    $Version = $(Get-Content "$PWD/.terraform-version")
  )
  if ([string]::IsNullOrEmpty($Version)) { throw "No version specified. Either ""'1.0.1' > .terraform-version && Switch-TerraformVersion"" or ""Switch-TerraformVersion 1.0.1""" }
  New-Item -Force -ItemType SymbolicLink -Path "$VersionPath" -name terraform -value terraform-$Version -Confirm
}
Set-Alias swtfv Switch-TerraformVersion

Function Find-TerraformVersion() {
  [CmdletBinding()]
  Param(
    [Parameter(Position=0)]
    $Version = ""
  )
  $RemoteVersions = Invoke-RestMethod "${env:TFENV_REMOTE}/terraform/"
  [regex]::Matches($RemoteVersions, "\d+\.\d+\.\d+(-(rc|beta|alpha|oci)\d*)?").Value | Sort-Object -Unique -Stable  | where { $_ -match $Version }
}
Set-Alias fdtfv Find-TerraformVersion

# to interact with terraform, lets set a couple aliases so nothing needs to be added to the PATH
Set-Alias tf "$VersionPath/terraform"
Set-Alias terraform "$VersionPath/terraform"