Skip to content
Merged
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
82 changes: 66 additions & 16 deletions PSDepend/PSDependScripts/Chocolatey.ps1
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
<#
.SYNOPSIS
Installs a Chocolatey package a repository.
Installs a package from a Chocolatey repository.

.DESCRIPTION
Installs a package from a Chocolatey repository like Chocolatey.org.
Installs a package from a Chocolatey repository like the Chocolatey community repository.

Relevant Dependency metadata:
Name: The name of the package
Version: Used to identify existing installs meeting this criteria. Defaults to 'latest'
Source: Source Uri. Defaults to https://chocolatey.org/api/v2/
Source: Source Uri. Defaults to https://community.chocolatey.org/api/v2/

.PARAMETER Dependency
Dependency to process

.PARAMETER Force
If specified and the package is already installed, force the install again.

.PARAMETER ChocoInstallScriptUrl
Url to the script used to bootstrap Chocolatey when choco.exe is not found.
Defaults to https://community.chocolatey.org/install.ps1

.PARAMETER PSDependAction
Test, or Install the package. Defaults to Install

Expand All @@ -27,7 +34,7 @@
}
}

# Install version 2.0.2 of git via Chocolatey.org
# Install version 2.0.2 of git from the Chocolatey community repository

.EXAMPLE
@{
Expand All @@ -54,7 +61,7 @@
'putty' = 'latest'
}

# Installs the list of Chocolatey packages from Chocolatey.org using the Global PSDependOptions to limit repetition.
# Installs the list of Chocolatey packages from the Chocolatey community repository using the Global PSDependOptions to limit repetition.

