Skip to content

Commit eb66390

Browse files
authored
Merge branch 'main' into arg-object
2 parents fdab2f1 + ef36815 commit eb66390

File tree

13 files changed

+566
-34
lines changed

13 files changed

+566
-34
lines changed

.github/workflows/rust.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
branches: [ "main" ]
66
pull_request:
77
branches: [ "main" ]
8+
paths-ignore:
9+
- "docs/**"
10+
- "*.md"
11+
- ".vscode/*.json"
812

913
env:
1014
CARGO_TERM_COLOR: always

dsc/src/util.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,26 +272,30 @@ pub fn enable_tracing(trace_level: &TraceLevel, trace_format: &TraceFormat) {
272272
.add_directive(tracing_level.into());
273273
let indicatif_layer = IndicatifLayer::new();
274274
let layer = tracing_subscriber::fmt::Layer::default().with_writer(indicatif_layer.get_stderr_writer());
275+
let with_source = tracing_level == Level::DEBUG || tracing_level == Level::TRACE;
275276
let fmt = match trace_format {
276277
TraceFormat::Default => {
277278
layer
278279
.with_ansi(true)
279280
.with_level(true)
280-
.with_line_number(true)
281+
.with_target(with_source)
282+
.with_line_number(with_source)
281283
.boxed()
282284
},
283285
TraceFormat::Plaintext => {
284286
layer
285287
.with_ansi(false)
286288
.with_level(true)
287-
.with_line_number(false)
289+
.with_target(with_source)
290+
.with_line_number(with_source)
288291
.boxed()
289292
},
290293
TraceFormat::Json => {
291294
layer
292295
.with_ansi(false)
293296
.with_level(true)
294-
.with_line_number(true)
297+
.with_target(with_source)
298+
.with_line_number(with_source)
295299
.json()
296300
.boxed()
297301
}

dsc/tests/dsc_discovery.tests.ps1

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,45 @@ Describe 'tests for resource discovery' {
6767
$resources = dsc resource list | ConvertFrom-Json
6868
$resources.Count | Should -Be 0
6969
}
70+
71+
It 'warns on invalid semver' {
72+
$manifest = @'
73+
{
74+
"$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.json",
75+
"type": "Test/Echo",
76+
"version": "1.1.0..1",
77+
"get": {
78+
"executable": "dsctest",
79+
"args": [
80+
"echo",
81+
"--input",
82+
"{json}"
83+
],
84+
"input": {
85+
"arg": "{json}"
86+
}
87+
},
88+
"schema": {
89+
"command": {
90+
"executable": "dsctest",
91+
"args": [
92+
"schema",
93+
"-s",
94+
"echo"
95+
]
96+
}
97+
}
98+
}
99+
'@
100+
$oldPath = $env:DSC_RESOURCE_PATH
101+
try {
102+
$env:DSC_RESOURCE_PATH = $testdrive
103+
Set-Content -Path "$testdrive/test.dsc.resource.json" -Value $manifest
104+
$out = dsc resource list 2>&1
105+
$out | Should -Match 'WARN.*?Validation.*?Invalid manifest.*?version'
106+
}
107+
finally {
108+
$env:DSC_RESOURCE_PATH = $oldPath
109+
}
110+
}
70111
}

dsc/tests/dsc_tracing.tests.ps1

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Describe 'tracing tests' {
77
# @{ level = 'WARNING' } TODO: currently no warnings are emitted
88
@{ level = 'info' }
99
@{ level = 'debug' }
10-
# @{ level = 'trace' } TODO: currently no trace is emitted
10+
@{ level = 'trace' }
1111
) {
1212
param($level)
1313

@@ -44,4 +44,23 @@ Describe 'tracing tests' {
4444
$trace.fields.message | Should -Not -BeNullOrEmpty
4545
}
4646
}
47+
48+
It 'trace level <level> emits source info: <sourceExpected>' -TestCases @(
49+
@{ level = 'error'; sourceExpected = $false }
50+
@{ level = 'warning'; sourceExpected = $false }
51+
@{ level = 'info'; sourceExpected = $false }
52+
@{ level = 'debug'; sourceExpected = $true }
53+
@{ level = 'trace'; sourceExpected = $true }
54+
) {
55+
param($level, $sourceExpected)
56+
57+
$logPath = "$TestDrive/dsc_trace.log"
58+
$null = '{}' | dsc -l $level resource get -r 'DoesNotExist' 2> $logPath
59+
$log = Get-Content $logPath -Raw
60+
if ($sourceExpected) {
61+
$log | Should -BeLike "*dsc*: *"
62+
} else {
63+
$log | Should -Not -BeLike "*dsc*: *"
64+
}
65+
}
4766
}

dsc_lib/Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ version = "3.0.0-preview.7"
44
edition = "2021"
55

66
[dependencies]
7-
base64 = "0.21"
7+
base64 = "0.22"
8+
chrono = "0.4.26"
89
derive_builder ="0.20"
910
indicatif = { version = "0.17" }
1011
jsonschema = "0.17"
1112
num-traits = "0.2"
1213
regex = "1.7"
13-
reqwest = { version = "0.11", features = ["blocking"] }
14+
reqwest = { version = "0.12", features = ["blocking"] }
1415
schemars = { version = "0.8.12", features = ["preserve_order"] }
1516
serde = { version = "1.0", features = ["derive"] }
1617
serde_json = { version = "1.0", features = ["preserve_order"] }
1718
serde_yaml = { version = "0.9.3" }
1819
thiserror = "1.0"
19-
chrono = "0.4.26"
2020
security_context_lib = { path = "../security_context_lib" }
21+
semver = "1.0"
2122
tracing = "0.1.37"
2223
tracing-indicatif = { version = "0.3.6" }
23-
tree-sitter = "0.20"
24+
tree-sitter = "0.22"
2425
tree-sitter-dscexpression = { path = "../tree-sitter-dscexpression" }
2526

