Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nuget.exe
nuget.exe
terraform.exe
8 changes: 7 additions & 1 deletion PSDepend2/PSDependMap.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Description = 'Install a Chocolatey package from a Chocolatey feed'
Supports = 'windows'
}

Command = @{
Script = 'Command.ps1'
Description = 'Invoke a command in PowerShell'
Expand Down Expand Up @@ -89,4 +89,10 @@
Description = 'Support dependencies by handling simple tasks'
Supports = 'core', 'windows', 'macos', 'linux'
}

Terraform = @{
Script = 'Terraform.ps1'
Description = 'Installs Terraform'
Supports = 'core', 'windows', 'macos', 'linux'
}
}
14 changes: 2 additions & 12 deletions PSDepend2/PSDependScripts/GitHub.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -456,18 +456,8 @@ if(($PSDependAction -contains 'Install') -and $ShouldInstall)
return
}

# Extract the zip file
if (($script:IsWindows) -and ($psEdition -eq 'Desktop') -and ($null -eq $(Get-Command -Name Expand-Archive)))
{
$ZipFile = (New-Object -com shell.application).NameSpace($OutFile)
$ZipDestination = (New-Object -com shell.application).NameSpace($OutPath)
$ZipDestination.CopyHere($ZipFile.Items())
}
else
{
# If not on Windows "Expand-Archive" should be available as PS version 6 is considered minimum.
Expand-Archive $OutFile -DestinationPath $OutPath
}
# Use our internal implementation to cater for Windows PS 5.1 and below + pwsh 6+
Expand-PSDependArchive -Path $OutFile -DestinationPath $OutPath

# Remove the zip file
Remove-Item $OutFile -Force -Confirm:$false
Expand Down
154 changes: 154 additions & 0 deletions PSDepend2/PSDependScripts/Terraform.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<#
.SYNOPSIS
Installs Terraform

.DESCRIPTION
Downloads and places the desired version of terraform on the PATH

Relevant Dependency metadata:
DependencyName (Key): This should be terraform
Target: The folder to download this file to. If a full path to a new file is used, this overrides any other file name.
AddToPath: If specified, prepend the target's parent container to PATH

.NOTES

.PARAMETER Architecture
The architecture of the binary to install. Defaults to amd64

.PARAMETER PSDependAction
Test or Install the module. Defaults to Install

Test: Return true or false on whether the dependency is in place
Install: Install the dependency

