Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sub-selector quantifiers #1423 #1525

Merged
Merged
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
10 changes: 3 additions & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,14 @@
"/ps-rule.yaml"
],
"./schemas/PSRule-language.schema.json": [
"/tests/PSRule.Tests/**.Rule.yaml",
"/tests/PSRule.Tests/**/**.Rule.yaml",
"/docs/scenarios/*/*.Rule.yaml",
"/docs/expressions/**/*.Rule.yaml"
"/**/**.Rule.yaml",
"/**/docs/scenarios/baselines/Baseline.rule.yaml"
]
},
"json.schemas": [
{
"fileMatch": [
"/tests/PSRule.Tests/**.Rule.jsonc",
"/tests/PSRule.Tests/**/**.Rule.jsonc",
"/docs/expressions/**/*.Rule.jsonc"
"/**/**.Rule.jsonc"
],
"url": "./schemas/PSRule-resources.schema.json"
}
Expand Down
8 changes: 8 additions & 0 deletions docs/CHANGELOG-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since pre-release v2.9.0-B0013:

- New features:
- Added sub-selector quantifiers for `allOf` or `anyOf` operators by @BernieWhite.
[#1423](https://github.com/microsoft/PSRule/issues/1423)
- Quantifiers allow you to specify the number of matches with `count`, `less`, `lessOrEqual`, `greater`, or `greaterOrEqual`.
- See [Sub-selectors][4] for more information.

## v2.9.0-B0013 (pre-release)

What's changed since release v2.8.1:
Expand Down
8 changes: 8 additions & 0 deletions docs/concepts/PSRule/en-US/about_PSRule_Expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ The `allOf` operator is used to require all nested expressions to match.
When any nested expression does not match, `allOf` does not match.
This is similar to a logical _and_ operation.

Additionally sub-selectors can be used to modify the `allOf` operator.
Sub-selectors allow filtering and looping through arrays of objects before the `allOf` operator is applied.
See sub-selectors for more information.

Syntax:

```yaml
Expand Down Expand Up @@ -121,6 +125,10 @@ The `anyOf` operator is used to require one or more nested expressions to match.
When any nested expression matches, `allOf` matches.
This is similar to a logical _or_ operation.

Additionally sub-selectors can be used to modify the `anyOf` operator.
Sub-selectors allow filtering and looping through arrays of objects before the `anyOf` operator is applied.
See sub-selectors for more information.

Syntax:

```yaml
Expand Down
6 changes: 6 additions & 0 deletions docs/expressions/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,9 @@ spec:
- string: '-'
- path: name
```

## Recommended content

- [Create a standalone rule](../quickstart/standalone-rule.md)
- [Expressions](../concepts/PSRule/en-US/about_PSRule_Expressions.md)
- [Sub-selectors](sub-selectors.md)
85 changes: 84 additions & 1 deletion docs/expressions/sub-selectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ In the example:

### When there are no results

Given the example, is important to understand what happens if:
Given the example, is important to understand what happens by default if:

- The `resources` property doesn't exist. **OR**
- The `resources` property doesn't contain any items that match the sub-selector condition.
Expand All @@ -196,6 +196,7 @@ If this was not the desired behavior, you could:

- Use a pre-condition to avoid running the rule.
- Group the sub-selector into a `anyOf`, and provide a secondary condition.
- Use a quantifier to determine how many items must match sub-selector and match the `allOf` / `anyOf` operator.

For example:

Expand Down Expand Up @@ -270,3 +271,85 @@ In the example:
- If the `resources` property exists but has 0 items of type `Microsoft.Web/sites/config`, the rule fails.
- If the `resources` property exists and has any items of type `Microsoft.Web/sites/config` but any fail, the rule fails.
- If the `resources` property exists and has any items of type `Microsoft.Web/sites/config` and all pass, the rule passes.

### Using a quantifier with sub-selectors

When iterating over a list of items, you may want to determine how many items must match.
A quantifier determines how many items in the list match.
Matching items must be:

- Selected by the sub-selector.
- Match the condition of the operator.

Supported quantifiers are:

- `count` — The number of items must equal then the specified value.
- `less` — The number of items must less then the specified value.
- `lessOrEqual` — The number of items must less or equal to the specified value.
- `greater` — The number of items must greater then the specified value.
- `greaterOrEqual` — The number of items must greater or equal to the specified value.

For example:

=== "YAML"

```yaml hl_lines="13"
---
# Synopsis: A rule with a sub-selector quantifier.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Yaml.Subselector.Quantifier
spec:
condition:
field: resources
where:
type: '.'
equals: 'Microsoft.Web/sites/config'
greaterOrEqual: 1
allOf:
- field: properties.detailedErrorLoggingEnabled
equals: true
```

=== "JSON"

```json hl_lines="15"
{
// Synopsis: A rule with a sub-selector quantifier.
"apiVersion": "github.com/microsoft/PSRule/v1",
"kind": "Rule",
"metadata": {
"name": "Json.Subselector.Quantifier"
},
"spec": {
"condition": {
"field": "resources",
"where": {
"type": ".",
"equals": "Microsoft.Web/sites/config"
},
"greaterOrEqual": 1,
"allOf": [
{
"field": "properties.detailedErrorLoggingEnabled",
"equals": true
}
]
}
}
}
```

In the example:

- If the array property `resources` exists, any items with a type of `Microsoft.Web/sites/config` are evaluated.
- Each item must have the `properties.detailedErrorLoggingEnabled` property set to `true` to pass.
- The number of items that pass must be greater or equal to `1`.
- If the `resources` property does not exist or is empty, the number of items is `0` which fails greater or equal to `1`.

## Recommended content

- [Create a standalone rule](../quickstart/standalone-rule.md)
- [Functions](functions.md)
- [Expressions](../concepts/PSRule/en-US/about_PSRule_Expressions.md)
Loading