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
196 changes: 160 additions & 36 deletions src/dsc/psresourceget.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Copyright (c) Microsoft Corporation. All rights reserved.
## Licensed under the MIT License.

using namespace System.Collections.Specialized

[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
Expand Down Expand Up @@ -97,15 +99,61 @@ class PSResource {
return $retValue
}

[OrderedDictionary] ToData([bool]$forTest) {
$data = [OrderedDictionary]::new()

$data.name = $this.name
if (-not [string]::IsNullOrEmpty($this.version)) {
$data.version = $this.version
}
$data.scope = $this.scope
if (-not [string]::IsNullOrEmpty($this.repositoryName)) {
$data.repositoryName = $this.repositoryName
}
$data.preRelease = $this.preRelease
$data._exist = $this._exist

if ($forTest) {
$data._inDesiredState = $this._inDesiredState
}

return $data
}

[OrderedDictionary] ToData() {
return $this.ToData($false)
}

[string] ToJson() {
$retVal = ($this | Select-Object -ExcludeProperty _inDesiredState | ConvertTo-Json -Compress -EnumsAsStrings)
Write-Trace -message "Serializing PSResource to JSON. Name: $($this.name), Version: $($this.version), Scope: $($this.scope), RepositoryName: $($this.repositoryName), PreRelease: $($this.preRelease), _exist: $($this._exist)" -level debug
Write-Trace -message "Serialized JSON: $retVal" -level trace
$retVal = $this.ToData() | ConvertTo-Json -Compress -EnumsAsStrings
$this.WriteSerializationTrace($retVal)
return $retVal
}

[string] ToJsonForTest() {
return ($this | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings)
$retVal = $this.ToData($true) | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings
$this.WriteSerializationTrace($retVal, $true)
return $retVal
}

[void] WriteSerializationTrace([string]$json, [bool]$forTest) {
$pairs = @(
"Name: $($this.name)"
"Version: $($this.version)"
"Scope: $($this.scope)"
"RepositoryName: $($this.repositoryName)"
"PreRelease: $($this.preRelease)"
"_exist: $($this._exist)"
)
if ($forTest) {
$pairs += "_inDesiredState: $($this._inDesiredState)"
}
Write-Trace -message "Serializing PSResource to JSON. $($pairs -join ', ')" -level debug
Write-Trace -message "Serialized JSON: $json" -level trace
}

[void] WriteSerializationTrace([string]$json) {
$this.WriteSerializationTrace($json, $false)
}
}

Expand Down Expand Up @@ -154,24 +202,53 @@ class PSResourceList {
return $true
}

[string] ToJson() {
$resourceJson = if ($this.resources) { ($this.resources | ForEach-Object { $_.ToJson() }) -join ',' } else { '' }
$resourceJson = "[$resourceJson]"
$jsonString = "{'repositoryName': '$($this.repositoryName)','resources': $resourceJson}"
$jsonString = $jsonString -replace "'", '"'
$retVal = $jsonString | ConvertFrom-Json | ConvertTo-Json -Compress -EnumsAsStrings
[OrderedDictionary] ToData([bool]$forTest) {
$data = [OrderedDictionary]::new()
if (-not [string]::IsNullOrEmpty($this.repositoryName)) {
$data['repositoryName'] = $this.repositoryName
}
Comment on lines +207 to +209
if ($this.resources) {
[OrderedDictionary[]] $resourceData = $this.resources | ForEach-Object { $_.ToData($forTest) }
$data['resources'] = $resourceData
}
if ($this.trustedRepository) {
$data['trustedRepository'] = $this.trustedRepository
}
if ($forTest) {
$data['_inDesiredState'] = $this._inDesiredState
}
return $data
}
[OrderedDictionary] ToData() {
return $this.ToData($false)
}

Write-Trace -message "Serializing PSResourceList to JSON. RepositoryName: $($this.repositoryName), TrustedRepository: $($this.trustedRepository), Resources count: $($this.resources.Count)" -level debug
Write-Trace -message "Serialized JSON: $retVal" -level trace
[string] ToJson() {
$retVal = $this.ToData() | ConvertTo-Json -Compress -EnumsAsStrings
$this.WriteSerializationTrace($retVal)

return $retVal
}

[string] ToJsonForTest() {
Write-Trace -message "Serializing PSResourceList to JSON for test output. RepositoryName: $($this.repositoryName), TrustedRepository: $($this.trustedRepository), Resources count: $($this.resources.Count)" -level debug
$jsonForTest = $this | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings
Write-Trace -message "Serialized JSON: $jsonForTest" -level trace
return $jsonForTest
$retVal = $this.ToData($true) | ConvertTo-Json -Compress -EnumsAsStrings
$this.WriteSerializationTrace($retVal, $true)
return $retVal
}

[void] WriteSerializationTrace([string]$json, [bool]$forTest) {
$preamble = 'Serializing PSResourceList to JSON'
$preamble += $forTest ? ' for test output.' : '.'
$pairs = @(
"repositoryName: $($this.repositoryName)"
"trustedRepository: $($this.trustedRepository)"
"resourcesCount: $($this.resources.Count)"
)
Write-Trace -message "$preamble $($pairs -join ', ')" -level debug
Write-Trace -message "Serialized JSON: $json" -level trace
}
[void] WriteSerializationTrace([string]$json) {
$this.WriteSerializationTrace($json, $false)
}
}

