Skip to content

Commit bd5a4b9

Browse files
After removing _exist for psresourcelist
1 parent 7efc412 commit bd5a4b9

8 files changed

+127
-94
lines changed

src/dsc/psresourceget.ps1

Lines changed: 45 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ class PSResource {
4444
[bool] IsInDesiredState([PSResource] $other) {
4545
$retValue = $true
4646

47+
$psResourceSplat = @{
48+
Name = $this.name
49+
Version = if ($this.version) { $this.version } else { '*' }
50+
}
51+
52+
Get-PSResource @psResourceSplat | Where-Object {
53+
($null -eq $this.scope -or $_.Scope -eq $this.scope) -and
54+
($null -eq $this.repositoryName -or $_.Repository -eq $this.repositoryName)
55+
} | Select-Object -First 1 | ForEach-Object {
56+
Write-Trace -message "Matching resource found: Name=$($_.Name), Version=$($_.Version), Scope=$($_.Scope), Repository=$($_.Repository), PreRelease=$($_.PreRelease)" -level trace
57+
$this._exist = $true
58+
}
59+
4760
if ($this.name -ne $other.name) {
4861
Write-Trace -message "Name mismatch: $($this.name) vs $($other.name)" -level trace
4962
$retValue = $false
@@ -60,28 +73,11 @@ class PSResource {
6073
Write-Trace -message "Repository mismatch: $($this.repositoryName) vs $($other.repositoryName)" -level trace
6174
$retValue = $false
6275
}
63-
elseif ($null -ne $this.preRelease -and $this.preRelease -ne $other.preRelease) {
64-
Write-Trace -message "PreRelease mismatch: $($this.preRelease) vs $($other.preRelease)" -level trace
65-
$retValue = $false
66-
}
6776
elseif ($this._exist -ne $other._exist) {
6877
Write-Trace -message "_exist mismatch: $($this._exist) vs $($other._exist)" -level trace
6978
$retValue = $false
7079
}
7180

72-
$psResourceSplat = @{
73-
Name = $this.name
74-
Version = $this.version
75-
}
76-
77-
Get-PSResource @psResourceSplat | Where-Object {
78-
($null -eq $this.scope -or $_.Scope -eq $this.scope) -and
79-
($null -eq $this.repositoryName -or $_.Repository -eq $this.repositoryName)
80-
} | Select-Object -First 1 | ForEach-Object {
81-
Write-Trace -message "Matching resource found: Name=$($_.Name), Version=$($_.Version), Scope=$($_.Scope), Repository=$($_.Repository), PreRelease=$($_.PreRelease)" -level trace
82-
$this._exist = $true
83-
}
84-
8581
return $retValue
8682
}
8783

@@ -98,7 +94,6 @@ class PSResourceList {
9894
[string]$repositoryName
9995
[PSResource[]]$resources
10096
[bool]$trustedRepository
101-
[bool]$_exist
10297
[bool]$_inDesiredState
10398

10499
PSResourceList([string]$repositoryName, [PSResource[]]$resources, [bool]$trustedRepository) {
@@ -149,7 +144,10 @@ class PSResourceList {
149144
}
150145

151146
[string] ToJsonForTest() {
152-
return ($this | ConvertTo-Json -Compress -Depth 5)
147+
Write-Trace -message "Serializing PSResourceList to JSON for test output. RepositoryName: $($this.repositoryName), TrustedRepository: $($this.trustedRepository), Resources count: $($this.resources.Count)" -level trace
148+
$jsonForTest = $this | ConvertTo-Json -Compress -Depth 5
149+
Write-Trace -message "Serialized JSON: $jsonForTest" -level trace
150+
return $jsonForTest
153151
}
154152
}
155153

@@ -239,13 +237,19 @@ function ConvertInputToPSResource(
239237
) {
240238
$scope = if ($inputObj.Scope) { [Scope]$inputObj.Scope } else { [Scope]"CurrentUser" }
241239

242-
return [PSResource]::new(
240+
$psResource = [PSResource]::new(
243241
$inputObj.Name,
244242
$inputObj.Version,
245243
$scope,
246244
$inputObj.repositoryName ? $inputObj.repositoryName : $repositoryName,
247245
$inputObj.PreRelease
248246
)
247+
248+
if ($null -ne $inputObj._exist) {
249+
$psResource._exist = $inputObj._exist
250+
}
251+
252+
return $psResource
249253
}
250254

251255
# catch any un-caught exception and write it to the error stream
@@ -506,75 +510,35 @@ function SetPSResourceList {
506510
$currentState = GetPSResourceList -inputObj $inputObj
507511

508512
$inputObj.resources | ForEach-Object {
509-
$resource = ConvertInputToPSResource -inputObj $_ -repositoryName $repositoryName
510-
$name = $resource.name
511-
$version = $resource.version
512-
$scope = $resource.scope ?? "CurrentUser"
513+
$resourceDesiredState = ConvertInputToPSResource -inputObj $_ -repositoryName $repositoryName
514+
$name = $resourceDesiredState.name
515+
$version = $resourceDesiredState.version
516+
$scope = if ($resourceDesiredState.scope) { $resourceDesiredState.scope } else { "CurrentUser" }
513517

514518
# Resource should not exist - uninstall if it does
515519
$currentState.resources | Where-PSResource -name $name -version $version -scope $scope -repositoryName $repositoryName | ForEach-Object {
516-
Write-Trace -message "Resource marked for uninstall: $($_.Name) version $($_.Version)" -level info
517520

518-
if (-not $resource._exist -or -not $inputObj._exist) {
519-
Write-Trace -message "Resource $($resource.name) has _exist set to false and exists in current state. Adding to uninstall list." -level info
521+
$isInDesiredState = $_.IsInDesiredState($resourceDesiredState)
522+
523+
# Uninstall if resource should not exist but does
524+
if (-not $resourceDesiredState._exist -and $_._exist) {
525+
Write-Trace -message "Resource $($resourceDesiredState.name) exists but _exist is false. Adding to uninstall list." -level info
520526
$resourcesToUninstall += $_
521527
}
522-
523-
if ($resource._exist -and $inputObj._exist) {
524-
Write-Trace -message "Resource $name has _exist set to true and exists in current state. Checking if it is in desired state." -level info
525-
if ($resource.IsInDesiredState($_)) {
526-
Write-Trace -message "Resource $name is in desired state. No action needed." -level info
527-
}
528-
else {
529-
Write-Trace -message "Resource $name is NOT in desired state. Adding to install list." -level info
530-
$key = $name.ToLowerInvariant() + '-' + ($version ?? 'latest').ToLowerInvariant()
531-
$resourcesToInstall[$key] = $resource
528+
# Install if resource should exist but doesn't, or exists but not in desired state
529+
elseif ($resourceDesiredState._exist -and (-not $_._exist -or -not $isInDesiredState)) {
530+
Write-Trace -message "Resource $($resourceDesiredState.name) needs to be installed." -level info
531+
$versionStr = if ($version) { $resourceDesiredState.version } else { 'latest' }
532+
$key = $name.ToLowerInvariant() + '-' + $versionStr.ToLowerInvariant()
533+
if (-not $resourcesToInstall.ContainsKey($key)) {
534+
$resourcesToInstall[$key] = $resourceDesiredState
532535
}
533536
}
537+
# Otherwise resource is in desired state, no action needed
538+
else {
539+
Write-Trace -message "Resource $($resourceDesiredState.name) is in desired state." -level info
540+
}
534541
}
535-
536-
# if (-not $existingResources) {
537-
# # No existing resources found, add to install list if _exist is true or not specified
538-
# if ($resource._exist -ne $false) {
539-
# $key = $name.ToLowerInvariant() + '-' + ($version ?? 'latest').ToLowerInvariant()
540-
# if (-not $resourcesToInstall.ContainsKey($key)) {
541-
# $resourcesToInstall[$key] = $resource
542-
# }
543-
# }
544-
# # If _exist is false and resource doesn't exist, nothing to do (already in desired state)
545-
# }
546-
# else {
547-
# # Existing resources found
548-
# if ($resource._exist -eq $false) {
549-
# # User wants resource removed - uninstall all existing versions
550-
# $resourcesToUninstall += $existingResources
551-
# }
552-
# elseif ($version) {
553-
# # Version specified - check if any existing version satisfies the range
554-
# $satisfyingResource = $null
555-
# foreach ($existing in $existingResources) {
556-
# $versionRange = [NuGet.Versioning.VersionRange]::Parse($version)
557-
# $resourceVersion = [NuGet.Versioning.NuGetVersion]::Parse($existing.Version.ToString())
558-
# if ($versionRange.Satisfies($resourceVersion)) {
559-
# $satisfyingResource = $existing
560-
# break
561-
# }
562-
# }
563-
564-
# if (-not $satisfyingResource) {
565-
# # No existing version satisfies the range - install desired version
566-
# $key = $name.ToLowerInvariant() + '-' + $version.ToLowerInvariant()
567-
# if (-not $resourcesToInstall.ContainsKey($key)) {
568-
# $resourcesToInstall[$key] = $resource
569-
# }
570-
# # Uninstall versions that don't satisfy the range
571-
# $resourcesToUninstall += $existingResources
572-
# }
573-
# # If a satisfying version exists, resource is in desired state
574-
# }
575-
# # If no version specified and _exist is true/not specified, any existing version is acceptable
576-
# }
577-
578542
}
579543

580544
if ($resourcesToUninstall.Count -gt 0) {
@@ -765,7 +729,7 @@ function PopulatePSResourceListObject {
765729
$repoGrps = $allPSResources | Group-Object -Property repositoryName
766730

767731
$repoGrps | ForEach-Object {
768-
$repositoryTrust = Get-PSResourceRepository -Name $_.Name -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Trusted ?? $false
732+
$repositoryTrust = if ($_.Name) { (Get-PSResourceRepository -Name $_.Name -ErrorAction SilentlyContinue).Trusted } else { $false }
769733
$repoName = $_.Name
770734
$resources = $_.Group
771735
[PSResourceList]::new($repoName, $resources, $repositoryTrust).ToJson()

src/dsc/psresourcelist.dsc.resource.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@
9494
},
9595
"minItems": 0
9696
},
97-
"_exist": {
98-
"$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json"
99-
},
10097
"_inDesiredState": {
10198
"$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/inDesiredState.json"
10299
}
@@ -126,8 +123,7 @@
126123
"version": {
127124
"title": "Version",
128125
"description": "The version range of the resource.",
129-
"type": "string",
130-
"pattern": "^\\d+(\\.\\d+){1,3}(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
126+
"type": "string"
131127
},
132128
"scope": {
133129
"title": "Scope",

test/DscResource/PSResourceGetDSCResource.Tests.ps1

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -319,24 +319,72 @@ Describe 'E2E tests for PSResourceList resource' -Tags 'CI' {
319319
}
320320

321321
It 'Can Install testmodule99' {
322-
Uninstall-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue
322+
$mod = Get-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Version '0.0.93'
323+
if ($mod) {
324+
$mod | Uninstall-PSResource -ErrorAction SilentlyContinue
325+
}
323326

324-
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourgetlist.install.dsc.yaml'
327+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourcegetlist.install.dsc.yaml'
325328
& $script:dscExe config set -f $configPath
326329

327-
$psresource = Get-PSResource -Name 'testmodule99'
330+
$psresource = Get-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Version '0.0.93'
328331
$psresource.Name | Should -Be 'testmodule99'
329332
$psresource.Version | Should -Be '0.0.93'
330333
}
331334

332335
It 'Can Uninstall testmodule99' {
333-
Install-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Repository PSGallery -Reinstall -TrustRepository
336+
Install-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Repository PSGallery -Reinstall -TrustRepository -Version '0.0.93'
334337

335-
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourgetlist.uninstall.dsc.yaml'
338+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourcegetlist.uninstall.dsc.yaml'
336339
& $script:dscExe config set -f $configPath
337340

338-
$psresource = Get-PSResource -Name 'testmodule99'
341+
$psresource = Get-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Version '0.0.93'
339342
$psresource | Should -BeNullOrEmpty
340343
}
341344

345+
It 'Can export PSResourceList with testmodule99' {
346+
Install-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue -Repository PSGallery -Reinstall -TrustRepository -Version '0.0.93'
347+
348+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourcegetlist.export.dsc.yaml'
349+
$out = & $script:dscExe config export -f $configPath -o json | ConvertFrom-Json
350+
351+
$psResourceList = $out.resources.properties | Where-Object { $_.repositoryName -eq 'PSGallery' }
352+
$psResourceList | Should -Not -BeNullOrEmpty
353+
$psResourceList.repositoryName | Should -BeExactly 'PSGallery'
354+
$psResourceList.resources.Count | Should -BeGreaterThan 0
355+
$psResourceList.resources.name | Should -Contain 'testmodule99'
356+
}
357+
358+
It 'Can Install module with dependency via PSResourceList' {
359+
$modulelist = @('TestModuleWithDependencyA', 'TestModuleWithDependencyB', 'TestModuleWithDependencyC', 'TestModuleWithDependencyD', 'TestModuleWithDependencyE')
360+
$mods = Get-PSResource -Name $modulelist -ErrorAction SilentlyContinue
361+
if ($mods) {
362+
$mods | Uninstall-PSResource -ErrorAction SilentlyContinue
363+
}
364+
365+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourcegetlist.moddeps.install.dsc.yaml'
366+
& $script:dscExe config set -f $configPath
367+
368+
$psresource = Get-PSResource -Name $modulelist -ErrorAction SilentlyContinue
369+
$psresource | Should -HaveCount 5
370+
}
371+
372+
It 'Can install modules with prerelease versions via PSResourceList' {
373+
$mod = Get-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue
374+
if ($mod) {
375+
$mod | Uninstall-PSResource -ErrorAction SilentlyContinue
376+
}
377+
378+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath 'configs/psresourcegetlist.prerelease.install.dsc.yaml'
379+
& $script:dscExe config set -f $configPath
380+
381+
$psresource = Get-PSResource -Name 'testmodule99' -ErrorAction SilentlyContinue
382+
$psresource | Should -HaveCount 2
383+
384+
$psresource | ForEach-Object {
385+
$version = if ($_.prerelease) { "$($_.Version)" + '.' + "$($_.PreRelease)" } else { $_.Version.ToString() }
386+
387+
$version | Should -BeIn @("101.0.99.beta1", "0.0.93")
388+
}
389+
}
342390
}

test/DscResource/configs/psresourgetlist.install.dsc.yaml renamed to test/DscResource/configs/psresourcegetlist.export.dsc.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,3 @@ resources:
77
trustedRepository: true
88
resources:
99
- name: testmodule99
10-
version: 0.0.93
11-
_exist: true

test/DscResource/configs/psresourgetlist.export.dsc.yaml renamed to test/DscResource/configs/psresourcegetlist.install.dsc.yaml

File renamed without changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
2+
resources:
3+
- name: Install Module with dependencies
4+
type: Microsoft.PowerShell.PSResourceGet/PSResourceList
5+
properties:
6+
repositoryName: PSGallery
7+
trustedRepository: true
8+
resources:
9+
- name: TestModuleWithDependencyA
10+
version: '5.0'
11+
_exist: true
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
2+
resources:
3+
- name: Install testmodule99 stable and prerelease
4+
type: Microsoft.PowerShell.PSResourceGet/PSResourceList
5+
properties:
6+
repositoryName: PSGallery
7+
trustedRepository: true
8+
resources:
9+
- name: testmodule99
10+
version: '[[0.0.93,)'
11+
_exist: true
12+
preRelease: true
13+
- name: testmodule99
14+
version: '[[100.0.99,)'
15+
_exist: true
16+
preRelease: true

test/DscResource/configs/psresourgetlist.uninstall.dsc.yaml renamed to test/DscResource/configs/psresourcegetlist.uninstall.dsc.yaml

File renamed without changes.

0 commit comments

Comments
 (0)