#>
[CmdletBinding()]
Expand All @@ -64,12 +71,33 @@ param(

[switch]$Force,

[string]$ChocoInstallScriptUrl = 'https://chocolatey.org/install.ps1',
[string]$ChocoInstallScriptUrl = 'https://community.chocolatey.org/install.ps1',

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

function Get-ChocoVersion {
[CmdletBinding()]
param ()

$invokeExternalCommandSplat = @{
Command = 'choco.exe'
Arguments = @('--version')
PassThru = $true
}
$rawVersion = [string](Invoke-ExternalCommand @invokeExternalCommandSplat | Select-Object -First 1)
[System.Version]$parsedVersion = $null
# Strip prerelease/build metadata (e.g. 2.2.2-beta) before parsing
if ([System.Version]::TryParse(($rawVersion -replace '[-+].*$'), [ref]$parsedVersion)) {
$parsedVersion
}
else {
# Assume a modern CLI when the version cannot be determined
[System.Version]'2.0'
}
}

function Get-ChocoInstalledPackage {
[CmdletBinding()]
param (
Expand All @@ -80,9 +108,13 @@ function Get-ChocoInstalledPackage {
'list',
"$Name",
'--limit-output',
'--exact',
'--local-only'
'--exact'
)
# Chocolatey 2.0 removed --local-only ('choco list' is now local-only by default);
# before 2.0, 'choco list' queried remote sources unless the flag was passed
if ((Get-ChocoVersion).Major -lt 2) {
$chocoParams += '--local-only'
}
$invokeExternalCommandSplat = @{
Command = 'choco.exe'
Arguments = $chocoParams
Expand All @@ -105,7 +137,9 @@ function Get-ChocoLatestPackage {
[Management.Automation.PSCredential]$Credential
)

$chocoParams = @('list', "$Name", '--limit-output', '--exact')
# 'choco search' queries remote sources on both 1.x and 2.x; 'choco list' stopped
# querying remote sources in Chocolatey 2.0 and rejects URL sources (issue #187)
$chocoParams = @('search', "$Name", '--limit-output', '--exact')
if ($Source) {
$chocoParams += "--source='$Source'"
}
Expand Down Expand Up @@ -191,7 +225,7 @@ if (-not $Dependency.Version -or $Version -eq '') {

$Source = $Dependency.Source
if (-not $Dependency.Source -or $Source -eq '') {
$Source = 'https://chocolatey.org/api/v2/'
$Source = 'https://community.chocolatey.org/api/v2/'
}

$Credential = $Dependency.Credential
Expand All @@ -211,7 +245,7 @@ if (-not (Get-Command -Name 'choco.exe' -ErrorAction SilentlyContinue)) {
& $scriptPath
}
catch {
throw "Unable to install Chocolatey from '$scriptUrl'."
throw "Unable to install Chocolatey from '$ChocoInstallScriptUrl'."
}
}

Expand Down Expand Up @@ -245,8 +279,8 @@ else {
Write-Verbose "Package [$Name] not installed."
}

# Version latest requested, and equal to current
if ($Version -ne 'latest' -and $Version -eq $existingVersion) {
# Specific version requested, and equal to current
if ($Version -ne 'latest' -and (Test-VersionEquality -ReferenceVersion $Version -DifferenceVersion $existingVersion)) {
Write-Verbose "You have the requested version [$Version] of [$Name]"
if ($PSDependAction -contains 'Test') {
return $true
Expand Down Expand Up @@ -275,10 +309,26 @@ else {
}

# If the version in the remote repository is less than or equal to the version installed, then we have the latest already
if (
$Version -eq 'latest' -and
([System.Version]$repositoryVersion -le [System.Version]$existingVersion)
[System.Version]$parsedRepositoryVersion = $null
[System.Version]$parsedExistingVersion = $null
[System.Management.Automation.SemanticVersion]$parsedRepositorySemanticVersion = $null
[System.Management.Automation.SemanticVersion]$parsedExistingSemanticVersion = $null
$haveLatest = if (
[System.Management.Automation.SemanticVersion]::TryParse([string]$repositoryVersion, [ref]$parsedRepositorySemanticVersion) -and
[System.Management.Automation.SemanticVersion]::TryParse([string]$existingVersion, [ref]$parsedExistingSemanticVersion)
) {
$parsedRepositorySemanticVersion -le $parsedExistingSemanticVersion
}
elseif (
[System.Version]::TryParse([string]$repositoryVersion, [ref]$parsedRepositoryVersion) -and
[System.Version]::TryParse([string]$existingVersion, [ref]$parsedExistingVersion)
) {
$parsedRepositoryVersion -le $parsedExistingVersion
}
else {
$false
}
if ($Version -eq 'latest' -and $haveLatest) {
Write-Verbose "You have the latest version of [$Name], with installed version [$existingVersion] and Source version [$repositoryVersion]"
if ($PSDependAction -contains 'Test') {
return $true
Expand Down
5 changes: 4 additions & 1 deletion PSDepend/PSDependScripts/Command.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
.PARAMETER Dependency
Dependency to process

.PARAMETER FailOnError
If specified, throw a terminating error if the command errors out

.EXAMPLE
@{
ExampleCommand = @{
Expand All @@ -30,13 +33,13 @@
}
}

# Run some aribtrary PowerShell code that assigns a variable and uses it in a string

Check warning on line 36 in PSDepend/PSDependScripts/Command.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (aribtrary) Suggestions: (arbitrary, arbitral, arbitrage, arbitrate, arbitrarily)
# Output: Running a command on WJ-LAB
#>
[cmdletbinding()]

Check warning on line 39 in PSDepend/PSDependScripts/Command.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (cmdletbinding)
param (
[PSTypeName('PSDepend.Dependency')]
[psobject[]]$Dependency,

Check warning on line 42 in PSDepend/PSDependScripts/Command.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psobject) Suggestions: (isobject, isObject, project, object, subject)

[switch]$FailOnError,

Expand All @@ -48,7 +51,7 @@

foreach ($Depend in $Dependency) {
foreach ($Command in $Depend.Source) {
Write-Verbose "Invoking command [$($Dependency.DependencyName)]:`n$Command"
Write-Verbose "Invoking command [$($Depend.DependencyName)]:`n$Command"
$ScriptBlock = [ScriptBlock]::Create($Command)
Try {
. $ScriptBlock
Expand Down
29 changes: 18 additions & 11 deletions PSDepend/PSDependScripts/FileSystem.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,30 @@
.EXAMPLE

@{
'psams' = @{

Check warning on line 52 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psams) Suggestions: (spams, prams, psalms, Psalms, spasm)
DependencyType = 'FileSystem'
Source = '\\FileServer\powershell\modules\psams'

Check warning on line 54 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psams) Suggestions: (spams, prams, psalms, Psalms, spasm)
Target = 'C:\ProjectX'
}
}

# Copy psams module to C:\ProjectX\psams

Check warning on line 59 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psams) Suggestions: (spams, prams, psalms, Psalms, spasm)

Check warning on line 59 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psams) Suggestions: (spams, prams, psalms, Psalms, spasm)

#>
[cmdletbinding()]

Check warning on line 62 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (cmdletbinding)
param (
[PSTypeName('PSDepend.Dependency')]
[psobject[]]

Check warning on line 65 in PSDepend/PSDependScripts/FileSystem.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psobject) Suggestions: (isobject, isObject, project, object, subject)
$Dependency,

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

[string]$ImportPath
[string]$ImportPath,

[switch]$Force,

[switch]$Mirror
)

# Extract data from Dependency
Expand All @@ -80,8 +84,8 @@
$TestOutput = @()
foreach ($Source in @($Sources)) {
if (-not (Test-Path $Source)) {
if (-not $PSDependAction -like 'Test') {
Write-Error "Skipping $DependencyName, could not find source [$Sources] due to error:"
if ($PSDependAction -notcontains 'Test') {
Write-Error "Skipping $DependencyName, could not find source [$Source]"
}
Comment thread
HeyItsGilbert marked this conversation as resolved.
continue
}
Expand All @@ -102,10 +106,13 @@
else {
$TestOutput += $false
}
if ($PSDependAction -like 'Install') {
if ($PSDependAction -contains 'Install') {
# TODO: Add non Windows equivalent...
[string[]]$Arguments = "/XO"
$Arguments += "/E"
[string[]]$Arguments = "/E"
if (-not ($Dependency.Parameters.Force -eq $True -or $Force)) {
# Without -Force, skip files where the target copy is newer
$Arguments += "/XO"
}
if ($Dependency.Parameters.Mirror -eq $True -or $Mirror) {
$Arguments += "/PURGE"
}
Expand All @@ -132,24 +139,24 @@

if ($TargetHash -ne $SourceHash) {
Write-Verbose "Hashes do not match"
if ($PSDependAction -like 'Install') {
if ($PSDependAction -contains 'Install') {
Write-Verbose "Copying file [$Source] to [$Target]"
Copy-Item -Path $Source -Destination $Target -Force
}
if ($PSDependAction -like 'Test' -and $PSDependAction.count -eq 1) {
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
$TestOutput += $false
}
}
else {
Write-Verbose "Matching hash: [$Source] = [$TargetFile]"
if ($PSDependAction -like 'Test' -and $PSDependAction.count -eq 1) {
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
$TestOutput += $True
}
}
}
}

if ($PSDependAction -like 'Test' -and $PSDependAction.count -eq 1) {
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
if (@($TestOutput) -contains $false -or @($TestOutput) -notcontains $true) {
return $false
}
Expand All @@ -158,7 +165,7 @@
}
}

if ($PSDependAction -like 'Import') {
if ($PSDependAction -contains 'Import') {
if (-not $ImportPath) {
if (Test-Path $Target -PathType Leaf) {
$ImportPath = Split-Path $Target -Parent
Expand Down
1 change: 1 addition & 0 deletions PSDepend/PSDependScripts/Git.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

.EXAMPLE
@{
'buildhelpers' = @{

Check warning on line 34 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (buildhelpers)
Name = 'https://github.com/RamblingCookieMonster/BuildHelpers.git'
Version = 'd32a9495c39046c851ceccfb7b1a85b17d5be051'
Target = 'C:\git'
Expand Down Expand Up @@ -118,6 +118,7 @@

if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Error "Git dependency type requires git. Ensure this is in your path, or explicitly specified in $ModuleRoot\PSDepend.Config's GitPath. Skipping [$DependencyName]"
return
}

$Version = $Dependency.Version
Expand Down
12 changes: 2 additions & 10 deletions PSDepend/PSDependScripts/GitHub.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -412,15 +412,7 @@ if (($PSDependAction -contains 'Install') -and $ShouldInstall) {
}

# Extract the zip file
if ($script:IsWindows) {
$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
}
Expand-Archive -Path $OutFile -DestinationPath $OutPath

# Remove the zip file
Remove-Item $OutFile -Force -Confirm:$false
Expand Down Expand Up @@ -454,7 +446,7 @@ if (($PSDependAction -contains 'Install') -and $ShouldInstall) {

# Copy the contents to their target
if (-not (Test-Path $TargetPath)) {
New-Item $TargetPath -ItemType "directory" -Force
$null = New-Item $TargetPath -ItemType "directory" -Force
}

$Destination = $null
Expand Down
3 changes: 1 addition & 2 deletions PSDepend/PSDependScripts/Npm.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ If (-not [string]::IsNullOrEmpty($Target) -and $Target -ne 'global') {
# Otherwise, assume that its a folder _in the current directory_.
# If no target is specified, it will install to the current directory.
If ($Target -notmatch '(^/|:|\\\\)') {
$Target = "$PWD\$Target"
$Target = Join-Path $PWD $Target
}
If (-not (Test-Path $Target) -and $PSDependAction -contains 'Install') {
Write-Verbose "Creating folder [$Target] for node module dependency [$Name]"
Expand All @@ -83,7 +83,6 @@ If (-not [string]::IsNullOrEmpty($Target) -and $Target -ne 'global') {
#endregion Extract Dependency Data
#region Test Action
If ($PSDependAction -contains 'Test') {
$PackageListArguments = 'ls --json --silent'
If ([string]::IsNullOrEmpty($Target)) {
$InstalledNodeModules = Get-NodeModule
}
Expand Down
40 changes: 30 additions & 10 deletions PSDepend/PSDependScripts/PSGalleryNuget.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,37 @@ if (Test-Path $ModulePath) {
}

# latest, and we have latest
if ( $Version -and
($Version -eq 'latest' -or $Version -like '') -and
($GalleryVersion = (& $GetGalleryVersion)) -le $ExistingVersion
) {
Write-Verbose "You have the latest version of [$Name], with installed version [$ExistingVersion] and PSGallery version [$GalleryVersion]"
# Conditional import
Import-PSDependModule -Name $ModulePath -Action $PSDependAction -Version $ExistingVersion
if ($PSDependAction -contains 'Test') {
return $True
if ($Version -and ($Version -eq 'latest' -or $Version -like '')) {
$GalleryVersion = & $GetGalleryVersion
[System.Version]$parsedExistingVersion = $null
[System.Version]$parsedGalleryVersion = $null
[System.Management.Automation.SemanticVersion]$parsedExistingSemanticVersion = $null
[System.Management.Automation.SemanticVersion]$parsedGallerySemanticVersion = $null
$isGalleryVersionLessEquals = if (
[System.Management.Automation.SemanticVersion]::TryParse([string]$ExistingVersion, [ref]$parsedExistingSemanticVersion) -and
[System.Management.Automation.SemanticVersion]::TryParse([string]$GalleryVersion, [ref]$parsedGallerySemanticVersion)
) {
$parsedGallerySemanticVersion -le $parsedExistingSemanticVersion
}
elseif (
[System.Version]::TryParse([string]$ExistingVersion, [ref]$parsedExistingVersion) -and
[System.Version]::TryParse([string]$GalleryVersion, [ref]$parsedGalleryVersion)
) {
$parsedGalleryVersion -le $parsedExistingVersion
}
else {
$false
}

if ($isGalleryVersionLessEquals) {
Write-Verbose "You have the latest version of [$Name], with installed version [$ExistingVersion] and PSGallery version [$GalleryVersion]"
# Conditional import
Import-PSDependModule -Name $ModulePath -Action $PSDependAction -Version $ExistingVersion
if ($PSDependAction -contains 'Test') {
return $True
}
return $null
}
return $null
}

Write-Verbose "Removing existing [$ModulePath]`nContinuing to install [$Name]: Requested version [$version], existing version [$ExistingVersion]"
Expand Down
5 changes: 3 additions & 2 deletions PSDepend/PSDependScripts/Task.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Support dependencies by handling simple tasks.

Relevant Dependency metadata:
Target: One or more scripts to run for this task
Target: One or more scripts to run for this task (Source is honored as an alias)
Parameters: Parameters to call against the task scripts

.PARAMETER PSDependAction
Expand Down Expand Up @@ -57,7 +57,8 @@ param (
Write-Verbose "Executing $($Dependency.count) tasks"

foreach ($Depend in $Dependency) {
foreach ($Task in $Depend.Source) {
$Tasks = if ($Depend.Source) { $Depend.Source } else { $Depend.Target }
foreach ($Task in $Tasks) {
if (Test-Path $Task -PathType Leaf) {
$params = @{}
if ($Depend.Parameters) {
Expand Down
4 changes: 2 additions & 2 deletions Tests/Chocolatey.Type.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ Describe 'Chocolatey script' -Tag 'WindowsOnly' -Skip:$SkipUnsupported {
}
}

It 'Defaults Source to https://chocolatey.org/api/v2/ when not supplied' {
It 'Defaults Source to https://community.chocolatey.org/api/v2/ when not supplied' {
$dep = New-PSDependFixture -DependencyName 'git' -DependencyType 'Chocolatey'
InModuleScope PSDepend -Parameters @{ Dep = $dep; ScriptPath = $script:ScriptPath } {
& $ScriptPath -Dependency $Dep -Force
}
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 1 -Exactly -ParameterFilter {
($Arguments -join ' ') -match "--source='https://chocolatey\.org/api/v2/'"
($Arguments -join ' ') -match "--source='https://community\.chocolatey\.org/api/v2/'"
}
}

Expand Down
Loading
Loading