Skip to content

Commit a8539f8

Browse files
(GH-538) Use DateVersion in ResourceVersion
Prior to this change, `ResourceVersion` defined the `Semantic` and `Arbitrary` variants, where the arbitrary variant was a fall-through for any version defined as a non-semantic version. This change: - Replaces the `Arbitrary` variant with a `Date` variant that wraps a `DateVersion` type. This allows us to maintain the distinction between semantic versions and date versions in the type system, which is preferable to having a catch-all arbitrary version type. - Defines the `ResourceVersionError` type with the `Error` and `Diagnostic` traits to represent errors that can occur when parsing and converting resource versions. This allows us to provide more detailed error messages and diagnostics when resource version parsing fails. To ensure these errors are properly surfaced during deserialization, this change also tells serde explicitly to deserialize from and serialize into strings, avoiding the untagged enum variant generic error message. - Replaces the `ResourceVersionToSemverConversion` variant for `DscError` with the `ResourceVersion` variant that transparently wraps `ResourceVersionError`.
1 parent 82f9abc commit a8539f8

6 files changed

Lines changed: 912 additions & 366 deletions

File tree

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,6 @@ parser = "Parser"
792792
progress = "Progress"
793793
resourceNotFound = "Resource not found"
794794
resourceManifestNotFound = "Resource manifest not found"
795-
resourceVersionToSemverConversion = "Unable to convert arbitrary string resource version to semantic version"
796795
resourceVersionReqToSemverConversion = "Unable to convert arbitrary string resource version requirement to semantic version requirement"
797796
schema = "Schema"
798797
schemaNotAvailable = "No Schema found and `validate` is not supported"
@@ -835,6 +834,13 @@ invalidDate = "unable to parse '%{text}' as a date version - %{errors}"
835834
successText = "Success"
836835
failureText = "Error"
837836

837+
[types.resource_version]
838+
unparseableVersion = "unable to parse '%{text}' as resource version - input doesn't seem to be a semantic or date version"
839+
invalidDateVersion = "invalid date resource version: %{err}"
840+
invalidSemanticVersion = "invalid semantic resource version: %{err}"
841+
invalidConversionToSemanticVersion = "unable to convert date resource version '%{version}' to semantic version"
842+
invalidConversionToDateVersion = "unable to convert semantic resource version '%{version}' to date version"
843+
838844
[types.semantic_version]
839845
invalidSemanticVersion = "invalid semantic version '%{text}': %{err}"
840846

