diff --git a/Cargo.lock b/Cargo.lock index d9a4a1814..eb571d7dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -719,7 +719,7 @@ dependencies = [ [[package]] name = "dsc" -version = "3.2.0" +version = "3.2.1" dependencies = [ "clap", "clap_complete", diff --git a/adapters/powershell/PowerShell_adapter.dsc.resource.json b/adapters/powershell/PowerShell_adapter.dsc.resource.json index 954191224..dd36c2c8c 100644 --- a/adapters/powershell/PowerShell_adapter.dsc.resource.json +++ b/adapters/powershell/PowerShell_adapter.dsc.resource.json @@ -41,7 +41,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin" @@ -61,7 +62,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", @@ -83,7 +85,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", @@ -104,7 +107,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", diff --git a/adapters/powershell/Tests/PSAdapted.tests.ps1 b/adapters/powershell/Tests/PSAdapted.tests.ps1 index dd7eb953a..95abef00c 100644 --- a/adapters/powershell/Tests/PSAdapted.tests.ps1 +++ b/adapters/powershell/Tests/PSAdapted.tests.ps1 @@ -19,4 +19,19 @@ Describe 'Tests for PS adapted manifests' { $out.actualState.Name | Should -BeExactly 'hello' -Because ($out | ConvertTo-Json) $out.actualState.Value | Should -Be 42 } + + It 'Get operation works if adapted resource is in a path with spaces' { + $resourcePath = Join-Path -Path $TestDrive -ChildPath 'Path with spaces' + New-Item -Path $resourcePath -ItemType Directory | Out-Null + Copy-Item -Path (Join-Path -Path $PSScriptRoot -ChildPath 'PSAdaptedTestClassResource*') -Destination $resourcePath + $oldPath = $env:PATH + try { + $env:PATH = $resourcePath + [System.IO.Path]::PathSeparator + $env:PATH + $out = dsc resource get -r 'PSAdaptedTestClassResource/PSAdaptedTestClass' -i '{"name":"hello"}' | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.actualState.Name | Should -BeExactly 'hello' + } finally { + $env:PATH = $oldPath + } + } } diff --git a/dsc/Cargo.toml b/dsc/Cargo.toml index 10b1f4ec5..6c6c0ce45 100644 --- a/dsc/Cargo.toml +++ b/dsc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dsc" -version = "3.2.0" +version = "3.2.1" edition = "2024" [dependencies] diff --git a/dsc/tests/dsc_adapter.tests.ps1 b/dsc/tests/dsc_adapter.tests.ps1 index 097e5a337..2b0f09673 100644 --- a/dsc/tests/dsc_adapter.tests.ps1 +++ b/dsc/tests/dsc_adapter.tests.ps1 @@ -179,6 +179,14 @@ Describe 'Tests for adapter support' { $out.schema | Should -Not -BeNullOrEmpty } + It 'Specifying includeQuotes should include quotes for path' { + $out = dsc -l trace resource set -r Adapted/Two -i '{"two":"2"}' 2>$TestDrive/error.log | ConvertFrom-Json -Depth 10 + $errorLog = Get-Content $TestDrive/error.log -Raw + $LASTEXITCODE | Should -Be 0 -Because $errorLog + $errorLog | Should -BeLike '*Invoking command ''dsctest'' with args Some(`["adapter", "--operation", "set", "--input", "{\"two\":\"2\"}", "--resource-type", "Adapted/Two", "--resource-path", "\"*adaptedTest.dsc.adaptedResource.json\""`])*' -Because $errorLog + $out.afterState.two | Should -BeExactly 'value2' -Because $errorLog + } + It 'Adapted resource with condition false should not be returned' { $out = dsc -l debug resource list 'Adapted/Four' 2>$TestDrive/error.log $errorLog = Get-Content $TestDrive/error.log -Raw diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index 8a3b2e646..3508cff88 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -961,10 +961,14 @@ pub fn process_get_args(args: Option<&Vec>, input: &str, command_res processed_args.push(resource_type_arg.clone()); processed_args.push(command_resource_info.type_name.to_string()); }, - GetArgKind::ResourcePath { resource_path_arg } => { + GetArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - processed_args.push(path.to_string_lossy().to_string()); + if *include_quotes { + processed_args.push(format!("\"{}\"", path.to_string_lossy())); + } else { + processed_args.push(path.to_string_lossy().to_string()); + } } }, } @@ -1026,10 +1030,14 @@ fn process_set_delete_args(args: Option<&Vec>, input: &str, co processed_args.push(json_input_arg.clone()); processed_args.push(input.to_string()); }, - SetDeleteArgKind::ResourcePath { resource_path_arg } => { + SetDeleteArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - processed_args.push(path.to_string_lossy().to_string()); + if *include_quotes { + processed_args.push(format!("\"{}\"", path.to_string_lossy())); + } else { + processed_args.push(path.to_string_lossy().to_string()); + } } }, SetDeleteArgKind::ResourceType { resource_type_arg } => { diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 96cbdcef2..568e44f9b 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -112,14 +112,17 @@ pub enum GetArgKind { /// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false. mandatory: Option, }, + #[serde(rename_all = "camelCase")] ResourcePath { /// The argument that accepts the resource path. - #[serde(rename = "resourcePathArg")] resource_path_arg: String, + /// Indicates if the argument should be wrapped in quotes. Default is false. + #[serde(default)] + include_quotes: bool, }, + #[serde(rename_all = "camelCase")] ResourceType { /// The argument that accepts the resource type name. - #[serde(rename = "resourceTypeArg")] resource_type_arg: String, }, } @@ -138,20 +141,23 @@ pub enum SetDeleteArgKind { /// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false. mandatory: Option, }, + #[serde(rename_all = "camelCase")] ResourcePath { /// The argument that accepts the resource path. - #[serde(rename = "resourcePathArg")] resource_path_arg: String, + /// Indicates if the resource path should be passed with quotes. Default is false. + #[serde(default)] + include_quotes: bool, }, + #[serde(rename_all = "camelCase")] ResourceType { /// The argument that accepts the resource type name. - #[serde(rename = "resourceTypeArg")] resource_type_arg: String, }, /// The argument is passed when the resource is invoked in what-if mode. + #[serde(rename_all = "camelCase")] WhatIf { /// The argument to pass when in what-if mode. - #[serde(rename = "whatIfArg")] what_if_arg: String, } } diff --git a/tools/dsctest/dsctest.dsc.manifests.json b/tools/dsctest/dsctest.dsc.manifests.json index aebd5a990..681dbbf4d 100644 --- a/tools/dsctest/dsctest.dsc.manifests.json +++ b/tools/dsctest/dsctest.dsc.manifests.json @@ -966,6 +966,10 @@ }, { "resourceTypeArg": "--resource-type" + }, + { + "resourcePathArg": "--resource-path", + "includeQuotes": true } ] },