.EXAMPLE
@{
'terraform' = @{
DependencyType = "Terraform"
Version = "1.1.1"
}

Downloads terraform v1.1.1 to the current working directory

.EXAMPLE
@{
'terraform' = @{
DependencyType = "Terraform"
Target = "./Tools"
Version = "1.2.0"
}

Downloads terraform v1.2.0 to the target path relative from the current working directory. It will create the Tools folder if it doesn't already exist.

This is the recommended setup in conjunction with a local folder within your repo that is untracked by VCS where your dependencies are local to your code and
you can specify a path that is not impacted by platform you are running PSDepend on

.EXAMPLE
@{
'terraform' = @{
DependencyType = "Terraform"
Target = "/usr/bin/local"
Version = "1.2.0"
}

Downloads terraform v1.2.0 to the absolute path

.EXAMPLE
@{
'terraform' = @{
DependencyType = "Terraform"
Parameters = @{
Architecture = "arm"
}
Version = "1.2.0"
}

Downloads terraform v1.2.0 for ARM architecture
}
#>
[cmdletbinding()]
param(
[PSTypeName('PSDepend.Dependency')]
[psobject[]]
$Dependency,

$Architecture = "amd64",

[ValidateSet('Test', 'Install')]
[string[]]$PSDependAction = @('Install')
)

$VersionRegex = "(?<version>\d+\.\d+.\d+)(-(?<prereleasetag>.+)){0,1}$"
$Source = $Dependency.Source
$tf = Get-InstalledTerraformVersion
$Version = Select-String -Pattern $VersionRegex -InputObject $Dependency.Version

if (-not $Version) {
throw "Input version does not match regex"
}

$Platform = if ((Get-OSEnvironment) -eq "MacOS") { "darwin" } else { Get-OSEnvironment }
$FileName = "terraform_{0}_{1}_{2}.zip" -f $Version, $Platform.ToLower(), $Architecture
$DownloadPath = Join-Path $env:TEMP $FileName
if (-not $Dependency.target) {
$Path = Get-Location
}
else {
$Path = $Dependency.Target
}

if ($tf.IsInstalled) {
if ($tf.Version -ne $Version) {
Write-Verbose "Installed Terraform v$($tf.Version) does not match version v$($Version) required"
$InstallNeeded = $true
}
else {
Write-Verbose "Terraform v$($tf.Version) installed"
$InstallNeeded = $false
}
}
else {
Write-Verbose "Terraform not found on path"
$InstallNeeded = $true
}

if ($PSDependAction -eq "Install" -and $InstallNeeded) {
if ($Source) {
$URL = $Source
}
else {
$URL = "https://releases.hashicorp.com/terraform/{0}/{1}" -f $Version, $FileName
}
Write-Verbose "Downloading [$URL] to [$DownloadPath]"

if (-not (Test-Path $DownloadPath)) {
Write-Verbose "Version of zip not found at $DownloadPath"
try {
Get-WebFile -URL $URL -Path $DownloadPath
}
catch {
$_
throw "Unable to retrieve package from $URL"
}
}
else {
Write-Verbose "Version of zip found at $DownloadPath"
}

Write-Verbose "Extracting [$DownloadPath] to [$Path]"
Expand-PSDependArchive -Path $DownloadPath -DestinationPath $Path -Force
Write-Verbose "Terraform installed to $Path"

if ($Dependency.AddToPath) {
Write-Verbose "Setting PATH to`n$($Path, $env:PATH -join ';' | Out-String)"
Add-ToItemCollection -Reference Env:\Path -Item $Path
}

return $true
}
elseif ($PSDependAction -eq "Install" -and $InstallNeeded -eq $false) {
return $true
}
elseif ($PSDependAction -eq "Test") {
return -not $InstallNeeded
}
27 changes: 27 additions & 0 deletions PSDepend2/Private/Expand-PSDependArchive.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function Expand-PSDependArchive {
[CmdletBinding()]
param (
[String]
$Path,

[String]
$DestinationPath,

[Switch]
$Force
)

end {
# Use Windows unzip method as otherwise Expand-Archive exists and that runs on all platforms
if ($null -eq $(Get-Command -Name Expand-Archive -ErrorAction SilentlyContinue)) {
Write-Verbose "Extracting using legacy unzip method"
$ZipFile = (New-Object -com shell.application).NameSpace($Path)
$ZipDestination = (New-Object -com shell.application).NameSpace($DestinationPath)
$ZipDestination.CopyHere($ZipFile.Items())
}
else {
Write-Verbose "Extracting using current Expand-Archive function"
Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force:$Force
}
}
}
37 changes: 37 additions & 0 deletions PSDepend2/Private/Get-InstalledTerraformVersion.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function Get-InstalledTerraformVersion {
param(
[string] $VersionRegex = "(?<version>\d+\.\d+.\d+)(-(?<prereleasetag>.+)){0,1}$"
)
end {
# We don't check the whole fs for TF, either its on the path at the version we want already
# or we put the version we want where the build wants it

# We add current location to the path as the first entry to search for the terraform command. To not do this would
# result in an output message that can't be avoided which we don't want or care about
# We assume that if the client installs tf into the current directory (i.e. doesn't specify a target dir)
# then they are happy to cater for the ./<cmd> requirement for pwsh to run the binary properly
$PATH_BACKUP = $env:PATH
Add-ToItemCollection -Reference Env:\Path -Item (Get-Location)
$IsInstalled = (Get-Command terraform -ErrorAction SilentlyContinue)
if ($IsInstalled) {
$g = ((terraform --version)[0] | Select-String -Pattern $VersionRegex).Matches.Groups
$env:PATH = $PATH_BACKUP
$VersionCore = ($g | Where-Object Name -EQ "Version").Value
$PreRelease = ($g | Where-Object Name -EQ "PreReleaseTag").Value
return ([psobject]@{
IsInstalled = $true
Version = "{0}{1}" -f $VersionCore, $PreReleaseTag
VersionCore = $VersionCore
PreRelease = $PreRelease
IsPreRelease = if ($null -ne $PreRelease) { $true } else { $false }
})
}
else {
$env:PATH = $PATH_BACKUP
return ([psobject]@{
IsInstalled = $false
IsPreRelease = $false
})
}
}
}
6 changes: 6 additions & 0 deletions Tests/DependFiles/terraform.depend.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
'terraform' = @{
DependencyType = "Terraform"
Version = "1.1.1"
}
}
6 changes: 6 additions & 0 deletions Tests/DependFiles/terraform_bad_version.depend.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
'terraform' = @{
DependencyType = "Terraform"
Version = "a.1.1"
}
}
6 changes: 6 additions & 0 deletions Tests/DependFiles/terraform_no_version.depend.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
'terraform' = @{
DependencyType = "Terraform"
Version = "0.0.0"
}
}
Loading