Skip to content

Commit bdd1c12

Browse files
authored
Merge pull request #1467 from SteveL-MSFT/appx-condition
Fix duplicates in listing resources and add condition to manifests
2 parents 44a6b07 + 65a1d80 commit bdd1c12

File tree

13 files changed

+94
-23
lines changed

13 files changed

+94
-23
lines changed

adapters/powershell/PowerShell_adapter.dsc.resource.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"tags": [
88
"PowerShell"
99
],
10+
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
1011
"adapter": {
1112
"list": {
1213
"executable": "pwsh",

adapters/powershell/powershell.dsc.resource.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"tags": [
99
"PowerShell"
1010
],
11+
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
1112
"adapter": {
1213
"list": {
1314
"executable": "pwsh",

data.build.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"runcommandonset",
3030
"sshdconfig",
3131
"sshd_config.dsc.resource.json",
32+
"sshd-subsystem.dsc.resource.json",
33+
"sshd-subsystemList.dsc.resource.json",
3234
"y2j"
3335
],
3436
"macOS": [
@@ -56,6 +58,8 @@
5658
"runcommandonset",
5759
"sshdconfig",
5860
"sshd_config.dsc.resource.json",
61+
"sshd-subsystem.dsc.resource.json",
62+
"sshd-subsystemList.dsc.resource.json",
5963
"y2j"
6064
],
6165
"Windows": [
@@ -92,6 +96,8 @@
9296
"sshdconfig.exe",
9397
"sshd-windows.dsc.resource.json",
9498
"sshd_config.dsc.resource.json",
99+
"sshd-subsystem.dsc.resource.json",
100+
"sshd-subsystemList.dsc.resource.json",
95101
"windowspowershell.dsc.resource.json",
96102
"windowsupdate.dsc.resource.json",
97103
"wu_dsc.exe",

dsc/src/mcp/list_dsc_resources.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rmcp::{ErrorData as McpError, Json, tool, tool_router, handler::server::wrap
1212
use rust_i18n::t;
1313
use schemars::JsonSchema;
1414
use serde::{Deserialize, Serialize};
15-
use std::collections::BTreeMap;
1615
use tokio::task;
1716

1817
#[derive(Serialize, JsonSchema)]
@@ -63,7 +62,7 @@ impl McpServer {
6362
},
6463
None => None,
6564
};
66-
let mut resources = BTreeMap::<FullyQualifiedTypeName, ResourceSummary>::new();
65+
let mut resources = Vec::<ResourceSummary>::new();
6766
for resource in dsc.list_available(&DiscoveryKind::Resource, &TypeNameFilter::default(), adapter_filter, ProgressFormat::None) {
6867
if let Resource(resource) = resource {
6968
let summary = ResourceSummary {
@@ -72,10 +71,10 @@ impl McpServer {
7271
description: resource.description.clone(),
7372
require_adapter: resource.require_adapter,
7473
};
75-
resources.insert(resource.type_name.clone(), summary);
74+
resources.push(summary);
7675
}
7776
}
78-
Ok(ResourceListResult { resources: resources.into_values().collect() })
77+
Ok(ResourceListResult { resources })
7978
}).await.map_err(|e| McpError::internal_error(e.to_string(), None))??;
8079

8180
Ok(Json(result))

dsc/tests/dsc_mcp.tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ Describe 'Tests for MCP server' {
104104

105105
$response = Send-McpRequest -request $mcpRequest
106106
$response.id | Should -BeGreaterOrEqual 3
107-
$resources = dsc resource list | ConvertFrom-Json -Depth 20 | Select-Object type, kind, description -Unique
108-
$response.result.structuredContent.resources.Count | Should -Be $resources.Count
107+
$resources = dsc resource list | ConvertFrom-Json -Depth 20 | Select-Object type, kind, description
108+
$response.result.structuredContent.resources.Count | Should -Be $resources.Count -Because "MCP:`n$($response.result.structuredContent.resources | Format-Table | Out-String)`nDSC:`n$($resources | Format-Table | Out-String)"
109109
for ($i = 0; $i -lt $resources.Count; $i++) {
110110
($response.result.structuredContent.resources[$i].psobject.properties | Measure-Object).Count | Should -BeGreaterOrEqual 3
111111
$response.result.structuredContent.resources[$i].type | Should -BeExactly $resources[$i].type -Because ($response.result.structuredContent | ConvertTo-Json -Depth 20 | Out-String)

dsc/tests/dsc_resource_list.tests.ps1

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,28 @@ Describe 'Tests for listing resources' {
3838
) {
3939
param($tags, $description, $expectedCount, $expectedType)
4040

41-
if ($tags -and $description) {
42-
$resources = dsc resource list --tags $tags --description $description | ConvertFrom-Json
43-
}
44-
elseif ($tags) {
45-
$resources = dsc resource list --tags $tags | ConvertFrom-Json
46-
}
47-
else {
48-
$resources = dsc resource list --description $description | ConvertFrom-Json
49-
}
41+
$oldPath = $env:DSC_RESOURCE_PATH
42+
try {
43+
# Need to restrict the search as more resources are being added like from PS7
44+
$env:DSC_RESOURCE_PATH = Split-Path (Get-Command dsc).Source -Parent
5045

51-
$LASTEXITCODE | Should -Be 0
52-
$resources.Count | Should -Be $expectedCount
53-
if ($expectedCount -gt 0) {
54-
$resources.type | Should -BeExactly $expectedType
46+
if ($tags -and $description) {
47+
$resources = dsc resource list --tags $tags --description $description | ConvertFrom-Json
48+
}
49+
elseif ($tags) {
50+
$resources = dsc resource list --tags $tags | ConvertFrom-Json
51+
}
52+
else {
53+
$resources = dsc resource list --description $description | ConvertFrom-Json
54+
}
55+
56+
$LASTEXITCODE | Should -Be 0
57+
$resources.Count | Should -Be $expectedCount
58+
if ($expectedCount -gt 0) {
59+
$resources.type | Should -BeExactly $expectedType
60+
}
61+
} finally {
62+
$env:DSC_RESOURCE_PATH = $oldPath
5563
}
5664
}
5765

@@ -111,4 +119,46 @@ Describe 'Tests for listing resources' {
111119
}
112120
$foundWideLine | Should -BeTrue
113121
}
122+
123+
It 'No duplicates based on type name and version are returned' {
124+
$resource_manifest = @'
125+
{
126+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
127+
"type": "Microsoft.DSC.Debug/EchoDupe",
128+
"version": "1.2.3",
129+
"description": "A duplicate resource for testing",
130+
"get": {
131+
"executable": "dscecho",
132+
"args": [
133+
{
134+
"jsonInputArg": "--input",
135+
"mandatory": true
136+
}
137+
]
138+
},
139+
"schema": {
140+
"command": {
141+
"executable": "dscecho"
142+
}
143+
}
144+
}
145+
'@
146+
$manifestPath = Join-Path $TestDrive "echoDupeManifest.dsc.resource.json"
147+
$manifestDupePath = Join-Path $TestDrive "echoDupeManifestDuplicate.dsc.resource.json"
148+
Set-Content -Path $manifestPath -Value $resource_manifest
149+
Set-Content -Path $manifestDupePath -Value $resource_manifest
150+
151+
$oldPath = $env:DSC_RESOURCE_PATH
152+
try {
153+
$env:DSC_RESOURCE_PATH = $TestDrive + [System.IO.Path]::PathSeparator + $env:PATH
154+
$resources = dsc resource list | ConvertFrom-Json
155+
$LASTEXITCODE | Should -Be 0
156+
$resourceGroups = $resources | Group-Object -Property type, version
157+
foreach ($group in $resourceGroups) {
158+
$group.Count | Should -Be 1 -Because ($resources | ConvertTo-Json -Depth 20)
159+
}
160+
} finally {
161+
$env:DSC_RESOURCE_PATH = $oldPath
162+
}
163+
}
114164
}

extensions/powershell/powershell.dsc.extension.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"type": "Microsoft.PowerShell/Discover",
44
"version": "0.1.0",
55
"description": "Discovers DSC resources packaged in PowerShell 7 modules.",
6+
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
67
"discover": {
78
"executable": "pwsh",
89
"args": [

lib/dsc-lib/src/discovery/mod.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl Discovery {
6868
Box::new(command_discovery::CommandDiscovery::new(progress_format)),
6969
];
7070

71-
let mut resources: Vec<ImportedManifest> = Vec::new();
71+
let mut resources: BTreeMap<String, ImportedManifest> = BTreeMap::new();
7272

7373
for mut discovery_type in discovery_types {
7474

@@ -81,8 +81,16 @@ impl Discovery {
8181
};
8282

8383
for (_resource_name, found_resources) in discovered_resources {
84-
for resource in found_resources {
85-
resources.push(resource.clone());
84+
for manifest in found_resources {
85+
let key = match &manifest {
86+
ImportedManifest::Resource(resource) => {
87+
format!("{}@{}", resource.type_name.to_lowercase(), resource.version)
88+
},
89+
ImportedManifest::Extension(extension) => {
90+
format!("{}@{}", extension.type_name.to_lowercase(), extension.version)
91+
}
92+
};
93+
resources.insert(key, manifest);
8694
}
8795
};
8896

@@ -91,7 +99,7 @@ impl Discovery {
9199
}
92100
}
93101

94-
resources
102+
resources.into_values().collect::<Vec<ImportedManifest>>()
95103
}
96104

97105
pub fn get_extensions(&mut self, capability: &Capability) -> Vec<DscExtension> {

resources/PSScript/psscript.dsc.resource.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"type": "Microsoft.DSC.Transitional/PowerShellScript",
44
"description": "Enable running PowerShell 7 scripts inline",
55
"version": "0.1.0",
6+
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
67
"get": {
78
"executable": "pwsh",
89
"args": [

resources/sshdconfig/sshd-subsystem.dsc.resource.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"type": "Microsoft.OpenSSH.SSHD/Subsystem",
44
"description": "Manage SSH Server Subsystem keyword (single entry)",
55
"version": "0.1.0",
6+
"condition": "[not(equals(tryWhich('sshd'), null()))]",
67
"get": {
78
"executable": "sshdconfig",
89
"args": [

0 commit comments

Comments
 (0)