Skip to content

Commit 493d75b

Browse files
authored
Merge pull request #997 from SteveL-MSFT/bicep-extension
Enable passing Bicep files directly to dsc
2 parents 0112a57 + d2c1d4f commit 493d75b

File tree

23 files changed

+329
-46
lines changed

23 files changed

+329
-46
lines changed

build.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ if ($GetPackageVersion) {
4040
$filesForWindowsPackage = @(
4141
'appx.dsc.extension.json',
4242
'appx-discover.ps1',
43+
'bicep.dsc.extension.json',
4344
'dsc.exe',
4445
'dsc_default.settings.json',
4546
'dsc.settings.json',
@@ -75,6 +76,7 @@ $filesForWindowsPackage = @(
7576
)
7677

7778
$filesForLinuxPackage = @(
79+
'bicep.dsc.extension.json',
7880
'dsc',
7981
'dsc_default.settings.json',
8082
'dsc.settings.json'
@@ -99,6 +101,7 @@ $filesForLinuxPackage = @(
99101
)
100102

101103
$filesForMacPackage = @(
104+
'bicep.dsc.extension.json',
102105
'dsc',
103106
'dsc_default.settings.json',
104107
'dsc.settings.json'
@@ -305,6 +308,7 @@ if (!$SkipBuild) {
305308
"dsc_lib",
306309
"dsc",
307310
"dscecho",
311+
"extensions/bicep",
308312
"osinfo",
309313
"powershell-adapter",
310314
'resources/PSScript',
@@ -313,8 +317,7 @@ if (!$SkipBuild) {
313317
"sshdconfig",
314318
"tools/dsctest",
315319
"tools/test_group_resource",
316-
"y2j",
317-
"."
320+
"y2j"
318321
)
319322
$pedantic_unclean_projects = @()
320323
$clippy_unclean_projects = @("tree-sitter-dscexpression", "tree-sitter-ssh-server-config")

dsc/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dsc/examples/bicepconfig.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"experimentalFeaturesEnabled": {
3+
"desiredStateConfiguration": true
4+
}
5+
}

dsc/examples/hello_world.dsc.bicep

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// This is a very simple example Bicep file for testing
2+
3+
targetScope = 'desiredStateConfiguration'
4+
5+
// use workaround where Bicep currently requires version in date format
6+
resource echo 'Microsoft.DSC.Debug/Echo@2025-01-01' = {
7+
name: 'exampleEcho'
8+
properties: {
9+
output: 'Hello, world!'
10+
}
11+
}

dsc/src/subcommand.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ pub fn validate_config(config: &Configuration, progress_format: ProgressFormat)
480480
let schema = serde_json::to_value(get_schema(SchemaType::Configuration))?;
481481
let config_value = serde_json::to_value(config)?;
482482
validate_json("Configuration", &schema, &config_value)?;
483-
let mut dsc = DscManager::new()?;
483+
let mut dsc = DscManager::new();
484484

485485
// then validate each resource
486486
let Some(resources) = config_value["resources"].as_array() else {
@@ -551,13 +551,7 @@ pub fn validate_config(config: &Configuration, progress_format: ProgressFormat)
551551
}
552552

553553
pub fn extension(subcommand: &ExtensionSubCommand, progress_format: ProgressFormat) {
554-
let mut dsc = match DscManager::new() {
555-
Ok(dsc) => dsc,
556-
Err(err) => {
557-
error!("Error: {err}");
558-
exit(EXIT_DSC_ERROR);
559-
}
560-
};
554+
let mut dsc = DscManager::new();
561555

562556
match subcommand {
563557
ExtensionSubCommand::List{extension_name, output_format} => {
@@ -577,13 +571,7 @@ pub fn function(subcommand: &FunctionSubCommand) {
577571

578572
#[allow(clippy::too_many_lines)]
579573
pub fn resource(subcommand: &ResourceSubCommand, progress_format: ProgressFormat) {
580-
let mut dsc = match DscManager::new() {
581-
Ok(dsc) => dsc,
582-
Err(err) => {
583-
error!("Error: {err}");
584-
exit(EXIT_DSC_ERROR);
585-
}
586-
};
574+
let mut dsc = DscManager::new();
587575

588576
match subcommand {
589577
ResourceSubCommand::List { resource_name, adapter_name, description, tags, output_format } => {

dsc/src/util.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
use crate::args::{SchemaType, OutputFormat, TraceFormat};
55
use crate::resolve::Include;
6-
use dsc_lib::configure::config_result::ResourceTestResult;
7-
use dsc_lib::extensions::discover::DiscoverResult;
8-
use dsc_lib::extensions::extension_manifest::ExtensionManifest;
96
use dsc_lib::{
107
configure::{
118
config_doc::{
@@ -16,22 +13,33 @@ use dsc_lib::{
1613
config_result::{
1714
ConfigurationGetResult,
1815
ConfigurationSetResult,
19-
ConfigurationTestResult
20-
}
16+
ConfigurationTestResult,
17+
ResourceTestResult,
18+
},
2119
},
20+
discovery::Discovery,
2221
dscerror::DscError,
2322
dscresources::{
2423
command_resource::TraceLevel,
25-
dscresource::DscResource, invoke_result::{
24+
dscresource::DscResource,
25+
invoke_result::{
2626
GetResult,
2727
SetResult,
2828
TestResult,
2929
ResolveResult,
30-
}, resource_manifest::ResourceManifest
30+
},
31+
resource_manifest::ResourceManifest
32+
},
33+
extensions::{
34+
discover::DiscoverResult,
35+
dscextension::Capability,
36+
extension_manifest::ExtensionManifest,
3137
},
3238
functions::FunctionDefinition,
33-
util::parse_input_to_json,
34-
util::get_setting,
39+
util::{
40+
get_setting,
41+
parse_input_to_json,
42+
},
3543
};
3644
use jsonschema::Validator;
3745
use path_absolutize::Absolutize;
@@ -487,6 +495,13 @@ pub fn get_input(input: Option<&String>, file: Option<&String>, parameters_from_
487495
}
488496
}
489497
} else {
498+
// see if an extension should handle this file
499+
let mut discovery = Discovery::new();
500+
for extension in discovery.get_extensions(&Capability::Import) {
501+
if let Ok(content) = extension.import(path) {
502+
return content;
503+
}
504+
}
490505
match std::fs::read_to_string(path) {
491506
Ok(input) => {
492507
// check if it contains UTF-8 BOM and remove it

dsc/tests/dsc_extension_discover.tests.ps1

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ Describe 'Discover extension tests' {
1515
It 'Discover extensions' {
1616
$out = dsc extension list | ConvertFrom-Json
1717
$LASTEXITCODE | Should -Be 0
18-
$out.Count | Should -Be 1
19-
$out.type | Should -BeExactly 'Test/Discover'
20-
$out.version | Should -BeExactly '0.1.0'
21-
$out.capabilities | Should -BeExactly @('discover')
22-
$out.manifest | Should -Not -BeNullOrEmpty
18+
$out.Count | Should -Be 2 -Because ($out | Out-String)
19+
$out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep'
20+
$out[0].version | Should -Be '0.1.0'
21+
$out[0].capabilities | Should -BeExactly @('import')
22+
$out[0].manifest | Should -Not -BeNullOrEmpty
23+
$out[1].type | Should -BeExactly 'Test/Discover'
24+
$out[1].version | Should -BeExactly '0.1.0'
25+
$out[1].capabilities | Should -BeExactly @('discover')
26+
$out[1].manifest | Should -Not -BeNullOrEmpty
2327
}
2428

2529
It 'Filtering works for extension discovered resources' {

dsc_lib/Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dsc_lib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ indicatif = "0.18"
2121
jsonschema = { version = "0.30", default-features = false }
2222
linked-hash-map = "0.5"
2323
num-traits = "0.2"
24+
path-absolutize = { version = "3.1" }
2425
regex = "1.11"
2526
rt-format = "0.3"
2627
rust-i18n = { version = "3.1" }

dsc_lib/locales/en-us.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ extensionResourceFound = "Extension found resource '%{resource}'"
9696
callingExtension = "Calling extension '%{extension}' to discover resources"
9797
extensionFoundResources = "Extension '%{extension}' found %{count} resources"
9898
invalidManifestVersion = "Manifest '%{path}' has invalid version: %{err}"
99+
importExtensionsEmpty = "Import extension '%{extension}' has no import extensions defined"
99100

100101
[dscresources.commandResource]
101102
invokeGet = "Invoking get for '%{resource}'"
@@ -183,6 +184,9 @@ secretExtensionReturnedInvalidJson = "Extension '%{extension}' returned invalid
183184
extensionReturnedSecret = "Extension '%{extension}' returned secret"
184185
extensionReturnedNoSecret = "Extension '%{extension}' did not return a secret"
185186
secretNoResults = "Extension '%{extension}' returned no output"
187+
importingFile = "Importing file '%{file}' with extension '%{extension}'"
188+
importNotSupported = "Import is not supported by extension '%{extension}' for file '%{file}'"
189+
importNoResults = "Extension '%{extension}' returned no results for import"
186190

187191
[extensions.extension_manifest]
188192
extensionManifestSchemaTitle = "Extension manifest schema URI"
@@ -453,3 +457,4 @@ foundSetting = "Found setting '%{name}' in %{path}"
453457
notFoundSetting = "Setting '%{name}' not found in %{path}"
454458
failedToGetExePath = "Can't get 'dsc' executable path"
455459
settingNotFound = "Setting '%{name}' not found"
460+
failedToAbsolutizePath = "Failed to absolutize path '%{path}'"

0 commit comments

Comments
 (0)