Skip to content

Commit 38847cd

Browse files
author
Steve Lee (POWERSHELL HE/HIM) (from Dev Box)
committed
fix copilot feedback
1 parent 98306ec commit 38847cd

12 files changed

Lines changed: 146 additions & 130 deletions

File tree

.vscode/settings.json

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,5 @@
2323
"."
2424
],
2525
"azure-pipelines.1ESPipelineTemplatesSchemaFile": true,
26-
"powershell.codeFormatting.preset": "OTBS",
27-
"chat.tools.terminal.autoApprove": {
28-
"cargo check": true,
29-
"cargo test": true,
30-
"cargo clippy": true,
31-
"Invoke-Pester": true
32-
}
33-
}
26+
"powershell.codeFormatting.preset": "OTBS"
27+
}

resources/dism_dsc/featureondemand.dsc.resource.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@
6969
"type": "object",
7070
"additionalProperties": false,
7171
"properties": {
72-
"name": {
72+
"identity": {
7373
"type": "string",
74-
"title": "Capability name",
75-
"description": "The name of the Windows capability (Feature on Demand). Required for get operation. For export operation, this is optional and wildcards (*) are supported for case-insensitive filtering."
74+
"title": "Capability identity",
75+
"description": "The identity of the Windows capability (Feature on Demand). Required for get and set operations. For export operation, this is optional and wildcards (*) are supported for case-insensitive filtering."
7676
},
7777
"_exist": {
7878
"type": "boolean",
@@ -92,7 +92,7 @@
9292
"PartiallyInstalled"
9393
],
9494
"title": "Capability state",
95-
"description": "The current state of the capability. For set operations, only Installed and NotPresent are accepted; other states are returned by get and export operations and are not valid inputs for set."
95+
"description": "The current state of the capability. For set operations, this property is required and only Installed and NotPresent are accepted; other states are returned by get and export operations and are not valid inputs for set."
9696
},
9797
"displayName": {
9898
"type": "string",

resources/dism_dsc/locales/en-us.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ failedSerializeOutput = "Failed to serialize output: %{err}"
2121
[fod_get]
2222
failedParseInput = "Failed to parse input: %{err}"
2323
capabilitiesArrayEmpty = "Capabilities array cannot be empty for get operation"
24-
nameRequired = "name is required for get operation"
24+
identityRequired = "identity is required for get operation"
2525
failedSerializeOutput = "Failed to serialize output: %{err}"
2626

2727
[fod_export]
@@ -31,9 +31,9 @@ failedSerializeOutput = "Failed to serialize output: %{err}"
3131
[fod_set]
3232
failedParseInput = "Failed to parse input: %{err}"
3333
capabilitiesArrayEmpty = "Capabilities array cannot be empty for set operation"
34-
nameRequired = "name is required for set operation"
34+
identityRequired = "identity is required for set operation"
3535
stateRequired = "state is required for set operation"
36-
capabilityNotFound = "Capability '%{name}' was not found on this system"
36+
capabilityNotFound = "Capability '%{identity}' was not found on this system"
3737
unsupportedDesiredState = "Unsupported desired state '%{state}'. Supported states for set are: Installed, NotPresent"
3838
failedSerializeOutput = "Failed to serialize output: %{err}"
3939

@@ -54,7 +54,7 @@ getFeatureInfoFailed = "DismGetFeatureInfo failed for '%{name}': HRESULT %{hr}"
5454
enableFeatureFailed = "DismEnableFeature failed for '%{name}': HRESULT %{hr}"
5555
disableFeatureFailed = "DismDisableFeature failed for '%{name}': HRESULT %{hr}"
5656
getFeaturesFailed = "DismGetFeatures failed: HRESULT %{hr}"
57-
capabilitiesNotSupported = "Capability operations are not supported on this system. DismGetCapabilities not found in dismapi.dll."
57+
capabilitiesNotSupported = "Capability operations are not supported on this system. Capability APIs not available in dismapi.dll."
5858
getCapabilitiesFailed = "DismGetCapabilities failed: HRESULT %{hr}"
5959
getCapabilityInfoFailed = "DismGetCapabilityInfo failed for '%{name}': HRESULT %{hr}"
6060
addCapabilityFailed = "DismAddCapability failed for '%{name}': HRESULT %{hr}"

resources/dism_dsc/src/feature_on_demand/export.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ pub fn handle_export(input: &str) -> Result<String, String> {
2727

2828
let mut results = Vec::new();
2929

30-
let (filters_with_name, filters_without_name): (Vec<&FeatureOnDemandInfo>, Vec<&FeatureOnDemandInfo>) =
30+
let (filters_with_identity, filters_without_identity): (Vec<&FeatureOnDemandInfo>, Vec<&FeatureOnDemandInfo>) =
3131
if needs_full_info {
32-
filters.iter().partition(|f| f.name.is_some())
32+
filters.iter().partition(|f| f.identity.is_some())
3333
} else {
3434
(Vec::new(), Vec::new())
3535
};
@@ -38,11 +38,11 @@ pub fn handle_export(input: &str) -> Result<String, String> {
3838
let state = CapabilityState::from_dism(*state_val);
3939

4040
if needs_full_info {
41-
let mut should_get_full = !filters_without_name.is_empty();
41+
let mut should_get_full = !filters_without_identity.is_empty();
4242
if !should_get_full {
43-
for f in &filters_with_name {
44-
if let Some(ref filter_name) = f.name {
45-
if matches_wildcard(name, filter_name) {
43+
for f in &filters_with_identity {
44+
if let Some(ref filter_identity) = f.identity {
45+
if matches_wildcard(name, filter_identity) {
4646
should_get_full = true;
4747
break;
4848
}
@@ -55,7 +55,7 @@ pub fn handle_export(input: &str) -> Result<String, String> {
5555

5656
let info = match session.get_capability_info(name) {
5757
Ok(raw) if !raw.unknown => FeatureOnDemandInfo {
58-
name: Some(raw.name),
58+
identity: Some(raw.name),
5959
exist: None,
6060
state: CapabilityState::from_dism(raw.state),
6161
display_name: Some(raw.display_name),
@@ -64,7 +64,7 @@ pub fn handle_export(input: &str) -> Result<String, String> {
6464
install_size: Some(raw.install_size),
6565
},
6666
_ => FeatureOnDemandInfo {
67-
name: Some(name.clone()),
67+
identity: Some(name.clone()),
6868
exist: None,
6969
state,
7070
display_name: None,
@@ -78,10 +78,10 @@ pub fn handle_export(input: &str) -> Result<String, String> {
7878
results.push(info);
7979
}
8080
} else {
81-
// Fast path: only need name and state for filtering, skip expensive
81+
// Fast path: only need identity and state for filtering, skip expensive
8282
// per-capability DismGetCapabilityInfo calls to match dism /online /get-capabilities speed.
8383
let basic = FeatureOnDemandInfo {
84-
name: Some(name.clone()),
84+
identity: Some(name.clone()),
8585
state: state.clone(),
8686
..FeatureOnDemandInfo::default()
8787
};

resources/dism_dsc/src/feature_on_demand/get.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ pub fn handle_get(input: &str) -> Result<String, String> {
1818
let mut results = Vec::new();
1919

2020
for cap_input in &capability_list.capabilities {
21-
let name = cap_input
22-
.name
21+
let identity = cap_input
22+
.identity
2323
.as_ref()
24-
.ok_or_else(|| t!("fod_get.nameRequired").to_string())?;
24+
.ok_or_else(|| t!("fod_get.identityRequired").to_string())?;
2525

26-
let raw = session.get_capability_info(name)?;
26+
let raw = session.get_capability_info(identity)?;
2727
let info = if raw.unknown {
2828
FeatureOnDemandInfo {
29-
name: Some(name.clone()),
29+
identity: Some(identity.clone()),
3030
exist: Some(false),
3131
..FeatureOnDemandInfo::default()
3232
}
3333
} else {
3434
FeatureOnDemandInfo {
35-
name: Some(raw.name),
35+
identity: Some(raw.name),
3636
state: CapabilityState::from_dism(raw.state),
3737
display_name: Some(raw.display_name),
3838
description: Some(raw.description),

resources/dism_dsc/src/feature_on_demand/set.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,20 @@ pub fn handle_set(input: &str) -> Result<String, String> {
2121
let mut reboot_required = false;
2222

2323
for cap_input in &capability_list.capabilities {
24-
let name = cap_input
25-
.name
24+
let identity = cap_input
25+
.identity
2626
.as_ref()
27-
.ok_or_else(|| t!("fod_set.nameRequired").to_string())?;
27+
.ok_or_else(|| t!("fod_set.identityRequired").to_string())?;
2828

2929
let desired_state = cap_input
3030
.state
3131
.as_ref()
3232
.ok_or_else(|| t!("fod_set.stateRequired").to_string())?;
3333

34-
let current = session.get_capability_info(name)?;
34+
let current = session.get_capability_info(identity)?;
3535

3636
if current.unknown {
37-
return Err(t!("fod_set.capabilityNotFound", name = name).to_string());
37+
return Err(t!("fod_set.capabilityNotFound", identity = identity).to_string());
3838
}
3939

4040
let current_state = CapabilityState::from_dism(current.state);
@@ -43,13 +43,13 @@ pub fn handle_set(input: &str) -> Result<String, String> {
4343
CapabilityState::Installed => {
4444
match current_state {
4545
Some(CapabilityState::Installed) => false,
46-
_ => session.add_capability(name)?,
46+
_ => session.add_capability(identity)?,
4747
}
4848
}
4949
CapabilityState::NotPresent => {
5050
match current_state {
5151
Some(CapabilityState::NotPresent) | Some(CapabilityState::Removed) => false,
52-
_ => session.remove_capability(name)?,
52+
_ => session.remove_capability(identity)?,
5353
}
5454
}
5555
_ => {
@@ -63,9 +63,9 @@ pub fn handle_set(input: &str) -> Result<String, String> {
6363

6464
reboot_required = reboot_required || needs_reboot;
6565

66-
let raw = session.get_capability_info(name)?;
66+
let raw = session.get_capability_info(identity)?;
6767
let info = FeatureOnDemandInfo {
68-
name: Some(raw.name),
68+
identity: Some(raw.name),
6969
state: CapabilityState::from_dism(raw.state),
7070
display_name: Some(raw.display_name),
7171
description: Some(raw.description),

resources/dism_dsc/src/feature_on_demand/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct FeatureOnDemandList {
2020
#[serde(rename_all = "camelCase")]
2121
pub struct FeatureOnDemandInfo {
2222
#[serde(skip_serializing_if = "Option::is_none")]
23-
pub name: Option<String>,
23+
pub identity: Option<String>,
2424
#[serde(rename = "_exist", skip_serializing_if = "Option::is_none")]
2525
pub exist: Option<bool>,
2626
#[serde(skip_serializing_if = "Option::is_none")]
@@ -37,7 +37,7 @@ pub struct FeatureOnDemandInfo {
3737

3838
impl WildcardFilterable for FeatureOnDemandInfo {
3939
fn matches_filter(&self, filter: &Self) -> bool {
40-
matches_optional_wildcard(&self.name, &filter.name)
40+
matches_optional_wildcard(&self.identity, &filter.identity)
4141
&& matches_optional_exact(&self.state, &filter.state)
4242
&& matches_optional_wildcard(&self.display_name, &filter.display_name)
4343
&& matches_optional_wildcard(&self.description, &filter.description)

resources/dism_dsc/src/optional_feature/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
mod types;
5-
pub mod dism;
5+
pub(crate) mod dism;
66
mod get;
77
mod export;
88
mod set;

resources/dism_dsc/src/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub fn matches_wildcard(text: &str, pattern: &str) -> bool {
7979
if part.is_empty() {
8080
continue;
8181
}
82-
match text_lower[pos..end].find(part) {
82+
match text_lower.get(pos..end).and_then(|s| s.find(part)) {
8383
Some(idx) => pos += idx + part.len(),
8484
None => return false,
8585
}

resources/dism_dsc/tests/featureOnDemand_export.tests.ps1

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Describe 'Microsoft.Windows/FeatureOnDemandList - export operation' -Skip:(!$IsW
2626
$knownCapabilityNameTwo = $notPresentMatches[0].Matches[0].Groups[1].Value
2727

2828
# Get the displayName for the known installed capability to use in wildcard displayName tests
29-
$fullInfoJson = '{"capabilities":[{"name":"' + $knownCapabilityNameOne + '","displayName":"*"}]}'
29+
$fullInfoJson = '{"capabilities":[{"identity":"' + $knownCapabilityNameOne + '","displayName":"*"}]}'
3030
$fullInfoOutput = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $fullInfoJson | ConvertFrom-Json
3131
$knownDisplayName = $fullInfoOutput.resources[0].properties.capabilities[0].displayName
3232
if (-not $knownDisplayName) {
@@ -43,36 +43,36 @@ Describe 'Microsoft.Windows/FeatureOnDemandList - export operation' -Skip:(!$IsW
4343
$capabilities = $output.resources[0].properties.capabilities
4444
$capabilities | Should -Not -BeNullOrEmpty
4545
$capabilities.Count | Should -BeGreaterThan 0
46-
$capabilities[0].name | Should -Not -BeNullOrEmpty
46+
$capabilities[0].identity | Should -Not -BeNullOrEmpty
4747
$capabilities[0].state | Should -BeIn @(
4848
'NotPresent', 'UninstallPending', 'Staged', 'Removed',
4949
'Installed', 'InstallPending', 'Superseded', 'PartiallyInstalled'
5050
)
5151
}
5252

53-
It 'exports capabilities filtered by exact name' -Skip:(!$isElevated) {
54-
$inputJson = '{"capabilities":[{"name":"' + $knownCapabilityNameOne + '"}]}'
53+
It 'exports capabilities filtered by exact identity' -Skip:(!$isElevated) {
54+
$inputJson = '{"capabilities":[{"identity":"' + $knownCapabilityNameOne + '"}]}'
5555
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
5656
$LASTEXITCODE | Should -Be 0
5757
$capabilities = $output.resources[0].properties.capabilities
5858
$capabilities | Should -Not -BeNullOrEmpty
5959
$capabilities.Count | Should -Be 1
6060
$cap = $capabilities[0]
61-
$cap.name | Should -BeExactly $knownCapabilityNameOne
61+
$cap.identity | Should -BeExactly $knownCapabilityNameOne
6262
$cap.state | Should -BeIn @(
6363
'NotPresent', 'UninstallPending', 'Staged', 'Removed',
6464
'Installed', 'InstallPending', 'Superseded', 'PartiallyInstalled'
6565
)
6666
}
6767

68-
It 'exports capabilities filtered by wildcard name' -Skip:(!$isElevated) {
69-
$inputJson = '{"capabilities":[{"name":"Language.Basic*"}]}'
68+
It 'exports capabilities filtered by wildcard identity' -Skip:(!$isElevated) {
69+
$inputJson = '{"capabilities":[{"identity":"Language.Basic*"}]}'
7070
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
7171
$LASTEXITCODE | Should -Be 0
7272
$capabilities = $output.resources[0].properties.capabilities
7373
$capabilities | Should -Not -BeNullOrEmpty
7474
foreach ($cap in $capabilities) {
75-
$cap.name | Should -BeLike 'Language.Basic*'
75+
$cap.identity | Should -BeLike 'Language.Basic*'
7676
}
7777
}
7878

@@ -87,8 +87,8 @@ Describe 'Microsoft.Windows/FeatureOnDemandList - export operation' -Skip:(!$IsW
8787
}
8888
}
8989

90-
It 'exports capabilities with combined name and state filter' -Skip:(!$isElevated) {
91-
$inputJson = '{"capabilities":[{"name":"*","state":"Installed"}]}'
90+
It 'exports capabilities with combined identity and state filter' -Skip:(!$isElevated) {
91+
$inputJson = '{"capabilities":[{"identity":"*","state":"Installed"}]}'
9292
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
9393
$LASTEXITCODE | Should -Be 0
9494
$capabilities = $output.resources[0].properties.capabilities
@@ -110,18 +110,18 @@ Describe 'Microsoft.Windows/FeatureOnDemandList - export operation' -Skip:(!$IsW
110110
}
111111

112112
It 'exports capabilities with multiple filters using OR logic' -Skip:(!$isElevated) {
113-
$inputJson = '{"capabilities":[{"name":"' + $knownCapabilityNameOne + '"},{"name":"' + $knownCapabilityNameTwo + '"}]}'
113+
$inputJson = '{"capabilities":[{"identity":"' + $knownCapabilityNameOne + '"},{"identity":"' + $knownCapabilityNameTwo + '"}]}'
114114
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
115115
$LASTEXITCODE | Should -Be 0
116116
$capabilities = $output.resources[0].properties.capabilities
117117
$capabilities | Should -Not -BeNullOrEmpty
118-
$names = $capabilities | ForEach-Object { $_.name }
119-
$names | Should -Contain $knownCapabilityNameOne
120-
$names | Should -Contain $knownCapabilityNameTwo
118+
$identities = $capabilities | ForEach-Object { $_.identity }
119+
$identities | Should -Contain $knownCapabilityNameOne
120+
$identities | Should -Contain $knownCapabilityNameTwo
121121
}
122122

123123
It 'returns empty results for non-matching wildcard filter' -Skip:(!$isElevated) {
124-
$inputJson = '{"capabilities":[{"name":"ZZZNonExistent*"}]}'
124+
$inputJson = '{"capabilities":[{"identity":"ZZZNonExistent*"}]}'
125125
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
126126
$LASTEXITCODE | Should -Be 0
127127
$capabilities = $output.resources[0].properties.capabilities
@@ -137,13 +137,13 @@ Describe 'Microsoft.Windows/FeatureOnDemandList - export operation' -Skip:(!$IsW
137137
}
138138

139139
It 'returns complete capability properties when full-info filter is used' -Skip:(!$isElevated) {
140-
$inputJson = '{"capabilities":[{"name":"' + $knownCapabilityNameOne + '","displayName":"*"}]}'
140+
$inputJson = '{"capabilities":[{"identity":"' + $knownCapabilityNameOne + '","displayName":"*"}]}'
141141
$output = dsc resource export -r Microsoft.Windows/FeatureOnDemandList -i $inputJson | ConvertFrom-Json
142142
$LASTEXITCODE | Should -Be 0
143143
$capabilities = $output.resources[0].properties.capabilities
144144
$capabilities.Count | Should -Be 1
145145
$cap = $capabilities[0]
146-
$cap.name | Should -BeExactly $knownCapabilityNameOne
146+
$cap.identity | Should -BeExactly $knownCapabilityNameOne
147147
$cap.state | Should -BeIn @(
148148
'NotPresent', 'UninstallPending', 'Staged', 'Removed',
149149
'Installed', 'InstallPending', 'Superseded', 'PartiallyInstalled'

0 commit comments

Comments
 (0)