Skip to content

Commit 7773a93

Browse files
(GH-538) Enhance schema export functionality and add error handling for duplicate paths (#1672)
* (GH-538) Enhance schema export functionality and add error handling for duplicate paths * (GH-538) Enhance schema export functionality and add error handling for duplicate paths * Update lib/dsc-lib/src/dscresources/adapted_resource_manifest.rs Co-authored-by: Mikey Lombardi (He/Him) <michael.t.lombardi@gmail.com> * Update schema URIs in adapted resource manifests to use the new resource schema * Remove comment * Add deprecated endpoint shipped * (GH-538) Enhance schema export functionality and add error handling for duplicate paths * Update lib/dsc-lib/src/dscresources/adapted_resource_manifest.rs Co-authored-by: Mikey Lombardi (He/Him) <michael.t.lombardi@gmail.com> * Update schema URIs in adapted resource manifests to use the new resource schema * Remove comment * Add deprecated endpoint shipped * Move tests * Rename error types for consistency * Fix clippy * Fix Clippy * Fix Pester test --------- Co-authored-by: Mikey Lombardi (He/Him) <michael.t.lombardi@gmail.com>
1 parent 12be466 commit 7773a93

29 files changed

Lines changed: 307 additions & 68 deletions

File tree

adapters/powershell/Tests/PSAdaptedTestClassResource.dsc.adaptedResource.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/adaptedresource/manifest.json",
2+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/adapted/manifest.json",
33
"type": "PSAdaptedTestClassResource/PSAdaptedTestClass",
44
"kind": "resource",
55
"version": "0.1.0",

dsc/src/util.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use dsc_lib::{
4141
extension_manifest::ExtensionManifest,
4242
},
4343
functions::FunctionDefinition,
44+
schemas::dsc_repo::{DscRepoSchema, RecognizedSchemaVersion, SchemaForm, SchemaUriPrefix},
4445
util::{
4546
get_setting,
4647
parse_input_to_json,
@@ -162,37 +163,37 @@ pub fn add_fields_to_json(json: &str, fields_to_add: &HashMap<String, String>) -
162163
pub fn get_schema(schema: SchemaType) -> Schema {
163164
match schema {
164165
SchemaType::AdaptedDscResourceManifest => {
165-
schema_for!(AdaptedDscResourceManifest)
166+
repo_schema::<AdaptedDscResourceManifest>()
166167
},
167168
SchemaType::Configuration => {
168-
schema_for!(Configuration)
169+
repo_schema::<Configuration>()
169170
},
170171
SchemaType::ConfigurationExportResult => {
171-
schema_for!(ConfigurationExportResult)
172+
repo_schema::<ConfigurationExportResult>()
172173
},
173174
SchemaType::ConfigurationGetResult => {
174-
schema_for!(ConfigurationGetResult)
175+
repo_schema::<ConfigurationGetResult>()
175176
},
176177
SchemaType::ConfigurationSetResult => {
177-
schema_for!(ConfigurationSetResult)
178+
repo_schema::<ConfigurationSetResult>()
178179
},
179180
SchemaType::ConfigurationTestResult => {
180-
schema_for!(ConfigurationTestResult)
181+
repo_schema::<ConfigurationTestResult>()
181182
},
182183
SchemaType::DscResource => {
183-
schema_for!(DscResource)
184+
repo_schema::<DscResource>()
184185
},
185186
SchemaType::ExtensionDiscoverResult => {
186-
schema_for!(DiscoverResult)
187+
repo_schema::<DiscoverResult>()
187188
},
188189
SchemaType::ExtensionManifest => {
189-
schema_for!(ExtensionManifest)
190+
repo_schema::<ExtensionManifest>()
190191
},
191192
SchemaType::FunctionDefinition => {
192-
schema_for!(FunctionDefinition)
193+
repo_schema::<FunctionDefinition>()
193194
},
194195
SchemaType::GetResult => {
195-
schema_for!(GetResult)
196+
repo_schema::<GetResult>()
196197
},
197198
SchemaType::Include => {
198199
schema_for!(Include)
@@ -201,35 +202,48 @@ pub fn get_schema(schema: SchemaType) -> Schema {
201202
schema_for!(ManifestList)
202203
},
203204
SchemaType::ResolveResult => {
204-
schema_for!(ResolveResult)
205+
repo_schema::<ResolveResult>()
205206
},
206207
SchemaType::Resource => {
207-
schema_for!(Resource)
208+
repo_schema::<Resource>()
208209
},
209210
SchemaType::ResourceGetResult => {
210-
schema_for!(ResourceGetResult)
211+
repo_schema::<ResourceGetResult>()
211212
},
212213
SchemaType::ResourceSetResult => {
213-
schema_for!(ResourceSetResult)
214+
repo_schema::<ResourceSetResult>()
214215
},
215216
SchemaType::ResourceTestResult => {
216-
schema_for!(ResourceTestResult)
217+
repo_schema::<ResourceTestResult>()
217218
},
218219
SchemaType::ResourceManifest => {
219-
schema_for!(ResourceManifest)
220+
repo_schema::<ResourceManifest>()
220221
},
221222
SchemaType::RestartRequired => {
222-
schema_for!(RestartRequired)
223+
repo_schema::<RestartRequired>()
223224
},
224225
SchemaType::SetResult => {
225-
schema_for!(SetResult)
226+
repo_schema::<SetResult>()
226227
},
227228
SchemaType::TestResult => {
228-
schema_for!(TestResult)
229+
repo_schema::<TestResult>()
229230
},
230231
}
231232
}
232233

234+
fn repo_schema<T: DscRepoSchema>() -> Schema {
235+
let schema_form = if T::SCHEMA_SHOULD_BUNDLE {
236+
SchemaForm::Bundled
237+
} else {
238+
SchemaForm::Canonical
239+
};
240+
T::generate_schema(
241+
RecognizedSchemaVersion::default(),
242+
schema_form,
243+
SchemaUriPrefix::AkaDotMs
244+
)
245+
}
246+
233247
/// Write the JSON object to the console
234248
///
235249
/// # Arguments

extensions/powershell/powershell.discover.tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ BeforeAll {
2222
$fakeManifest | ConvertTo-Json -Depth 10 | Set-Content -Path $manifestPath
2323

2424
$fakeAdaptedManifest = @{
25-
'$schema' = "https://aka.ms/dsc/schemas/v3/bundled/adaptedresource/manifest.json"
25+
'$schema' = "https://aka.ms/dsc/schemas/v3/bundled/resource/adapted/manifest.json"
2626
type = "Test/FakeAdaptedResource"
2727
kind = "resource"
2828
version = "0.1.0"

extensions/test/discover/discover.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ if ($Extensions) {
1414
foreach ($extension in $Extensions.Split(',')) {
1515
$resource = [pscustomobject]@{
1616
manifestContent = @{
17-
'$schema' = "https://aka.ms/dsc/schemas/v3/bundled/adaptedresource/manifest.json"
17+
'$schema' = "https://aka.ms/dsc/schemas/v3/bundled/resource/adapted/manifest.json"
1818
type = "TestDiscover/$count"
1919
kind = "resource"
2020
version = "1.0.0"

lib/dsc-lib-jsonschema-macros/src/derive/dsc_repo_schema.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ fn generate_with_schema_field(
153153

154154
#schema_property_metadata
155155

156-
fn validate_schema_uri(&self) -> Result<(), dsc_lib_jsonschema::dsc_repo::UnrecognizedSchemaUri> {
156+
fn validate_schema_uri(&self) -> Result<(), dsc_lib_jsonschema::dsc_repo::UnrecognizedSchemaUriError> {
157157
if Self::is_recognized_schema_uri(&self.#field) {
158158
Ok(())
159159
} else {
160-
Err(dsc_lib_jsonschema::dsc_repo::UnrecognizedSchemaUri(
160+
Err(dsc_lib_jsonschema::dsc_repo::UnrecognizedSchemaUriError(
161161
self.#field.clone(),
162162
Self::recognized_schema_uris(),
163163
))
@@ -196,12 +196,12 @@ fn generate_schema_property_metadata_fn(schema_field: &DscRepoSchemaField) -> pr
196196
/// required to ensure that the translations use the correct locale definitions.
197197
fn generate_schema_i18n_fn() -> proc_macro2::TokenStream {
198198
quote! {
199-
fn schema_i18n(suffix: &str) -> Result<String, dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslation> {
199+
fn schema_i18n(suffix: &str) -> Result<String, dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslationError> {
200200
let i18n_key = format!("{}.{}", Self::SCHEMA_I18N_ROOT_KEY, suffix);
201201
if let Some(translated) = crate::_rust_i18n_try_translate(&rust_i18n::locale(), &i18n_key) {
202202
Ok(translated.into())
203203
} else {
204-
Err(dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslation { i18n_key })
204+
Err(dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslationError { i18n_key })
205205
}
206206
}
207207
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ unrecognizedSchemaUri = "Unrecognized $schema URI"
55
validSchemaUrisAre = "Valid schema URIs are"
66
missingTranslation = "unable to retrieve translation for undefined key '#{key}'"
77

8+
[dsc_repo.recognized_schema_version]
9+
unrecognizedVersion = "Unrecognized schema version folder"
10+
validVersionsAre = "Valid schema version folders are"
11+
812
[transforms.idiomaticize_externally_tagged_enum]
913
applies_to = "invalid application of idiomaticize_externally_tagged_enum; missing 'oneOf' keyword in transforming schema: %{transforming_schema}"
1014
oneOf_array = "invalid application of idiomaticize_externally_tagged_enum; 'oneOf' isn't an array in transforming schema: %{transforming_schema}"

lib/dsc-lib-jsonschema/src/dsc_repo/dsc_repo_schema.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ pub trait DscRepoSchema : JsonSchema {
327327
/// # Errors
328328
///
329329
/// If the value for the schema field isn't a recognized schema, the method should raise the
330-
/// [`UnrecognizedSchemaUri`] error.
331-
fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUri> {
330+
/// [`UnrecognizedSchemaUriError`] error.
331+
fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUriError> {
332332
Ok(())
333333
}
334334

@@ -355,8 +355,8 @@ pub trait DscRepoSchema : JsonSchema {
355355
///
356356
/// # Errors
357357
///
358-
/// Returns a [`DscRepoSchemaMissingTranslation`] error if the translation key doesn't exist.
359-
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslation>;
358+
/// Returns a [`DscRepoSchemaMissingTranslationError`] error if the translation key doesn't exist.
359+
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslationError>;
360360
}
361361

362362
/// Defines the error when a user-defined JSON Schema references an unrecognized schema URI.
@@ -366,13 +366,13 @@ pub trait DscRepoSchema : JsonSchema {
366366
t = t!("dsc_repo.dsc_repo_schema.unrecognizedSchemaUri"),
367367
t2 = t!("dsc_repo.dsc_repo_schema.validSchemaUrisAre")
368368
)]
369-
pub struct UnrecognizedSchemaUri(pub String, pub Vec<String>);
369+
pub struct UnrecognizedSchemaUriError(pub String, pub Vec<String>);
370370

371371
#[derive(Error, Debug, Clone, PartialEq)]
372372
#[error("{t}", t = t!(
373373
"dsc_repo.dsc_repo_schema.missingTranslation",
374374
"key" => i18n_key
375375
))]
376-
pub struct DscRepoSchemaMissingTranslation {
376+
pub struct DscRepoSchemaMissingTranslationError {
377377
pub i18n_key: String
378378
}

lib/dsc-lib-jsonschema/src/dsc_repo/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ use schemars::{Schema, json_schema};
55

66
mod dsc_repo_schema;
77
pub use dsc_repo_schema::DscRepoSchema;
8-
pub use dsc_repo_schema::UnrecognizedSchemaUri;
9-
pub use dsc_repo_schema::DscRepoSchemaMissingTranslation;
8+
pub use dsc_repo_schema::UnrecognizedSchemaUriError;
9+
pub use dsc_repo_schema::DscRepoSchemaMissingTranslationError;
1010

1111
#[macro_use]
1212
mod macros;
1313
pub use crate::schema_i18n;
1414

1515
mod recognized_schema_version;
1616
pub use recognized_schema_version::RecognizedSchemaVersion;
17+
pub use recognized_schema_version::UnrecognizedSchemaVersionError;
1718

1819
mod schema_form;
1920
pub use schema_form::SchemaForm;

lib/dsc-lib-jsonschema/src/dsc_repo/recognized_schema_version.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,31 @@
66
//! checks the git tags for non-prerelease versions of DSC to generate the enum type with all of the
77
//! correct values. The enum can be used transparently throughout the rest of the libraries.
88
9+
use rust_i18n::t;
10+
use thiserror::Error;
11+
912
include!(concat!(env!("OUT_DIR"), "/recognized_schema_version.rs"));
13+
14+
/// Defines the error when parsing a string that isn't a recognized schema version folder.
15+
#[derive(Error, Debug, Clone, PartialEq)]
16+
#[error(
17+
"{t}: {0}. {t2}: {1:?}",
18+
t = t!("dsc_repo.recognized_schema_version.unrecognizedVersion"),
19+
t2 = t!("dsc_repo.recognized_schema_version.validVersionsAre")
20+
)]
21+
pub struct UnrecognizedSchemaVersionError(pub String, pub Vec<String>);
22+
23+
impl std::str::FromStr for RecognizedSchemaVersion {
24+
type Err = UnrecognizedSchemaVersionError;
25+
26+
fn from_str(s: &str) -> Result<Self, Self::Err> {
27+
let candidate = s.trim();
28+
Self::all()
29+
.into_iter()
30+
.find(|version| version.to_string().eq_ignore_ascii_case(candidate))
31+
.ok_or_else(|| UnrecognizedSchemaVersionError(
32+
candidate.to_string(),
33+
Self::all().iter().map(ToString::to_string).collect()
34+
))
35+
}
36+
}

lib/dsc-lib-jsonschema/src/tests/dsc_repo.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use schemars::{JsonSchema, Schema, json_schema};
55
use serde::{Deserialize, Serialize};
66

77
use crate::dsc_repo::{
8-
DscRepoSchema, DscRepoSchemaMissingTranslation, RecognizedSchemaVersion, SchemaForm, SchemaUriPrefix, get_default_schema_uri, get_recognized_schema_uri
8+
DscRepoSchema, DscRepoSchemaMissingTranslationError, RecognizedSchemaVersion, SchemaForm, SchemaUriPrefix, get_default_schema_uri, get_recognized_schema_uri
99
};
1010

1111
#[test]
@@ -52,12 +52,12 @@ fn test_dsc_repo_schema_bundled() {
5252
const SCHEMA_SHOULD_BUNDLE: bool = true;
5353
const SCHEMA_I18N_ROOT_KEY: &'static str = "example.schema";
5454

55-
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslation> {
55+
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslationError> {
5656
let i18n_key = format!("{}.{}", Self::SCHEMA_I18N_ROOT_KEY, suffix);
5757
if let Some(translated) = crate::_rust_i18n_try_translate(&rust_i18n::locale(), &i18n_key) {
5858
Ok(translated.into())
5959
} else {
60-
Err(DscRepoSchemaMissingTranslation { i18n_key })
60+
Err(DscRepoSchemaMissingTranslationError { i18n_key })
6161
}
6262
}
6363

@@ -107,12 +107,12 @@ fn test_dsc_repo_schema_not_bundled() {
107107
const SCHEMA_SHOULD_BUNDLE: bool = false;
108108
const SCHEMA_I18N_ROOT_KEY: &'static str = "example.schema";
109109

110-
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslation> {
110+
fn schema_i18n(suffix: &str) -> Result<String, DscRepoSchemaMissingTranslationError> {
111111
let i18n_key = format!("{}.{}", Self::SCHEMA_I18N_ROOT_KEY, suffix);
112112
if let Some(translated) = crate::_rust_i18n_try_translate(&rust_i18n::locale(), &i18n_key) {
113113
Ok(translated.into())
114114
} else {
115-
Err(DscRepoSchemaMissingTranslation { i18n_key })
115+
Err(DscRepoSchemaMissingTranslationError { i18n_key })
116116
}
117117
}
118118

0 commit comments

Comments
 (0)