Skip to content

Commit 8bd52b9

Browse files
author
Justin Grote
committed
Add some basic Update functionality
1 parent 3b03a80 commit 8bd52b9

2 files changed

Lines changed: 77 additions & 37 deletions

File tree

ModuleFast.ps1

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ function Install-ModuleFast {
3333
#By default will modify your PSModulePath to use the builtin destination if not present. Setting this implicitly skips profile update as well.
3434
[Switch]$NoPSModulePathUpdate,
3535
#Setting this won't add the default destination to your profile.
36-
[Switch]$NoProfileUpdate
36+
[Switch]$NoProfileUpdate,
37+
#Setting this will check remote if the module spec has a higher bound than any currently installed local packages.
38+
[Switch]$Update
3739
)
3840

3941
# Setup the Destination repository
@@ -67,7 +69,7 @@ function Install-ModuleFast {
6769
$WhatIfPreference = $false
6870
$httpClient = New-ModuleFastClient -Credential $Credential
6971
Write-Progress -Id 1 -Activity 'Install-ModuleFast' -Status 'Plan' -PercentComplete 1
70-
$plan = Get-ModuleFastPlan $ModulesToInstall -HttpClient $httpClient -Source $Source
72+
$plan = Get-ModuleFastPlan $ModulesToInstall -HttpClient $httpClient -Source $Source -Update:$Update
7173
$WhatIfPreference = $currentWhatIfPreference
7274

7375
if ($plan.Count -eq 0) {
@@ -199,7 +201,7 @@ function Get-ModuleFastPlan {
199201
#This try finally is so that we can interrupt all http call tasks if Ctrl-C is pressed
200202
try {
201203
foreach ($moduleSpec in $ModulesToResolve) {
202-
[string]$localMatch = Find-LocalModule $moduleSpec
204+
[string]$localMatch = Find-LocalModule $moduleSpec -Update:$Update
203205
if ($localMatch -and -not $Update) {
204206
Write-Verbose "Found local module $localMatch that satisfies $moduleSpec. Skipping..."
205207
#TODO: Capture this somewhere that we can use it to report in the deploy plan
@@ -1107,31 +1109,37 @@ function Add-DestinationToPSModulePath {
11071109

11081110
# Check if the destination is in the PSModulePath
11091111
[string[]]$modulePaths = $env:PSModulePath -split [Path]::PathSeparator
1112+
if ($Destination -in $modulePaths) {
1113+
Write-Debug "Destination '$Destination' is already in the PSModulePath, we will assume it is already configured correctly"
1114+
return
1115+
}
1116+
1117+
Write-Verbose "Updating PSModulePath to include $Destination"
1118+
$modulePaths += $Destination
1119+
$env:PSModulePath = $modulePaths -join [Path]::PathSeparator
11101120

1111-
if ($Destination -notin $modulePaths) {
1112-
Write-Verbose "Updating PSModulePath to include $Destination"
1113-
$modulePaths += $Destination
1114-
$env:PSModulePath = $modulePaths -join [Path]::PathSeparator
1121+
if ($NoProfileUpdate) {
1122+
Write-Debug 'Skipping updating the profile because -NoProfileUpdate was specified'
1123+
return
11151124
}
11161125

1117-
if (-not $NoProfileUpdate) {
1118-
#TODO: Support other profiles?
1119-
$myProfile = $profile.CurrentUserAllHosts
1126+
#TODO: Support other profiles?
1127+
$myProfile = $profile.CurrentUserAllHosts
11201128

1121-
if (-not (Test-Path $myProfile)) {
1122-
if (-not $PSCmdlet.ShouldProcess($myProfile, "Allow ModuleFast to work by creating a profile at $myProfile.")) { return }
1123-
Write-Verbose 'User All Hosts profile not found, creating one.'
1124-
New-Item -ItemType File -Path $myProfile -Force | Out-Null
1125-
}
1126-
$ProfileLine = "`$env:PSModulePath += '$([IO.Path]::PathSeparator + $Destination)' #Added by ModuleFast. DO NOT EDIT THIS LINE. If you do not want this, add -NoProfileUpdate to Install-ModuleFast."
1127-
if ((Get-Content -Raw $myProfile) -notmatch [Regex]::Escape($ProfileLine)) {
1128-
if (-not $PSCmdlet.ShouldProcess($myProfile, "Allow ModuleFast to work by adding $Destination to your PSModulePath on startup by appending to your CurrentUserAllHosts profile.")) { return }
1129-
Write-Verbose "Adding $Destination to profile $myProfile"
1130-
Add-Content -Path $myProfile -Value "`n`n"
1131-
Add-Content -Path $myProfile -Value $ProfileLine
1132-
} else {
1133-
Write-Verbose "PSModulePath $Destination already in profile, skipping..."
1134-
}
1129+
if (-not (Test-Path $myProfile)) {
1130+
if (-not $PSCmdlet.ShouldProcess($myProfile, "Allow ModuleFast to work by creating a profile at $myProfile.")) { return }
1131+
Write-Verbose 'User All Hosts profile not found, creating one.'
1132+
New-Item -ItemType File -Path $myProfile -Force | Out-Null
1133+
}
1134+
1135+
[string]$profileLine = "if ('$destination' -notin (`$env:PSModulePath -split [Path]::PathSeparator)) { `$env:PSModulePath += `$([IO.Path]::PathSeparator + '$Destination') } #Added by ModuleFast. DO NOT EDIT THIS LINE. If you do not want this, add -NoProfileUpdate to Install-ModuleFast."
1136+
if ((Get-Content -Raw $myProfile) -notmatch [Regex]::Escape($ProfileLine)) {
1137+
if (-not $PSCmdlet.ShouldProcess($myProfile, "Allow ModuleFast to work by adding $Destination to your PSModulePath on startup by appending to your CurrentUserAllHosts profile.")) { return }
1138+
Write-Verbose "Adding $Destination to profile $myProfile"
1139+
Add-Content -Path $myProfile -Value "`n`n"
1140+
Add-Content -Path $myProfile -Value $ProfileLine
1141+
} else {
1142+
Write-Verbose "PSModulePath $Destination already in profile, skipping..."
11351143
}
11361144
}
11371145

@@ -1142,7 +1150,8 @@ Searches local PSModulePath repositories
11421150
function Find-LocalModule {
11431151
param(
11441152
[Parameter(Mandatory)][ModuleFastSpec]$ModuleSpec,
1145-
[string[]]$ModulePath = $($env:PSModulePath -split [Path]::PathSeparator)
1153+
[string[]]$ModulePath = $($env:PSModulePath -split [Path]::PathSeparator),
1154+
[Switch]$Update
11461155
)
11471156
$ErrorActionPreference = 'Stop'
11481157
# BUG: Prerelease Module paths are still not recognized by internal PS commands and can break things
@@ -1233,6 +1242,11 @@ function Find-LocalModule {
12331242

12341243
[string]$matchingManifest = $candidateVersions[$versionMatch]
12351244

1245+
if ($Update -and $moduleSpec.Max -gt [ModuleFastSpec]::ParseVersion($versionMatch)) {
1246+
Write-Debug "$moduleSpec`: Found a matching module version $versionMatch at $matchingManifest, but -Update was specified and the module spec allows for higher versions. Checking remote for updates..."
1247+
return $null
1248+
}
1249+
12361250
if (-not [File]::Exists($matchingManifest)) {
12371251
throw "A matching module folder was found for $ModuleSpec but the manifest is not present at $matchingManifest. This is a bug and should never happen as we should have checked this ahead of time."
12381252
}

ModuleFast.tests.ps1

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using namespace System.Management.Automation
22
using namespace System.Collections.Generic
3+
using namespace System.Diagnostics.CodeAnalysis
34

45
BeforeAll {
56
. ./ModuleFast.ps1
@@ -327,9 +328,22 @@ Describe 'NugetRange' {
327328

328329

329330
Describe 'Get-ModuleFastPlan' -Tag 'E2E' {
330-
$DebugPreference = 'contine'
331-
$VerbosePreference = 'continue'
331+
BeforeAll {
332+
$SCRIPT:__existingPSModulePath = $env:PSModulePath
333+
$env:PSModulePath = $testDrive
334+
335+
$SCRIPT:__existingProgressPreference = $ProgressPreference
336+
$ProgressPreference = 'SilentlyContinue'
337+
338+
}
339+
AfterAll {
340+
$env:PSModulePath = $SCRIPT:__existingPSModulePath
341+
$ProgressPreference = $SCRIPT:__existingProgressPreference
342+
}
343+
344+
#This is used for testcases
332345
$SCRIPT:moduleName = 'Az.Accounts'
346+
333347
It 'Gets Module by <Test>' {
334348
$actual = Get-ModuleFastPlan $spec
335349
$actual | Should -HaveCount 1
@@ -357,37 +371,49 @@ Describe 'Get-ModuleFastPlan' -Tag 'E2E' {
357371
}
358372

359373
Describe 'Install-ModuleFast' -Tag 'E2E' {
374+
BeforeAll {
375+
$SCRIPT:__existingPSModulePath = $env:PSModulePath
376+
}
360377
BeforeEach {
361378
#Remove all PSModulePath to not affect existing environment
362-
$SCRIPT:__existingPSModulePath = $env:PSModulePath
363-
$testDrivePath = (Get-Item testdrive:).fullname
364-
$installTempPath = Join-Path $testDrivePath $(New-Guid)
379+
$installTempPath = Join-Path $testdrive $(New-Guid)
365380
New-Item -ItemType Directory -Path $installTempPath -ErrorAction stop
381+
$env:PSModulePath = $installTempPath
382+
383+
[SuppressMessageAttribute(
384+
<#Category#>'PSUseDeclaredVarsMoreThanAssignments',
385+
<#CheckId#>$null,
386+
Justification = 'PSScriptAnalyzer doesnt see the connection between beforeeach and Describe/It'
387+
)]
366388
$imfParams = @{
367389
Destination = $installTempPath
368390
NoProfileUpdate = $true
369391
NoPSModulePathUpdate = $true
370392
Confirm = $false
371393
}
372394
}
395+
AfterAll {
396+
$env:PSModulePath = $SCRIPT:__existingPSModulePath
397+
}
373398
It 'Installs Module' {
374399
#HACK: The testdrive mount is not available in the threadjob runspaces so we need to translate it
375400
Install-ModuleFast @imfParams 'Az.Accounts'
376401
Get-Item $installTempPath\Az.Accounts\*\Az.Accounts.psd1 | Should -Not -BeNullOrEmpty
377402
}
378-
It 'Installs Module with lots of dependencies (Az)' {
379-
Install-ModuleFast @imfParams 'Az'
380-
}
381403
It 'Installs Module with 4 section version numbers (VMware.PowerCLI)' {
382404
Install-ModuleFast @imfParams 'VMware.VimAutomation.Common'
383-
Get-Item TestDrive:\*\*\*.psd1 | ForEach-Object {
405+
Get-Item $installTempPath\VMware*\*\*.psd1 | ForEach-Object {
384406
$moduleFolderVersion = $_ | Split-Path | Split-Path -Leaf
385407
Import-PowerShellDataFile -Path $_.FullName | ForEach-Object ModuleVersion | Should -Be $moduleFolderVersion
386408
}
387-
$env:PSModulePath = $testDrivePath
388409
Get-Module VMWare* -ListAvailable | Should -HaveCount 2
389410
}
390-
AfterAll {
391-
$env:PSModulePath = $SCRIPT:__existingPSModulePath
411+
It 'Installs Module with lots of dependencies (Az)' {
412+
Install-ModuleFast @imfParams 'Az'
413+
(Get-Module Az* -ListAvailable).count | Should -BeGreaterThan 10
414+
}
415+
It 'Installs Module with specific requiredVersion' {
416+
Install-ModuleFast @imfParams @{ ModuleName = 'Az.Accounts'; RequiredVersion = '2.7.3' }
417+
Get-Module Az.Accounts -ListAvailable | Select-Object -ExpandProperty Version | Should -Be '2.7.3'
392418
}
393419
}

0 commit comments

Comments
 (0)