lib/dsc-lib/locales/schemas.definitions.yaml

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -130,26 +130,24 @@ schemas:
130130
en-us: |-
131131
Defines the version of a DSC resource.
132132
133-
DSC supports both semantic versioning and arbitrary versioning for resources. Semantic
133+
DSC supports both semantic versioning and date versioning for resources. Semantic
134134
versioning is the preferred and recommended versioning strategy. DSC only supports
135-
arbitrary versioning for compatibility scenarios.
135+
date versioning for compatibility scenarios.
136136
137137
When the version is defined as a valid [semantic version][01], DSC can correctly compare
138138
versions to determine the latest version or match a [semantic version requirement][02].
139139
Where possible, resource and extension authors should follow semantic versioning for the
140140
best user experience.
141141
142-
When the version is an arbitrary string, DSC compares the strings
143-
[lexicographically][03]. Arbitrary string versions are only equivalent when they contain
144-
exactly the same characters - the comparison is case-sensitive. If you're defining a
145-
resource that doesn't follow semantic versioning, consider defining the version as an
146-
[ISO 8601 date][04], like `2026-01-15`. When you do, DSC can correctly determine that a
147-
later date should be treated as a newer version.
142+
When the version is defined as a valid [date version][03], DSC compares the dates to see
143+
which one is newer. Date versions are only equivalent when they define the same date and
144+
optional prerelease segment. Both versions must define or omit the prerelease segment. If
145+
the prerelease segment is defined, the segments must be identical - the comparison is
146+
case sensitive.
148147
149148
[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/semver
150-
[02]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/semverReq
151-
[03]: https://doc.rust-lang.org/std/cmp/trait.Ord.html#lexicographical-comparison
152-
[04]: https://www.iso.org/iso-8601-date-and-time-format.html
149+
[02]: https://learn.microsoft.com/en-us/powershell/dsc/concepts/defining-semver-reqs.md
150+
[03]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/dateVersion
153151
semanticVariant:
154152
title:
155153
en-us: Semantic resource version
@@ -167,36 +165,31 @@ schemas:
167165
168166
[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/semver
169167
[02]: https://semver.org
170-
arbitraryVariant:
168+
dateVariant:
171169
title:
172-
en-us: Arbitrary string resource version
170+
en-us: Date resource version
173171
description:
174172
en-us: >-
175-
Defines the resource's version as an arbitrary string.
173+
Defines the resource's version as a date version.
176174
deprecationMessage:
177175
en-us: >-
178-
Defining a resource version as an arbitrary string is supported only for compatibility
176+
Defining a resource version as a date version is supported only for compatibility
179177
purposes. If possible, define your resource version as a valid semantic version. For
180178
more information about defining a semantic version, see [semver.org](https://semver.org).
181179
markdownDescription:
182180
en-us: |-
183-
Defines the resource's version as an arbitrary string.
181+
Defines the resource's version as a date version.
184182
185-
DSC uses this variant for the version of any DSC resource that defines its version as a
186-
string that can't be parsed as a semantic version. This variant remains supported for
187-
compatibility purposes but is _not_ recommended for production usage.
183+
This variant remains supported for compatibility purposes but is _not_ recommended for
184+
production usage.
188185
189-
When a resource defines the version as an arbitrary string:
186+
When a resource defines the version as a date version:
190187
191-
1. You can only use exact match version requirements for that resource.
192-
1. When a resource defines the version as an arbitrary string, DSC uses Rust's
193-
[lexicographic comparison][01] logic to determine the "latest" version of the
194-
resource to use as the default version when no version requirement is specified.
188+
1. The resource only matches a resource version requirement that is defined as a date
189+
version when the date and optional prerelease segments are exactly the same. The
190+
comparison is case-sensitive for the prerelease segment.
195191
1. When DSC discovers a multiple manifests for a resource, DSC always treats
196-
semantically versioned resources as newer than resources with an arbitrary string
197-
version.
198-
199-
[01]: https://doc.rust-lang.org/std/cmp/trait.Ord.html#lexicographical-comparison
192+
semantically versioned resources as newer than resources with a date version.
200193
201194
resourceVersionReq:
202195
title:

lib/dsc-lib/src/dscerror.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ pub enum DscError {
140140
#[error("{t}: {0}", t = t!("dscerror.resourceManifestNotFound"))]
141141
ResourceManifestNotFound(String),
142142

143-
#[error("{t}: '{0}'", t = t!("dscerror.resourceVersionToSemverConversion"))]
144-
ResourceVersionToSemverConversion(String),
143+
#[error(transparent)]
144+
ResourceVersion(#[from] crate::types::ResourceVersionError),
145145

146146
#[error("{t}: '{0}'", t = t!("dscerror.resourceVersionReqToSemverConversion"))]
147147
ResourceVersionReqToSemverConversion(String),

lib/dsc-lib/src/types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use exit_codes_map::ExitCodesMap;
1010
mod fully_qualified_type_name;
1111
pub use fully_qualified_type_name::FullyQualifiedTypeName;
1212
mod resource_version;
13-
pub use resource_version::ResourceVersion;
13+
pub use resource_version::{ResourceVersion, ResourceVersionError};
1414
mod resource_version_req;
1515
pub use resource_version_req::ResourceVersionReq;
1616
mod semantic_version;

0 commit comments

Comments
 (0)