Skip to content

Commit c6e12c4

Browse files
committed
Add tryWhich() function and enable manifests to have condition
1 parent ca5fefe commit c6e12c4

File tree

12 files changed

+289
-52
lines changed

12 files changed

+289
-52
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
Describe 'Extension Manifests' {
5+
It 'Extension manifests with condition: <condition>' -TestCases @(
6+
@{ condition = "[equals(1, 1)]"; shouldBeFound = $true }
7+
@{ condition = "[equals(1, 0)]"; shouldBeFound = $false }
8+
) {
9+
param($condition, $shouldBeFound)
10+
11+
$extension_manifest = @"
12+
{
13+
"`$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
14+
"type": "Test/Extension",
15+
"condition": "$condition",
16+
"version": "0.1.0",
17+
"import": {
18+
"fileExtensions": ["foo"],
19+
"executable": "dsc"
20+
}
21+
}
22+
"@
23+
24+
try {
25+
$env:DSC_RESOURCE_PATH = $TestDrive
26+
$manifestPath = Join-Path -Path $TestDrive -ChildPath 'Extension.dsc.extension.json'
27+
$extension_manifest | Out-File -FilePath $manifestPath -Encoding utf8
28+
$extensions = dsc extension list | ConvertFrom-Json -Depth 10
29+
$LASTEXITCODE | Should -Be 0
30+
if ($shouldBeFound) {
31+
$extensions.count | Should -Be 1
32+
$extensions.type | Should -BeExactly 'Test/Extension'
33+
}
34+
else {
35+
$extensions.count | Should -Be 0
36+
}
37+
} finally {
38+
$env:DSC_RESOURCE_PATH = $null
39+
}
40+
}
41+
}

