Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dsc/src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,12 +805,12 @@ pub fn list_resources(dsc: &mut DscManager, resource_name: Option<&String>, adap

// if tags is specified, skip if resource tags do not contain the tags
if let Some(tags) = tags {
let Some(manifest_tags) = &manifest.tags else { continue; };
if manifest.tags.is_empty() { continue; }

let mut found = false;
for tag_to_find in tags {
for tag in manifest_tags {
if tag.to_lowercase() == tag_to_find.to_lowercase() {
for tag in manifest.tags.as_ref() {
if tag == tag_to_find {
found = true;
break;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/dsc-lib/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@ forExecutable = "for executable"
function = "Function"
integerConversion = "Function integer argument conversion"
invalidConfiguration = "Invalid configuration"
invalidTagPrefix = "Invalid tag"
invalidTagSuffix = "valid tags must match the following pattern"
invalidTypeNamePrefix = "Invalid type name"
invalidTypeNameSuffix = "valid resource type names must match the following pattern"
unsupportedManifestVersion = "Unsupported manifest version"
Expand Down
71 changes: 70 additions & 1 deletion lib/dsc-lib/locales/schemas.definitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,73 @@ schemas:
en-us: >-
Invalid semantic version requirement. A semantic version requirement must define one or
more valid comparators. For more information, see
[Defining semantic version requirements](https://learn.microsoft.com/en-us/powershell/dsc/concepts/defining-semver-reqs.md)
[Defining semantic version requirements](https://learn.microsoft.com/en-us/powershell/dsc/concepts/defining-semver-reqs.md)

tag:
title:
en-us: Tag
description:
en-us: >-
Defines a short search term for a DSC resource or extension.
markdownDescription:
en-us: |-
Defines a short search term for a DSC resource or extension.

To help with discovery, DSC enables users to filter the list of available resources or
extensions by tags. DSC treats tags case-insensitively.

Define each tag as a non-empty string consisting of only unicode word characters. The
following list contains the valid character sets for a tag:

- `\p{alpha}` - All alphabetic characters, regardless of casing, use of marks, or script.
- `\p{gc=Mark}` - Characters that modify other characters
- `\p{digit}` - Characters `[0-9]`
- `\p{gc=Connector_Punctuation}` - Underscore (`_`) and similar characters
- `\p{Join_Control}` - characters that function for cursive joining and ligatures

A tag with any other characters, including spaces, is invalid.

For more information about unicode word characters, see
[Annex C: Compatibility property][01] in [Unicode Technical Standard #18][02].

[01]: https://www.unicode.org/reports/tr18/#Compatibility_Properties
[02]: https://www.unicode.org/reports/tr18
patternErrorMessage:
en-us: |-
Invalid tag. Tags must be non-empty strings consisting of only unicode word characters.

tags:
title:
en-us: Tag list
description:
en-us: >-
Defines a set of short search terms for a DSC resource or extension.
markdownDescription:
en-us: |-
Defines a set of short search terms for a DSC resource or extension.

To help with discovery, DSC enables users to filter the list of available resources or
extensions by tags. DSC treats tags case-insensitively.

Every tag in the list must be unique within the list. Defining a list with a repeated tag
is invalid. This schema will raise a validation error if you define an identical pair of
strings as list items, like `["macOS", "macOS"]`. However, due to limitations in the
expressiveness of JSON Schema, a list that defines the same tag with different casing
will pass JSON Schema validation, like `["MACOS", "macos", "macOS"]`. When DSC
deserializes that JSON array value, it only records the _first_ tag for any set of tags
that differ only by casing. Subsequent values are discarded.

For example, the following tag lists are functionally equivalent:

```yaml
tags: [apt, Linux]
---
tags: [apt, Linux, APT]
```

When DSC processes the second tag list, the uppercased `APT` is ignored.

Don't define the same tag, regardless of casing, more than once in any tag list. While
JSON Schema and DSC are _resilient_ for lists that repeat the same tag with different
casing, it is best practice to ensure that every tag in the list is unique regardless of
casing.
5 changes: 4 additions & 1 deletion lib/dsc-lib/src/dscerror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ pub enum DscError {
#[error("{t} '{0}': {1}", t = t!("dscerror.invalidRequiredVersion"))]
InvalidRequiredVersion(String, String),

#[error("{t} '{0}' - {t2}: '{1}'", t = t!("dscerror.invalidTypeNamePrefix"), t2 = t!("dscerror.InvalidTypeNameSuffix"))]
#[error("{t} '{0}' - {t2}: '{1}'", t = t!("dscerror.invalidTagPrefix"), t2 = t!("dscerror.invalidTagSuffix"))]
InvalidTag(String, String),

#[error("{t} '{0}' - {t2}: '{1}'", t = t!("dscerror.invalidTypeNamePrefix"), t2 = t!("dscerror.invalidTypeNameSuffix"))]
InvalidTypeName(String, String),

#[error("IO: {0}")]
Expand Down
5 changes: 3 additions & 2 deletions lib/dsc-lib/src/dscresources/resource_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::collections::HashMap;

use crate::{
schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum},
types::FullyQualifiedTypeName,
types::{FullyQualifiedTypeName, TagList},
};

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
Expand Down Expand Up @@ -56,7 +56,8 @@ pub struct ResourceManifest {
/// The description of the resource.
pub description: Option<String>,
/// Tags for the resource.
pub tags: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "TagList::is_empty")]
pub tags: TagList,
/// Details how to call the Get method of the resource.
pub get: Option<GetMethod>,
/// Details how to call the Set method of the resource.
Expand Down
5 changes: 3 additions & 2 deletions lib/dsc-lib/src/extensions/extension_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::collections::HashMap;
use crate::dscerror::DscError;
use crate::extensions::{discover::DiscoverMethod, import::ImportMethod, secret::SecretMethod};
use crate::schemas::dsc_repo::DscRepoSchema;
use crate::types::FullyQualifiedTypeName;
use crate::types::{FullyQualifiedTypeName, TagList};

#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -41,7 +41,8 @@ pub struct ExtensionManifest {
/// The description of the extension.
pub description: Option<String>,
/// Tags for the extension.
pub tags: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "TagList::is_empty")]
pub tags: TagList,
/// Details how to call the Discover method of the extension.
pub discover: Option<DiscoverMethod>,
/// Details how to call the Import method of the extension.
Expand Down
4 changes: 4 additions & 0 deletions lib/dsc-lib/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ mod semantic_version;
pub use semantic_version::SemanticVersion;
mod semantic_version_req;
pub use semantic_version_req::SemanticVersionReq;
mod tag;
pub use tag::Tag;
mod tag_list;
pub use tag_list::TagList;
Loading