2627
[dev-dependencies]

dsc_lib/src/discovery/command_discovery.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use crate::discovery::discovery_trait::ResourceDiscovery;
55
use crate::discovery::convert_wildcard_to_regex;
66
use crate::dscresources::dscresource::{Capability, DscResource, ImplementedAs};
7-
use crate::dscresources::resource_manifest::{import_manifest, Kind, ResourceManifest};
7+
use crate::dscresources::resource_manifest::{import_manifest, validate_semver, Kind, ResourceManifest};
88
use crate::dscresources::command_resource::invoke_command;
99
use crate::dscresources::command_resource::log_resource_traces;
1010
use crate::dscerror::DscError;
@@ -380,6 +380,10 @@ fn load_manifest(path: &Path) -> Result<DscResource, DscError> {
380380
}
381381
};
382382

383+
if let Err(err) = validate_semver(&manifest.version) {
384+
return Err(DscError::Validation(format!("Invalid manifest {path:?} version value: {err}")));
385+
}
386+
383387
let kind = if let Some(kind) = manifest.kind.clone() {
384388
kind
385389
} else if manifest.adapter.is_some() {

dsc_lib/src/dscresources/dscresource.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@ pub trait Invoke {
130130
fn test(&self, expected: &str) -> Result<TestResult, DscError>;
131131

132132
/// Invoke the delete operation on the resource.
133-
///
133+
///
134134
/// # Arguments
135-
///
135+
///
136136
/// * `filter` - The filter as JSON to apply to the resource.
137-
///
137+
///
138138
/// # Errors
139-
///
139+
///
140140
/// This function will return an error if the underlying resource fails.
141141
fn delete(&self, filter: &str) -> Result<(), DscError>;
142142

@@ -256,7 +256,7 @@ impl Invoke for DscResource {
256256
let resource_manifest = import_manifest(manifest.clone())?;
257257
command_resource::invoke_delete(&resource_manifest, &self.directory, filter)
258258
},
259-
}
259+
}
260260
}
261261

262262
fn validate(&self, config: &str) -> Result<ValidateResult, DscError> {

dsc_lib/src/dscresources/resource_manifest.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
use schemars::JsonSchema;
5+
use semver::Version;
56
use serde::{Deserialize, Serialize};
67
use serde_json::Value;
78
use std::collections::HashMap;
@@ -27,7 +28,7 @@ pub struct ResourceManifest {
2728
/// The kind of resource.
2829
#[serde(skip_serializing_if = "Option::is_none")]
2930
pub kind: Option<Kind>,
30-
/// The version of the resource.
31+
/// The version of the resource using semantic versioning.
3132
pub version: String,
3233
/// The description of the resource.
3334
pub description: Option<String>,
@@ -248,11 +249,29 @@ pub struct ListMethod {
248249
///
249250
/// * `DscError` - The JSON value is invalid or the schema version is not supported.
250251
pub fn import_manifest(manifest: Value) -> Result<ResourceManifest, DscError> {
252+
// TODO: enable schema version validation, if not provided, use the latest
251253
// const MANIFEST_SCHEMA_VERSION: &str = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.json";
252254
let manifest = serde_json::from_value::<ResourceManifest>(manifest)?;
253255
// if !manifest.schema_version.eq(MANIFEST_SCHEMA_VERSION) {
254256
// return Err(DscError::InvalidManifestSchemaVersion(manifest.schema_version, MANIFEST_SCHEMA_VERSION.to_string()));
255257
// }
256-
257258
Ok(manifest)
258259
}
260+
261+
/// Validate a semantic version string.
262+
///
263+
/// # Arguments
264+
///
265+
/// * `version` - The semantic version string to validate.
266+
///
267+
/// # Returns
268+
///
269+
/// * `Result<(), Error>` - The result of the validation.
270+
///
271+
/// # Errors
272+
///
273+
/// * `Error` - The version string is not a valid semantic version.
274+
pub fn validate_semver(version: &str) -> Result<(), semver::Error> {
275+
Version::parse(version)?;
276+
Ok(())
277+
}

dsc_lib/src/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Statement {
2626
/// This function will return an error if the underlying parser fails to initialize.
2727
pub fn new() -> Result<Self, DscError> {
2828
let mut parser = Parser::new();
29-
parser.set_language(tree_sitter_dscexpression::language())?;
29+
parser.set_language(&tree_sitter_dscexpression::language())?;
3030
let function_dispatcher = FunctionDispatcher::new();
3131
Ok(Self {
3232
parser,

tree-sitter-dscexpression/.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Rust artifacts
2+
Cargo.lock
3+
target/
4+
5+
# Node artifacts
6+
build/
7+
prebuilds/
8+
node_modules/
9+
*.tgz
10+
11+
# Swift artifacts
12+
.build/
13+
14+
# Go artifacts
15+
go.sum
16+
_obj/
17+
18+
# Python artifacts
19+
.venv/
20+
dist/
21+
*.egg-info
22+
*.whl
23+
24+
# C artifacts
25+
*.a
26+
*.so
27+
*.so.*
28+
*.dylib
29+
*.dll
30+
*.pc
31+
32+
# Example dirs
33+
/examples/*/
34+
35+
# Grammar volatiles
36+
*.wasm
37+
*.obj
38+
*.o

0 commit comments

Comments
 (0)