dsc/tests/dsc_functions.tests.ps1

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Describe 'tests for function expressions' {
123123
@{ expression = "[intersection(parameters('nestedObject1'), parameters('nestedObject2'))]"; expected = [pscustomobject]@{
124124
shared = [pscustomobject]@{ value = 42; flag = $true }
125125
level = 1
126-
}
126+
}
127127
}
128128
@{ expression = "[intersection(parameters('nestedObject1'), parameters('nestedObject3'))]"; expected = [pscustomobject]@{ level = 1 } }
129129
@{ expression = "[intersection(parameters('nestedObject1'), parameters('nestedObject2'), parameters('nestedObject4'))]"; expected = [pscustomobject]@{ level = 1 } }
@@ -948,10 +948,10 @@ Describe 'tests for function expressions' {
948948
@{ testInput = ' ' }
949949
) {
950950
param($testInput)
951-
951+
952952
$expected = [Uri]::EscapeDataString($testInput)
953953
$expression = "[uriComponent('$($testInput -replace "'", "''")')]"
954-
954+
955955
$config_yaml = @"
956956
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
957957
resources:
@@ -963,13 +963,13 @@ Describe 'tests for function expressions' {
963963
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
964964
$out.results[0].result.actualState.output | Should -BeExactly $expected
965965
}
966-
966+
967967
It 'uriComponent function works with concat' {
968968
$input1 = 'hello'
969969
$input2 = ' '
970970
$input3 = 'world'
971971
$expected = [Uri]::EscapeDataString($input1 + $input2 + $input3)
972-
972+
973973
$config_yaml = @"
974974
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
975975
resources:
@@ -995,10 +995,10 @@ Describe 'tests for function expressions' {
995995
@{ testInput = '100%25' }
996996
) {
997997
param($testInput)
998-
998+
999999
$expected = [Uri]::UnescapeDataString($testInput)
10001000
$expression = "[uriComponentToString('$($testInput -replace "'", "''")')]"
1001-
1001+
10021002
$config_yaml = @"
10031003
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
10041004
resources:
@@ -1010,11 +1010,11 @@ Describe 'tests for function expressions' {
10101010
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
10111011
$out.results[0].result.actualState.output | Should -BeExactly $expected
10121012
}
1013-
1013+
10141014
It 'uriComponentToString function works with round-trip encoding' {
10151015
$original = 'hello world'
10161016
$expected = $original
1017-
1017+
10181018
$config_yaml = @"
10191019
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
10201020
resources:
@@ -1026,11 +1026,11 @@ Describe 'tests for function expressions' {
10261026
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
10271027
$out.results[0].result.actualState.output | Should -BeExactly $expected
10281028
}
1029-
1029+
10301030
It 'uriComponentToString function works with nested round-trip' {
10311031
$original = 'user+tag@example.com'
10321032
$expected = $original
1033-
1033+
10341034
$config_yaml = @"
10351035
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
10361036
resources:
@@ -1042,13 +1042,13 @@ Describe 'tests for function expressions' {
10421042
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
10431043
$out.results[0].result.actualState.output | Should -BeExactly $expected
10441044
}
1045-
1045+
10461046
It 'uriComponentToString function works with concat' {
10471047
$input1 = 'hello'
10481048
$input2 = '%20'
10491049
$input3 = 'world'
10501050
$expected = [Uri]::UnescapeDataString($input1 + $input2 + $input3)
1051-
1051+
10521052
$config_yaml = @"
10531053
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
10541054
resources:
@@ -1077,7 +1077,7 @@ Describe 'tests for function expressions' {
10771077
@{ data = @{ nested = @{ value = 123 } }; accessor = '.nested.value'; expected = 123 }
10781078
) {
10791079
param($data, $accessor, $expected)
1080-
1080+
10811081
$jsonString = ConvertTo-Json -Compress -InputObject $data
10821082
$expression = "[json(''$($jsonString)'')$accessor]"
10831083

@@ -1116,4 +1116,27 @@ Describe 'tests for function expressions' {
11161116
$errorContent = Get-Content $TestDrive/error.log -Raw
11171117
$errorContent | Should -Match ([regex]::Escape('Invalid JSON string'))
11181118
}
1119+
1120+
It 'tryWhich() works for: <expression>' -TestCases @(
1121+
@{ expression = "[tryWhich('pwsh')]"; found = $true }
1122+
@{ expression = "[tryWhich('nonexistentcommand12345')]"; found = $false }
1123+
) {
1124+
param($expression, $found)
1125+
1126+
$config_yaml = @"
1127+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
1128+
resources:
1129+
- name: Echo
1130+
type: Microsoft.DSC.Debug/Echo
1131+
properties:
1132+
output: "$expression"
1133+
"@
1134+
$out = dsc -l trace config get -i $config_yaml 2>$TestDrive/error.log | ConvertFrom-Json
1135+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content $TestDrive/error.log -Raw)
1136+
if ($found) {
1137+
$out.results[0].result.actualState.output | Should -Not -BeNullOrEmpty
1138+
} else {
1139+
$out.results[0].result.actualState.output | Should -BeNullOrEmpty
1140+
}
1141+
}
11191142
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
Describe 'Resource Manifests' {
5+
It 'Resource manifests with condition: <condition>' -TestCases @(
6+
@{ condition = "[equals(1, 1)]"; shouldBeFound = $true }
7+
@{ condition = "[equals(1, 0)]"; shouldBeFound = $false }
8+
) {
9+
param($condition, $shouldBeFound)
10+
11+
$resource_manifest = @"
12+
{
13+
"`$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
14+
"type": "Test/MyEcho",
15+
"version": "1.0.0",
16+
"condition": "$condition",
17+
"get": {
18+
"executable": "dscecho",
19+
"args": [
20+
{
21+
"jsonInputArg": "--input",
22+
"mandatory": true
23+
}
24+
]
25+
},
26+
"schema": {
27+
"command": {
28+
"executable": "dscecho"
29+
}
30+
}
31+
}
32+
"@
33+
34+
try {
35+
$env:DSC_RESOURCE_PATH = $TestDrive
36+
$manifestPath = Join-Path -Path $TestDrive -ChildPath 'MyEcho.dsc.resource.json'
37+
$resource_manifest | Out-File -FilePath $manifestPath -Encoding utf8
38+
$resources = dsc resource list | ConvertFrom-Json -Depth 10
39+
$LASTEXITCODE | Should -Be 0
40+
if ($shouldBeFound) {
41+
$resources.count | Should -Be 1
42+
$resources.type | Should -BeExactly 'Test/MyEcho'
43+
}
44+
else {
45+
$resources.count | Should -Be 0
46+
}
47+
} finally {
48+
$env:DSC_RESOURCE_PATH = $null
49+
}
50+
}
51+
}

extensions/bicep/bicep.dsc.extension.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"type": "Microsoft.DSC.Extension/Bicep",
44
"version": "0.1.0",
55
"description": "Enable passing Bicep file directly to DSC, but requires bicep executable to be available.",
6+
"condition": "[not(equals(tryWhich('bicep'), null()))]",
67
"import": {
78
"fileExtensions": ["bicep"],
89
"executable": "bicep",

lib/dsc-lib/locales/en-us.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ foundResourceWithVersion = "Found matching resource '%{resource}' version %{vers
110110
foundNonAdapterResources = "Found %{count} non-adapter resources"
111111
resourceMissingRequireAdapter = "Resource '%{resource}' is missing 'require_adapter' field."
112112
extensionDiscoverFailed = "Extension '%{extension}' failed to discover resources: %{error}"
113+
conditionNotBoolean = "Condition '%{condition}' did not evaluate to a boolean"
114+
conditionNotMet = "Condition '%{condition}' not met, skipping manifest at '%{path}'"
113115

114116
[dscresources.commandResource]
115117
invokeGet = "Invoking get for '%{resource}'"
@@ -533,6 +535,10 @@ invoked = "tryGet function"
533535
invalidKeyType = "Invalid key type, must be a string"
534536
invalidIndexType = "Invalid index type, must be an integer"
535537

538+
[functions.tryWhich]
539+
description = "Attempts to locate an executable in the system PATH. Null is returned if the executable is not found otherwise the full path to the executable is returned."
540+
invoked = "tryWhich function"
541+
536542
[functions.union]
537543
description = "Returns a single array or object with all elements from the parameters"
538544
invoked = "union function"

0 commit comments

Comments
 (0)