Expand Down Expand Up @@ -213,8 +290,28 @@ class Repository {
$this.repositoryType = 'Unknown'
}

[OrderedDictionary] ToData([bool]$forTest) {
$data = [OrderedDictionary]::new()
$data['name'] = $this.name
if (-not [string]::IsNullOrEmpty($this.uri)) {
$data['uri'] = $this.uri
}
$data['trusted'] = $this.trusted
$data['priority'] = $this.priority
if (-not [string]::IsNullOrEmpty($this.repositoryType)) {
$data['repositoryType'] = $this.repositoryType
}
$data['_exist'] = $this._exist

return $data
}
[OrderedDictionary] ToData() {
return $this.ToData($false)
}

[string] ToJson() {
return ($this | ConvertTo-Json -Compress -EnumsAsStrings)
$retVal = $this.ToData() | ConvertTo-Json -Compress -EnumsAsStrings
return $retVal
}
}

Expand Down Expand Up @@ -527,9 +624,12 @@ function ExportOperation {
exit [ExitCode]::ExportNotImplemented
}
'psresourcelist' {
$currentUserPSResources = Get-PSResource
$allUsersPSResources = Get-PSResource -Scope AllUsers
PopulatePSResourceListObject -allUsersPSResources $allUsersPSResources -currentUserPSResources $currentUserPSResources
$populatingParams = @{
currentUserPSResources = GetAllPsResourcesInScope -Scope CurrentUser
allUsersPSResources = GetAllPsResourcesInScope -Scope AllUsers
}

PopulatePSResourceListObject @populatingParams
}
default {
Write-Trace -level error -message "Unknown ResourceType: $ResourceType"
Expand Down Expand Up @@ -747,6 +847,22 @@ function DeleteOperation {
}
}

function GetAllPsResourcesInScope {
param(
[Scope]$Scope
)

try {
Get-PSResource -Scope $Scope -ErrorAction Stop
} catch [Microsoft.PowerShell.PSResourceGet.UtilClasses.ResourceNotFoundException] {
# Everything is fine, there's just no installed resources
@()
} catch {
Write-Trace -level error -message "Failed to get PSResources for '$Scope' scope: $_"
@()
}
Comment on lines +860 to +863
}

function PopulatePSResourceListObjectByRepository {
param (
$resourcesExist,
Expand Down Expand Up @@ -794,24 +910,32 @@ function PopulatePSResourceListObject {

$allPSResources = @()

$allPSResources += $allUsersPSResources | ForEach-Object {
return [PSResource]::new(
$_.Name,
$_.Version,
[Scope]"AllUsers",
$_.Repository,
$_.PreRelease ? $true : $false
)
if ($allUsersPSResources.count -gt 1) {
$allPSResources += $allUsersPSResources | ForEach-Object {
return [PSResource]::new(
$_.Name,
$_.Version,
[Scope]"AllUsers",
$_.Repository,
$_.PreRelease ? $true : $false
)
}
} else {
Write-Trace -level info "No PSResources found for AllUsers scope."
}

$allPSResources += $currentUserPSResources | ForEach-Object {
return [PSResource]::new(
$_.Name,
$_.Version,
[Scope]"CurrentUser",
$_.Repository,
$_.PreRelease ? $true : $false
)
if ($currentUserPSResources.count -gt 1) {
$allPSResources += $currentUserPSResources | ForEach-Object {
return [PSResource]::new(
$_.Name,
$_.Version,
[Scope]"CurrentUser",
$_.Repository,
$_.PreRelease ? $true : $false
)
}
} else {
Write-Trace -level info "No PSResources found for CurrentUser scope."
}

$repoGrps = $allPSResources | Group-Object -Property repositoryName
Expand Down
10 changes: 5 additions & 5 deletions src/dsc/psresourcelist.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"repositoryName": {
"title": "Repository Name",
"description": "The name of the repository from where the resources are acquired.",
"type": ["string", "null"]
"type": "string"
},
"trustedRepository": {
"title": "Trusted Repository",
Expand All @@ -115,7 +115,7 @@
},
"$defs": {
"Scope": {
"type": ["string", "null"],
"type": "string",
"title": "Scope",
"description": "Scope of the resource installation.",
"enum": [
Expand All @@ -133,12 +133,12 @@
"name": {
"title": "Name",
"description": "The name of the resource.",
"type": ["string", "null"]
"type": "string"
},
"version": {
"title": "Version",
"description": "The version range of the resource.",
"type": ["string", "null"]
"type": "string"
},
"scope": {
"title": "Scope",
Expand All @@ -148,7 +148,7 @@
"repositoryName": {
"title": "Repository Name",
"description": "The name of the repository from where the resource is acquired.",
"type": ["string", "null"]
"type": "string"
},
"preRelease": {
"title": "Pre-Release version",
Expand Down
11 changes: 3 additions & 8 deletions src/dsc/repository.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,18 @@
"description": "A PowerShell Resource repository from where to acquire the resources.",
"type": "object",
"additionalProperties": false,
"required": ["name"],
"allOf": [
{
"if": {
"properties": {
"_exist": {
"const": false
"const": true
}
}
},
"then": {
"required": [
"name"
]
},
"else": {
"required": [
"name",
"uri"
]
}
Expand All @@ -105,7 +100,7 @@
"uri": {
"title": "URI",
"description": "The URI of the repository.",
"type": ["string", "null"],
"type": "string",
"format": "uri"
},
"trusted": {
Expand Down
Loading