зеркало из https://github.com/microsoft/PSRule.git
Родитель
93333d85ba
Коммит
2a9ef35711
|
@ -18,6 +18,20 @@
|
|||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Run Pester test group",
|
||||
"detail": "Runs a specific group for Pester tests.",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Test -AssertStyle Client -TestGroup '${input:pesterTestGroup}'",
|
||||
"group": "test",
|
||||
"problemMatcher": [
|
||||
"$pester"
|
||||
],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Analyze repository",
|
||||
"detail": "Run repository analysis.",
|
||||
|
@ -95,5 +109,12 @@
|
|||
"panel": "dedicated"
|
||||
}
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "pesterTestGroup",
|
||||
"type": "promptString",
|
||||
"description": "A group to use for Pester tests."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ See [upgrade notes][upgrade-notes] for helpful information when upgrading from p
|
|||
|
||||
## Unreleased
|
||||
|
||||
What's changed since pre-release v1.3.0-B2104042:
|
||||
|
||||
- Engine features:
|
||||
- Options can be configured with environment variables. [#691](https://github.com/microsoft/PSRule/issues/691)
|
||||
- See [about_PSRule_Options] for details.
|
||||
|
||||
## v1.3.0-B2104042 (pre-release)
|
||||
|
||||
What's changed since pre-release v1.3.0-B2104030:
|
||||
|
|
|
@ -147,6 +147,8 @@ spec: { }
|
|||
### Example Baseline.Rule.yaml
|
||||
|
||||
```yaml
|
||||
# Example Baseline.Rule.yaml
|
||||
|
||||
---
|
||||
# Synopsis: This is an example baseline
|
||||
apiVersion: github.com/microsoft/PSRule/v1
|
||||
|
@ -183,3 +185,10 @@ spec:
|
|||
configuration:
|
||||
key1: value1
|
||||
```
|
||||
|
||||
## KEYWORDS
|
||||
|
||||
- Options
|
||||
- PSRule
|
||||
- Baseline
|
||||
- Binding
|
||||
|
|
|
@ -118,7 +118,30 @@ If more than one of these files exist, the following order will be used to find
|
|||
- `psrule.yml`
|
||||
|
||||
We recommend only using lowercase characters as shown above.
|
||||
This is because not all operation systems treat case in the same way.
|
||||
This is because not all operating systems treat case in the same way.
|
||||
|
||||
Most options can be set using environment variables.
|
||||
When configuring environment variables we recommend that all capital letters are used.
|
||||
This is because environment variables are case-sensitive on some operating systems.
|
||||
|
||||
PSRule environment variables use a consistent naming pattern of `PSRULE_<PARENT>_<NAME>`.
|
||||
Where `<PARENT>` is the parent class and `<NAME>` is the specific option.
|
||||
For example:
|
||||
|
||||
- `Execution.InconclusiveWarning` is configured by `PSRULE_EXECUTION_INCONCLUSIVEWARNING`.
|
||||
- `Input.TargetType` is configured by `PSRULE_INPUT_TARGETTYPE`.
|
||||
- `Output.Format` is configured by `PSRULE_OUTPUT_FORMAT`.
|
||||
|
||||
When setting environment variables:
|
||||
|
||||
- Enum values are set by string.
|
||||
For example `PSRULE_OUTPUT_FORMAT` could be set to `Yaml`.
|
||||
Enum values are case-insensitive.
|
||||
- Boolean values are set by `true`, `false`, `1`, or `0`.
|
||||
For example `PSRULE_EXECUTION_INCONCLUSIVEWARNING` could be set to `false`.
|
||||
Boolean values are case-insensitive.
|
||||
- String array values can specify multiple items by using a semi-colon separator.
|
||||
For example `PSRULE_INPUT_TARGETTYPE` could be set to `virtualMachine;virtualNetwork`.
|
||||
|
||||
### Binding.Field
|
||||
|
||||
|
@ -197,6 +220,24 @@ binding:
|
|||
ignoreCase: false
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_IGNORECASE=false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_IGNORECASE: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_IGNORECASE
|
||||
value: false
|
||||
```
|
||||
|
||||
### Binding.NameSeparator
|
||||
|
||||
When an object is passed from the pipeline, PSRule assigns the object a _TargetName_.
|
||||
|
@ -234,6 +275,24 @@ binding:
|
|||
nameSeparator: '::'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_NAMESEPARATOR='::'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_NAMESEPARATOR: '::'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_NAMESEPARATOR
|
||||
value: '::'
|
||||
```
|
||||
|
||||
### Binding.PreferTargetInfo
|
||||
|
||||
Some built-in objects within PSRule perform automatic binding of TargetName and TargetType.
|
||||
|
@ -267,6 +326,24 @@ binding:
|
|||
preferTargetInfo: true
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_PREFERTARGETINFO=false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_PREFERTARGETINFO: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_PREFERTARGETINFO
|
||||
value: false
|
||||
```
|
||||
|
||||
### Binding.TargetName
|
||||
|
||||
When an object is passed from the pipeline, PSRule assigns the object a _TargetName_.
|
||||
|
@ -315,6 +392,24 @@ binding:
|
|||
- AlternateName
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_TARGETNAME='ResourceName;AlternateName'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_TARGETNAME: 'ResourceName;AlternateName'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_TARGETNAME
|
||||
value: 'ResourceName;AlternateName'
|
||||
```
|
||||
|
||||
To specify a custom binding function use:
|
||||
|
||||
```powershell
|
||||
|
@ -376,6 +471,24 @@ binding:
|
|||
- kind
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_TARGETTYPE='ResourceType;kind'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_TARGETTYPE: 'ResourceType;kind'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_TARGETTYPE
|
||||
value: 'ResourceType;kind'
|
||||
```
|
||||
|
||||
To specify a custom binding function use:
|
||||
|
||||
```powershell
|
||||
|
@ -433,9 +546,28 @@ binding:
|
|||
useQualifiedName: true
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_BINDING_USEQUALIFIEDNAME=false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_BINDING_USEQUALIFIEDNAME: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_BINDING_USEQUALIFIEDNAME
|
||||
value: false
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Configures a set of baseline configuration values that can be used in rule definitions instead of using hard coded values.
|
||||
Configures a set of baseline configuration values that can be used in rule definitions.
|
||||
Configuration values can be overridden at different scopes.
|
||||
|
||||
This option can be specified using:
|
||||
|
||||
|
@ -450,6 +582,27 @@ configuration:
|
|||
LOCAL_APPSERVICEMININSTANCECOUNT: 2
|
||||
```
|
||||
|
||||
Configuration values can be specified using environment variables.
|
||||
To specify a configuration value, prefix the configuration value with `PSRULE_CONFIGURATION_`.
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_CONFIGURATION_LOCAL_APPSERVICEMININSTANCECOUNT=2
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_CONFIGURATION_LOCAL_APPSERVICEMININSTANCECOUNT: '2'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_CONFIGURATION_LOCAL_APPSERVICEMININSTANCECOUNT
|
||||
value: '2'
|
||||
```
|
||||
|
||||
### Convention.Include
|
||||
|
||||
Specifies conventions to execute when the pipeline run.
|
||||
|
@ -480,6 +633,24 @@ convention:
|
|||
- 'Convention2'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_CONVENTION_INCLUDE='Convention1;Convention2'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_CONVENTION_INCLUDE: 'Convention1;Convention2'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_CONVENTION_INCLUDE
|
||||
value: 'Convention1;Convention2'
|
||||
```
|
||||
|
||||
### Execution.LanguageMode
|
||||
|
||||
Unless PowerShell has been constrained, full language features of PowerShell are available to use within rule definitions.
|
||||
|
@ -505,6 +676,24 @@ execution:
|
|||
languageMode: ConstrainedLanguage
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_EXECUTION_LANGUAGEMODE=ConstrainedLanguage
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_EXECUTION_LANGUAGEMODE: ConstrainedLanguage
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_EXECUTION_LANGUAGEMODE
|
||||
value: ConstrainedLanguage
|
||||
```
|
||||
|
||||
### Execution.InconclusiveWarning
|
||||
|
||||
When defining rules, it is possible not return a valid `$True` or `$False` result within the definition script block.
|
||||
|
@ -543,6 +732,24 @@ execution:
|
|||
inconclusiveWarning: false
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_EXECUTION_INCONCLUSIVEWARNING=false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_EXECUTION_INCONCLUSIVEWARNING: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_EXECUTION_INCONCLUSIVEWARNING
|
||||
value: false
|
||||
```
|
||||
|
||||
### Execution.NotProcessedWarning
|
||||
|
||||
When evaluating rules, it is possible to incorrectly select a path with rules that use pre-conditions that do not accept the pipeline object.
|
||||
|
@ -576,6 +783,24 @@ execution:
|
|||
notProcessedWarning: false
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_EXECUTION_NOTPROCESSEDWARNING=false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_EXECUTION_NOTPROCESSEDWARNING: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_EXECUTION_NOTPROCESSEDWARNING
|
||||
value: false
|
||||
```
|
||||
|
||||
### Input.Format
|
||||
|
||||
Configures the input format for when a string is passed in as a target object.
|
||||
|
@ -645,6 +870,24 @@ input:
|
|||
format: Yaml
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_INPUT_FORMAT=Yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_INPUT_FORMAT: Yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_INPUT_FORMAT
|
||||
value: Yaml
|
||||
```
|
||||
|
||||
### Input.ObjectPath
|
||||
|
||||
The object path to a property to use instead of the pipeline object.
|
||||
|
@ -680,6 +923,24 @@ input:
|
|||
objectPath: items
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_INPUT_OBJECTPATH=items
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_INPUT_OBJECTPATH: items
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_INPUT_OBJECTPATH
|
||||
value: items
|
||||
```
|
||||
|
||||
### Input.PathIgnore
|
||||
|
||||
Ignores input files that match the path spec when using `-InputPath`.
|
||||
|
@ -710,6 +971,24 @@ input:
|
|||
- '*.Designer.cs'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_INPUT_PATHIGNORE=*.Designer.cs
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_INPUT_PATHIGNORE: '*.Designer.cs'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_INPUT_PATHIGNORE
|
||||
value: '*.Designer.cs'
|
||||
```
|
||||
|
||||
### Input.TargetType
|
||||
|
||||
Filters input objects by TargetType.
|
||||
|
@ -728,17 +1007,17 @@ This option can be specified using:
|
|||
|
||||
```powershell
|
||||
# PowerShell: Using the InputTargetType parameter
|
||||
$option = New-PSRuleOption -InputTargetType 'virtualMachine';
|
||||
$option = New-PSRuleOption -InputTargetType 'virtualMachine', 'virtualNetwork';
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell: Using the Input.TargetType hashtable key
|
||||
$option = New-PSRuleOption -Option @{ 'Input.TargetType' = 'virtualMachine' };
|
||||
$option = New-PSRuleOption -Option @{ 'Input.TargetType' = 'virtualMachine', 'virtualNetwork' };
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell: Using the InputTargetType parameter to set YAML
|
||||
Set-PSRuleOption -InputTargetType 'virtualMachine';
|
||||
Set-PSRuleOption -InputTargetType 'virtualMachine', 'virtualNetwork';
|
||||
```
|
||||
|
||||
```yaml
|
||||
|
@ -748,6 +1027,24 @@ input:
|
|||
- virtualMachine
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_INPUT_TARGETTYPE=virtualMachine;virtualNetwork
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_INPUT_TARGETTYPE: virtualMachine;virtualNetwork
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_INPUT_TARGETTYPE
|
||||
value: virtualMachine;virtualNetwork
|
||||
```
|
||||
|
||||
### Logging.LimitDebug
|
||||
|
||||
Limits debug messages to a list of named debug scopes.
|
||||
|
@ -942,6 +1239,24 @@ output:
|
|||
as: Summary
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_AS=Summary
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_AS: Summary
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_AS
|
||||
value: Summary
|
||||
```
|
||||
|
||||
### Output.Culture
|
||||
|
||||
Specified the name of one or more cultures to use for generating output.
|
||||
|
@ -976,6 +1291,24 @@ output:
|
|||
culture: [ 'en-AU', 'en-US' ]
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_CULTURE=en-AU;en-US
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_CULTURE: en-AU;en-US
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_CULTURE
|
||||
value: en-AU;en-US
|
||||
```
|
||||
|
||||
### Output.Encoding
|
||||
|
||||
Configures the encoding used when output is written to file.
|
||||
|
@ -1013,6 +1346,24 @@ output:
|
|||
encoding: UTF8
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_ENCODING=UTF8
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_ENCODING: UTF8
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_ENCODING
|
||||
value: UTF8
|
||||
```
|
||||
|
||||
### Output.Format
|
||||
|
||||
Configures the format that results will be presented in.
|
||||
|
@ -1059,6 +1410,24 @@ output:
|
|||
format: Yaml
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_FORMAT=Yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_FORMAT: Yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_FORMAT
|
||||
value: Yaml
|
||||
```
|
||||
|
||||
### Output.Outcome
|
||||
|
||||
Filters output to include results with the specified outcome.
|
||||
|
@ -1095,6 +1464,24 @@ output:
|
|||
outcome: 'Fail'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_OUTCOME=Fail
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_OUTCOME: Fail
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_OUTCOME
|
||||
value: Fail
|
||||
```
|
||||
|
||||
### Output.Path
|
||||
|
||||
Specifies the output file path to write results.
|
||||
|
@ -1127,6 +1514,24 @@ output:
|
|||
path: 'out/results.yaml'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_PATH=out/results.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_PATH: out/results.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_PATH
|
||||
value: out/results.yaml
|
||||
```
|
||||
|
||||
### Output.Style
|
||||
|
||||
Configures the style that results will be presented in.
|
||||
|
@ -1165,6 +1570,24 @@ output:
|
|||
style: AzurePipelines
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_OUTPUT_STYLE=AzurePipelines
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_OUTPUT_STYLE: AzurePipelines
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_OUTPUT_STYLE
|
||||
value: AzurePipelines
|
||||
```
|
||||
|
||||
### Requires
|
||||
|
||||
Specifies module version constraints for running PSRule.
|
||||
|
@ -1191,6 +1614,32 @@ requires:
|
|||
PSRule.Rules.Azure: '>=1.0.0' # Require v1.0.0 or greater.
|
||||
```
|
||||
|
||||
This option can be configured using environment variables.
|
||||
To specify a module version constraint, prefix the module name with `PSRULE_REQUIRES_`.
|
||||
When the module name includes a dot (`.`) use an underscore (`_`) instead.
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_REQUIRES_PSRULE='>=1.0.0'
|
||||
export PSRULE_REQUIRES_PSRULE_RULES_AZURE='>=1.0.0'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_REQUIRES_PSRULE: '>=1.0.0'
|
||||
PSRULE_REQUIRES_PSRULE_RULES_AZURE: '>=1.0.0'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_REQUIRES_PSRULE
|
||||
value: '>=1.0.0'
|
||||
- name: PSRULE_REQUIRES_PSRULE_RULES_AZURE
|
||||
value: '>=1.0.0'
|
||||
```
|
||||
|
||||
### Rule.Include
|
||||
|
||||
The name of specific rules to evaluate.
|
||||
|
@ -1209,8 +1658,26 @@ $option = New-PSRuleOption -Option @{ 'Rule.Include' = 'Rule1','Rule2' };
|
|||
# YAML: Using the rule/include property
|
||||
rule:
|
||||
include:
|
||||
- rule1
|
||||
- rule2
|
||||
- Rule1
|
||||
- Rule2
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_RULE_INCLUDE='Rule1;Rule2'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_RULE_INCLUDE: 'Rule1;Rule2'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_RULE_INCLUDE
|
||||
value: 'Rule1;Rule2'
|
||||
```
|
||||
|
||||
### Rule.Exclude
|
||||
|
@ -1229,8 +1696,26 @@ $option = New-PSRuleOption -Option @{ 'Rule.Exclude' = 'Rule3','Rule4' };
|
|||
# YAML: Using the rule/exclude property
|
||||
rule:
|
||||
exclude:
|
||||
- rule3
|
||||
- rule4
|
||||
- Rule3
|
||||
- Rule4
|
||||
```
|
||||
|
||||
```bash
|
||||
# Bash: Using environment variable
|
||||
export PSRULE_RULE_EXCLUDE='Rule3;Rule4'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# GitHub Actions: Using environment variable
|
||||
env:
|
||||
PSRULE_RULE_EXCLUDE: 'Rule3;Rule4'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Azure Pipelines: Using environment variable
|
||||
variables:
|
||||
- name: PSRULE_RULE_EXCLUDE
|
||||
value: 'Rule3;Rule4'
|
||||
```
|
||||
|
||||
### Rule.Tag
|
||||
|
|
|
@ -117,13 +117,14 @@ Similarly, when including baselines within a module use the `.Rule.yaml` suffix.
|
|||
|
||||
## Defining a module configuration
|
||||
|
||||
A module configuration that sets options defaults can be optionally packaged with a module.
|
||||
A module configuration that sets options defaults and can be optionally packaged with a module.
|
||||
To set a module configuration, define a `ModuleConfig` resource within an included `.Rule.yaml` file.
|
||||
A module configuration `.Rule.yaml` file must be distributed within the module directory structure.
|
||||
|
||||
PSRule only supports a single `ModuleConfig` resource.
|
||||
The name of the `ModuleConfig` must match the name of the module.
|
||||
Additional `ModuleConfig` resources or with an alternative name are ignored.
|
||||
PSRule does not support module configurations distributed outside of a module.
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
@ -154,6 +155,7 @@ The following options are allowed within a `ModuleConfig`:
|
|||
- `Binding.Field`
|
||||
- `Binding.IgnoreCase`
|
||||
- `Binding.NameSeparator`
|
||||
- `Binding.PreferTargetInfo`
|
||||
- `Binding.TargetName`
|
||||
- `Binding.TargetType`
|
||||
- `Binding.UseQualifiedName`
|
||||
|
|
|
@ -22,7 +22,10 @@ param (
|
|||
[String]$ArtifactPath = (Join-Path -Path $PWD -ChildPath out/modules),
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$AssertStyle = 'AzurePipelines'
|
||||
[String]$AssertStyle = 'AzurePipelines',
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$TestGroup = $Null
|
||||
)
|
||||
|
||||
Write-Host -Object "[Pipeline] -- PowerShell v$($PSVersionTable.PSVersion.ToString())" -ForegroundColor Green;
|
||||
|
@ -274,6 +277,10 @@ task TestModule Pester, PSScriptAnalyzer, {
|
|||
$Null = New-Item -Path reports -ItemType Directory -Force;
|
||||
}
|
||||
|
||||
if ($Null -ne $TestGroup) {
|
||||
$pesterParams['Tags'] = $TestGroup;
|
||||
}
|
||||
|
||||
$results = Invoke-Pester @pesterParams;
|
||||
|
||||
# Throw an error if pester tests failed
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace PSRule
|
||||
{
|
||||
|
@ -32,7 +32,33 @@ namespace PSRule
|
|||
public static bool TryPopBool(this IDictionary<string, object> dictionary, string key, out bool value)
|
||||
{
|
||||
value = default;
|
||||
return dictionary.TryGetValue(key, out object v) && dictionary.Remove(key) && bool.TryParse(v.ToString(), out value);
|
||||
return TryPopValue(dictionary, key, out object v) && bool.TryParse(v.ToString(), out value);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static bool TryPopEnum<TEnum>(this IDictionary<string, object> dictionary, string key, out TEnum value) where TEnum : struct
|
||||
{
|
||||
value = default;
|
||||
return TryPopValue(dictionary, key, out object v) && Enum.TryParse(v.ToString(), ignoreCase: true, result: out value);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static bool TryPopString(this IDictionary<string, object> dictionary, string key, out string value)
|
||||
{
|
||||
value = default;
|
||||
if (TryPopValue(dictionary, key, out object v) && v is string svalue)
|
||||
{
|
||||
value = svalue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static bool TryPopStringArray(this IDictionary<string, object> dictionary, string key, out string[] value)
|
||||
{
|
||||
value = default;
|
||||
return TryPopValue(dictionary, key, out object v) && TryStringArray(v, out value);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
|
@ -87,5 +113,16 @@ namespace PSRule
|
|||
if (!dictionary.ContainsKey(kv.Key))
|
||||
dictionary.Add(kv.Key, kv.Value);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
private static bool TryStringArray(object o, out string[] value)
|
||||
{
|
||||
value = default;
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
value = o.GetType().IsArray ? ((object[])o).OfType<string>().ToArray() : new string[] { o.ToString() };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Security;
|
||||
|
||||
namespace PSRule
|
||||
{
|
||||
internal static class EnvironmentHelper
|
||||
internal sealed class EnvironmentHelper
|
||||
{
|
||||
private const char UNDERSCORE = '_';
|
||||
private readonly static char[] STRINGARRAY_SEPARATOR = new char[] { ';' };
|
||||
|
||||
internal static bool TryString(string key, out string value)
|
||||
public static readonly EnvironmentHelper Default = new EnvironmentHelper();
|
||||
|
||||
internal bool TryString(string key, out string value)
|
||||
{
|
||||
value = null;
|
||||
var variable = System.Environment.GetEnvironmentVariable(key);
|
||||
if (string.IsNullOrEmpty(variable))
|
||||
return false;
|
||||
|
||||
value = variable;
|
||||
return true;
|
||||
return TryVariable(key, out value) && !string.IsNullOrEmpty(value);
|
||||
}
|
||||
|
||||
internal static bool TrySecureString(string key, out SecureString value)
|
||||
internal bool TrySecureString(string key, out SecureString value)
|
||||
{
|
||||
value = null;
|
||||
if (!TryString(key, out string variable))
|
||||
|
@ -31,27 +30,68 @@ namespace PSRule
|
|||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryInt(string key, out int value)
|
||||
internal bool TryInt(string key, out int value)
|
||||
{
|
||||
var variable = System.Environment.GetEnvironmentVariable(key);
|
||||
if (!int.TryParse(variable, out value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
value = default;
|
||||
return TryVariable(key, out string variable) && int.TryParse(variable, out value);
|
||||
}
|
||||
|
||||
internal static bool TryBool(string key, out bool value)
|
||||
internal bool TryBool(string key, out bool value)
|
||||
{
|
||||
var variable = System.Environment.GetEnvironmentVariable(key);
|
||||
if (!bool.TryParse(variable, out value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
value = default;
|
||||
return TryVariable(key, out string variable) && TryParseBool(variable, out value);
|
||||
}
|
||||
|
||||
private static string CombineKey(string prefix, string key)
|
||||
internal bool TryEnum<TEnum>(string key, out TEnum value) where TEnum : struct
|
||||
{
|
||||
return string.IsNullOrEmpty(prefix) ? key : string.Concat(prefix, UNDERSCORE, key);
|
||||
value = default;
|
||||
if (!TryVariable(key, out string variable))
|
||||
return false;
|
||||
|
||||
return Enum.TryParse(variable, ignoreCase: true, out value);
|
||||
}
|
||||
|
||||
internal bool TryStringArray(string key, out string[] value)
|
||||
{
|
||||
value = default;
|
||||
if (!TryVariable(key, out string variable))
|
||||
return false;
|
||||
|
||||
value = variable.Split(STRINGARRAY_SEPARATOR, options: StringSplitOptions.RemoveEmptyEntries);
|
||||
return value != null;
|
||||
}
|
||||
|
||||
private bool TryVariable(string key, out string variable)
|
||||
{
|
||||
variable = Environment.GetEnvironmentVariable(key);
|
||||
return variable != null;
|
||||
}
|
||||
|
||||
private static bool TryParseBool(string variable, out bool value)
|
||||
{
|
||||
if (bool.TryParse(variable, out value))
|
||||
return true;
|
||||
|
||||
if (int.TryParse(variable, out int ivalue))
|
||||
{
|
||||
value = ivalue > 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal IEnumerable<KeyValuePair<string, object>> WithPrefix(string prefix)
|
||||
{
|
||||
var env = Environment.GetEnvironmentVariables();
|
||||
var enumerator = env.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var key = enumerator.Key.ToString();
|
||||
if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
yield return new KeyValuePair<string, object>(key, enumerator.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ namespace PSRule
|
|||
public static string GetHeadRef(string path)
|
||||
{
|
||||
// Try PSRule
|
||||
if (EnvironmentHelper.TryString("PSRULE_GITREF", out string value))
|
||||
if (EnvironmentHelper.Default.TryString("PSRULE_GITREF", out string value))
|
||||
return value;
|
||||
|
||||
// Try Azure Pipelines
|
||||
if (EnvironmentHelper.TryString("BUILD_SOURCEBRANCH", out value))
|
||||
if (EnvironmentHelper.Default.TryString("BUILD_SOURCEBRANCH", out value))
|
||||
return value;
|
||||
|
||||
// Try GitHub Actions
|
||||
if (EnvironmentHelper.TryString("GITHUB_REF", out value))
|
||||
if (EnvironmentHelper.Default.TryString("GITHUB_REF", out value))
|
||||
return value;
|
||||
|
||||
// Try .git/HEAD
|
||||
|
|
|
@ -108,6 +108,9 @@ namespace PSRule
|
|||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load options from a hashtable.
|
||||
/// </summary>
|
||||
protected void Load(Hashtable hashtable)
|
||||
{
|
||||
if (hashtable == null)
|
||||
|
@ -117,6 +120,29 @@ namespace PSRule
|
|||
_Map.Add(entry.Key.ToString(), (TValue)entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load options from environment variables.
|
||||
/// </summary>
|
||||
internal void Load(string prefix, EnvironmentHelper env, Func<string, string> format = null)
|
||||
{
|
||||
if (env == null)
|
||||
throw new ArgumentNullException(nameof(env));
|
||||
|
||||
foreach (var variable in env.WithPrefix(prefix))
|
||||
{
|
||||
if (TryKeyPrefix(variable.Key, prefix, out string suffix))
|
||||
{
|
||||
if (format != null)
|
||||
suffix = format(suffix);
|
||||
|
||||
_Map[suffix] = (TValue)variable.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load options from a dictionary.
|
||||
/// </summary>
|
||||
protected void Load(string prefix, IDictionary<string, object> dictionary)
|
||||
{
|
||||
if (dictionary == null)
|
||||
|
@ -133,6 +159,9 @@ namespace PSRule
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try a key prefix.
|
||||
/// </summary>
|
||||
private static bool TryKeyPrefix(string key, string prefix, out string suffix)
|
||||
{
|
||||
suffix = key;
|
||||
|
|
|
@ -65,6 +65,40 @@ namespace PSRule.Configuration
|
|||
return new BaselineRef(value);
|
||||
}
|
||||
|
||||
internal static void Load(IBaselineSpec option, EnvironmentHelper env)
|
||||
{
|
||||
// Binding.Field - currently not supported
|
||||
|
||||
if (env.TryBool("PSRULE_BINDING_IGNORECASE", out bool ignoreCase))
|
||||
option.Binding.IgnoreCase = ignoreCase;
|
||||
|
||||
if (env.TryString("PSRULE_BINDING_NAMESEPARATOR", out string nameSeparator))
|
||||
option.Binding.NameSeparator = nameSeparator;
|
||||
|
||||
if (env.TryBool("PSRULE_BINDING_PREFERTARGETINFO", out bool preferTargetInfo))
|
||||
option.Binding.PreferTargetInfo = preferTargetInfo;
|
||||
|
||||
if (env.TryStringArray("PSRULE_BINDING_TARGETNAME", out string[] targetName))
|
||||
option.Binding.TargetName = targetName;
|
||||
|
||||
if (env.TryStringArray("PSRULE_BINDING_TARGETTYPE", out string[] targetType))
|
||||
option.Binding.TargetType = targetType;
|
||||
|
||||
if (env.TryBool("PSRULE_BINDING_USEQUALIFIEDNAME", out bool useQualifiedName))
|
||||
option.Binding.UseQualifiedName = useQualifiedName;
|
||||
|
||||
if (env.TryStringArray("PSRULE_RULE_INCLUDE", out string[] include))
|
||||
option.Rule.Include = include;
|
||||
|
||||
if (env.TryStringArray("PSRULE_RULE_EXCLUDE", out string[] exclude))
|
||||
option.Rule.Exclude = exclude;
|
||||
|
||||
// Rule.Tag - currently not supported
|
||||
|
||||
// Process configuration values
|
||||
option.Configuration.Load(env);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load matching values
|
||||
/// </summary>
|
||||
|
@ -75,46 +109,29 @@ namespace PSRule.Configuration
|
|||
if (properties.TryPopValue("Binding.Field", out Hashtable map))
|
||||
option.Binding.Field = new FieldMap(map);
|
||||
|
||||
if (properties.TryPopBool("Binding.IgnoreCase", out bool bvalue))
|
||||
option.Binding.IgnoreCase = bvalue;
|
||||
if (properties.TryPopBool("Binding.IgnoreCase", out bool ignoreCase))
|
||||
option.Binding.IgnoreCase = ignoreCase;
|
||||
|
||||
if (properties.TryPopBool("Binding.PreferTargetInfo", out bvalue))
|
||||
option.Binding.PreferTargetInfo = bvalue;
|
||||
if (properties.TryPopString("Binding.NameSeparator", out string nameSeparator))
|
||||
option.Binding.NameSeparator = nameSeparator;
|
||||
|
||||
if (properties.TryPopValue("Binding.NameSeparator", out object value))
|
||||
option.Binding.NameSeparator = value.ToString();
|
||||
if (properties.TryPopBool("Binding.PreferTargetInfo", out bool preferTargetInfo))
|
||||
option.Binding.PreferTargetInfo = preferTargetInfo;
|
||||
|
||||
if (properties.TryPopValue("Binding.TargetName", out value))
|
||||
{
|
||||
if (value.GetType().IsArray)
|
||||
option.Binding.TargetName = ((object[])value).OfType<string>().ToArray();
|
||||
else
|
||||
option.Binding.TargetName = new string[] { value.ToString() };
|
||||
}
|
||||
if (properties.TryPopValue("Binding.targettype", out value))
|
||||
{
|
||||
if (value.GetType().IsArray)
|
||||
option.Binding.TargetType = ((object[])value).OfType<string>().ToArray();
|
||||
else
|
||||
option.Binding.TargetType = new string[] { value.ToString() };
|
||||
}
|
||||
if (properties.TryPopValue("Binding.UseQualifiedName", out bvalue))
|
||||
option.Binding.UseQualifiedName = bvalue;
|
||||
if (properties.TryPopStringArray("Binding.TargetName", out string[] targetName))
|
||||
option.Binding.TargetName = targetName;
|
||||
|
||||
if (properties.TryPopStringArray("Binding.TargetType", out string[] targetType))
|
||||
option.Binding.TargetType = targetType;
|
||||
|
||||
if (properties.TryPopValue("Binding.UseQualifiedName", out bool useQualifiedName))
|
||||
option.Binding.UseQualifiedName = useQualifiedName;
|
||||
|
||||
if (properties.TryPopStringArray("Rule.Include", out string[] include))
|
||||
option.Rule.Include = include;
|
||||
if (properties.TryPopStringArray("Rule.Exclude", out string[] exclude))
|
||||
option.Rule.Exclude = exclude;
|
||||
|
||||
if (properties.TryPopValue("Rule.Include", out value))
|
||||
{
|
||||
if (value.GetType().IsArray)
|
||||
option.Rule.Include = ((object[])value).OfType<string>().ToArray();
|
||||
else
|
||||
option.Rule.Include = new string[] { value.ToString() };
|
||||
}
|
||||
if (properties.TryPopValue("Rule.Exclude", out value))
|
||||
{
|
||||
if (value.GetType().IsArray)
|
||||
option.Rule.Exclude = ((object[])value).OfType<string>().ToArray();
|
||||
else
|
||||
option.Rule.Exclude = new string[] { value.ToString() };
|
||||
}
|
||||
if (properties.TryPopValue("Rule.Tag", out Hashtable tag))
|
||||
option.Rule.Tag = tag;
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ namespace PSRule.Configuration
|
|||
/// </summary>
|
||||
public sealed class ConfigurationOption : KeyMapDictionary<object>
|
||||
{
|
||||
private const string KEYMAP_PREFIX = "Configuration.";
|
||||
private const string ENVIRONMENT_PREFIX = "PSRULE_CONFIGURATION_";
|
||||
private const string DICTIONARY_PREFIX = "Configuration.";
|
||||
|
||||
public ConfigurationOption()
|
||||
: base() { }
|
||||
|
@ -34,9 +35,14 @@ namespace PSRule.Configuration
|
|||
return result;
|
||||
}
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
base.Load(ENVIRONMENT_PREFIX, env);
|
||||
}
|
||||
|
||||
internal void Load(IDictionary<string, object> dictionary)
|
||||
{
|
||||
base.Load(KEYMAP_PREFIX, dictionary);
|
||||
base.Load(DICTIONARY_PREFIX, dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace PSRule.Configuration
|
||||
|
@ -61,5 +62,17 @@ namespace PSRule.Configuration
|
|||
|
||||
[DefaultValue(null)]
|
||||
public string[] Include { get; set; }
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
if (env.TryStringArray("PSRULE_CONVENTION_INCLUDE", out string[] include))
|
||||
Include = include;
|
||||
}
|
||||
|
||||
internal void Load(Dictionary<string, object> index)
|
||||
{
|
||||
if (index.TryPopStringArray("Convention.Include", out string[] include))
|
||||
Include = include;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace PSRule.Configuration
|
||||
|
@ -80,5 +81,29 @@ namespace PSRule.Configuration
|
|||
|
||||
[DefaultValue(null)]
|
||||
public bool? NotProcessedWarning { get; set; }
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
if (env.TryEnum("PSRULE_EXECUTION_LANGUAGEMODE", out LanguageMode languageMode))
|
||||
LanguageMode = languageMode;
|
||||
|
||||
if (env.TryBool("PSRULE_EXECUTION_INCONCLUSIVEWARNING", out bool bvalue))
|
||||
InconclusiveWarning = bvalue;
|
||||
|
||||
if (env.TryBool("PSRULE_EXECUTION_NOTPROCESSEDWARNING", out bvalue))
|
||||
NotProcessedWarning = bvalue;
|
||||
}
|
||||
|
||||
internal void Load(Dictionary<string, object> index)
|
||||
{
|
||||
if (index.TryPopEnum("Execution.LanguageMode", out LanguageMode languageMode))
|
||||
LanguageMode = languageMode;
|
||||
|
||||
if (index.TryPopBool("Execution.InconclusiveWarning", out bool bvalue))
|
||||
InconclusiveWarning = bvalue;
|
||||
|
||||
if (index.TryPopBool("Execution.NotProcessedWarning", out bvalue))
|
||||
NotProcessedWarning = bvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace PSRule.Configuration
|
||||
|
@ -105,5 +106,35 @@ namespace PSRule.Configuration
|
|||
/// </summary>
|
||||
[DefaultValue(null)]
|
||||
public string[] TargetType { get; set; }
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
if (env.TryEnum("PSRULE_INPUT_FORMAT", out InputFormat format))
|
||||
Format = format;
|
||||
|
||||
if (env.TryString("PSRULE_INPUT_OBJECTPATH", out string objectPath))
|
||||
ObjectPath = objectPath;
|
||||
|
||||
if (env.TryStringArray("PSRULE_INPUT_PATHIGNORE", out string[] pathIgnore))
|
||||
PathIgnore = pathIgnore;
|
||||
|
||||
if (env.TryStringArray("PSRULE_INPUT_TARGETTYPE", out string[] targetType))
|
||||
TargetType = targetType;
|
||||
}
|
||||
|
||||
internal void Load(Dictionary<string, object> index)
|
||||
{
|
||||
if (index.TryPopEnum("Input.Format", out InputFormat format))
|
||||
Format = format;
|
||||
|
||||
if (index.TryPopString("Input.ObjectPath", out string objectPath))
|
||||
ObjectPath = objectPath;
|
||||
|
||||
if (index.TryPopStringArray("Input.PathIgnore", out string[] pathIgnore))
|
||||
PathIgnore = pathIgnore;
|
||||
|
||||
if (index.TryPopStringArray("Input.TargetType", out string[] targetType))
|
||||
TargetType = targetType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace PSRule.Configuration
|
||||
|
@ -103,5 +104,35 @@ namespace PSRule.Configuration
|
|||
/// </summary>
|
||||
[DefaultValue(null)]
|
||||
public OutcomeLogStream? RulePass { get; set; }
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
if (env.TryStringArray("PSRULE_LOGGING_LIMITDEBUG", out string[] limitDebug))
|
||||
LimitDebug = limitDebug;
|
||||
|
||||
if (env.TryStringArray("PSRULE_LOGGING_LIMITVERBOSE", out string[] limitVerbose))
|
||||
LimitVerbose = limitVerbose;
|
||||
|
||||
if (env.TryEnum("PSRULE_LOGGING_RULEFAIL", out OutcomeLogStream ruleFail))
|
||||
RuleFail = ruleFail;
|
||||
|
||||
if (env.TryEnum("PSRULE_LOGGING_RULEPASS", out OutcomeLogStream rulePass))
|
||||
RulePass = rulePass;
|
||||
}
|
||||
|
||||
internal void Load(Dictionary<string, object> index)
|
||||
{
|
||||
if (index.TryPopStringArray("Logging.LimitDebug", out string[] limitDebug))
|
||||
LimitDebug = limitDebug;
|
||||
|
||||
if (index.TryPopStringArray("Logging.LimitVerbose", out string[] limitVerbose))
|
||||
LimitVerbose = limitVerbose;
|
||||
|
||||
if (index.TryPopEnum("Logging.RuleFail", out OutcomeLogStream ruleFail))
|
||||
RuleFail = ruleFail;
|
||||
|
||||
if (index.TryPopEnum("Logging.RulePass", out OutcomeLogStream rulePass))
|
||||
RulePass = rulePass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using PSRule.Rules;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace PSRule.Configuration
|
||||
|
@ -131,5 +132,53 @@ namespace PSRule.Configuration
|
|||
|
||||
[DefaultValue(null)]
|
||||
public OutputStyle? Style { get; set; }
|
||||
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
if (env.TryEnum("PSRULE_OUTPUT_AS", out ResultFormat value))
|
||||
As = value;
|
||||
|
||||
if (env.TryStringArray("PSRULE_OUTPUT_CULTURE", out string[] culture))
|
||||
Culture = culture;
|
||||
|
||||
if (env.TryEnum("PSRULE_OUTPUT_ENCODING", out OutputEncoding encoding))
|
||||
Encoding = encoding;
|
||||
|
||||
if (env.TryEnum("PSRULE_OUTPUT_FORMAT", out OutputFormat format))
|
||||
Format = format;
|
||||
|
||||
if (env.TryEnum("PSRULE_OUTPUT_OUTCOME", out RuleOutcome outcome))
|
||||
Outcome = outcome;
|
||||
|
||||
if (env.TryString("PSRULE_OUTPUT_PATH", out string path))
|
||||
Path = path;
|
||||
|
||||
if (env.TryEnum("PSRULE_OUTPUT_STYLE", out OutputStyle style))
|
||||
Style = style;
|
||||
}
|
||||
|
||||
internal void Load(Dictionary<string, object> index)
|
||||
{
|
||||
if (index.TryPopEnum("Output.As", out ResultFormat value))
|
||||
As = value;
|
||||
|
||||
if (index.TryPopStringArray("Output.Culture", out string[] culture))
|
||||
Culture = culture;
|
||||
|
||||
if (index.TryPopEnum("Output.Encoding", out OutputEncoding encoding))
|
||||
Encoding = encoding;
|
||||
|
||||
if (index.TryPopEnum("Output.Format", out OutputFormat format))
|
||||
Format = format;
|
||||
|
||||
if (index.TryPopEnum("Output.Outcome", out RuleOutcome outcome))
|
||||
Outcome = outcome;
|
||||
|
||||
if (index.TryPopString("Output.Path", out string path))
|
||||
Path = path;
|
||||
|
||||
if (index.TryPopEnum("Output.Style", out OutputStyle style))
|
||||
Style = style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
using Newtonsoft.Json;
|
||||
using PSRule.Definitions;
|
||||
using PSRule.Resources;
|
||||
using PSRule.Rules;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using YamlDotNet.Serialization;
|
||||
|
@ -207,7 +205,7 @@ namespace PSRule.Configuration
|
|||
if (!File.Exists(filePath))
|
||||
throw new FileNotFoundException(PSRuleResources.OptionsNotFound, filePath);
|
||||
|
||||
return FromYaml(path: filePath, yaml: File.ReadAllText(filePath));
|
||||
return FromEnvironment(FromYaml(path: filePath, yaml: File.ReadAllText(filePath)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -227,7 +225,7 @@ namespace PSRule.Configuration
|
|||
if (!File.Exists(filePath))
|
||||
return new PSRuleOption();
|
||||
|
||||
return FromYaml(path: filePath, yaml: File.ReadAllText(filePath));
|
||||
return FromEnvironment(FromYaml(path: filePath, yaml: File.ReadAllText(filePath)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -255,11 +253,47 @@ namespace PSRule.Configuration
|
|||
.WithTypeConverter(new FieldMapYamlTypeConverter())
|
||||
.WithTypeConverter(new SuppressionRuleYamlTypeConverter())
|
||||
.Build();
|
||||
|
||||
var option = d.Deserialize<PSRuleOption>(yaml) ?? new PSRuleOption();
|
||||
option.SourcePath = path;
|
||||
return option;
|
||||
}
|
||||
|
||||
private static PSRuleOption FromEnvironment(PSRuleOption option)
|
||||
{
|
||||
if (option == null)
|
||||
option = new PSRuleOption();
|
||||
|
||||
// Start loading matching values
|
||||
var env = EnvironmentHelper.Default;
|
||||
option.Convention.Load(env);
|
||||
option.Execution.Load(env);
|
||||
option.Input.Load(env);
|
||||
option.Logging.Load(env);
|
||||
option.Output.Load(env);
|
||||
option.Requires.Load(env);
|
||||
BaselineOption.Load(option, env);
|
||||
return option;
|
||||
}
|
||||
|
||||
public static PSRuleOption FromHashtable(Hashtable hashtable)
|
||||
{
|
||||
var option = new PSRuleOption();
|
||||
if (hashtable == null)
|
||||
return option;
|
||||
|
||||
// Start loading matching values
|
||||
var index = BuildIndex(hashtable);
|
||||
option.Convention.Load(index);
|
||||
option.Execution.Load(index);
|
||||
option.Input.Load(index);
|
||||
option.Logging.Load(index);
|
||||
option.Output.Load(index);
|
||||
option.Requires.Load(index);
|
||||
BaselineOption.Load(option, index);
|
||||
return option;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set working path from PowerShell host environment.
|
||||
/// </summary>
|
||||
|
@ -277,11 +311,13 @@ namespace PSRule.Configuration
|
|||
_GetWorkingPath = () => executionContext.SessionState.Path.CurrentFileSystemLocation.Path;
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static void UseCurrentCulture()
|
||||
{
|
||||
UseCurrentCulture(Thread.CurrentThread.CurrentCulture);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static void UseCurrentCulture(string culture)
|
||||
{
|
||||
UseCurrentCulture(CultureInfo.CreateSpecificCulture(culture));
|
||||
|
@ -308,94 +344,7 @@ namespace PSRule.Configuration
|
|||
/// <param name="hashtable"></param>
|
||||
public static implicit operator PSRuleOption(Hashtable hashtable)
|
||||
{
|
||||
var option = new PSRuleOption();
|
||||
if (hashtable == null)
|
||||
return option;
|
||||
|
||||
// Build index to allow mapping
|
||||
var index = BuildIndex(hashtable);
|
||||
|
||||
// Start loading matching values
|
||||
|
||||
if (index.TryPopValue("Convention.Include", out object value))
|
||||
{
|
||||
option.Convention.Include = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("execution.languagemode", out value))
|
||||
{
|
||||
option.Execution.LanguageMode = (LanguageMode)Enum.Parse(typeof(LanguageMode), (string)value);
|
||||
}
|
||||
if (index.TryPopBool("execution.inconclusivewarning", out bool bvalue))
|
||||
{
|
||||
option.Execution.InconclusiveWarning = bvalue;
|
||||
}
|
||||
if (index.TryPopBool("execution.notprocessedwarning", out bvalue))
|
||||
{
|
||||
option.Execution.NotProcessedWarning = bvalue;
|
||||
}
|
||||
if (index.TryPopValue("input.format", out value))
|
||||
{
|
||||
option.Input.Format = (InputFormat)Enum.Parse(typeof(InputFormat), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("input.objectpath", out value))
|
||||
{
|
||||
option.Input.ObjectPath = (string)value;
|
||||
}
|
||||
if (index.TryPopValue("input.pathignore", out value))
|
||||
{
|
||||
option.Input.PathIgnore = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("input.targettype", out value))
|
||||
{
|
||||
option.Input.TargetType = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("logging.limitdebug", out value))
|
||||
{
|
||||
option.Logging.LimitDebug = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("logging.limitverbose", out value))
|
||||
{
|
||||
option.Logging.LimitVerbose = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("logging.rulefail", out value))
|
||||
{
|
||||
option.Logging.RuleFail = (OutcomeLogStream)Enum.Parse(typeof(OutcomeLogStream), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("logging.rulepass", out value))
|
||||
{
|
||||
option.Logging.RulePass = (OutcomeLogStream)Enum.Parse(typeof(OutcomeLogStream), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("output.as", out value))
|
||||
{
|
||||
option.Output.As = (ResultFormat)Enum.Parse(typeof(ResultFormat), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("output.culture", out value))
|
||||
{
|
||||
option.Output.Culture = AsStringArray(value);
|
||||
}
|
||||
if (index.TryPopValue("output.encoding", out value))
|
||||
{
|
||||
option.Output.Encoding = (OutputEncoding)Enum.Parse(typeof(OutputEncoding), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("output.format", out value))
|
||||
{
|
||||
option.Output.Format = (OutputFormat)Enum.Parse(typeof(OutputFormat), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("output.outcome", out value))
|
||||
{
|
||||
option.Output.Outcome = (RuleOutcome)Enum.Parse(typeof(RuleOutcome), (string)value);
|
||||
}
|
||||
if (index.TryPopValue("output.path", out value))
|
||||
{
|
||||
option.Output.Path = (string)value;
|
||||
}
|
||||
if (index.TryPopValue("output.style", out value))
|
||||
{
|
||||
option.Output.Style = (OutputStyle)Enum.Parse(typeof(OutputStyle), (string)value);
|
||||
}
|
||||
option.Requires.Load(index);
|
||||
BaselineOption.Load(option, index);
|
||||
return option;
|
||||
return FromHashtable(hashtable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -404,8 +353,7 @@ namespace PSRule.Configuration
|
|||
/// <param name="path">A file or directory to read options from.</param>
|
||||
public static implicit operator PSRuleOption(string path)
|
||||
{
|
||||
var option = FromFile(path);
|
||||
return option;
|
||||
return FromFile(path);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -494,6 +442,9 @@ namespace PSRule.Configuration
|
|||
return string.Concat(rootedPath, Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build index to allow mapping values.
|
||||
/// </summary>
|
||||
[DebuggerStepThrough]
|
||||
internal static Dictionary<string, object> BuildIndex(Hashtable hashtable)
|
||||
{
|
||||
|
@ -539,15 +490,6 @@ namespace PSRule.Configuration
|
|||
return s.Serialize(this);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
private static string[] AsStringArray(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return value.GetType().IsArray ? ((object[])value).OfType<string>().ToArray() : new string[] { value.ToString() };
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
private static bool IsSeparator(char c)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,10 @@ namespace PSRule.Configuration
|
|||
{
|
||||
public sealed class RequiresOption : KeyMapDictionary<string>
|
||||
{
|
||||
private const string KEYMAP_PREFIX = "Requires.";
|
||||
private const string ENVIRONMENT_PREFIX = "PSRULE_REQUIRES_";
|
||||
private const string DICTIONARY_PREFIX = "Requires.";
|
||||
private const char UNDERSCORE = '_';
|
||||
private const char DOT = '.';
|
||||
|
||||
public RequiresOption()
|
||||
: base() { }
|
||||
|
@ -15,9 +18,28 @@ namespace PSRule.Configuration
|
|||
internal RequiresOption(RequiresOption option)
|
||||
: base(option) { }
|
||||
|
||||
/// <summary>
|
||||
/// Load Requires option from environment variables.
|
||||
/// </summary>
|
||||
internal void Load(EnvironmentHelper env)
|
||||
{
|
||||
base.Load(ENVIRONMENT_PREFIX, env, ConvertUnderscore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load Requires option from a dictionary.
|
||||
/// </summary>
|
||||
internal void Load(IDictionary<string, object> dictionary)
|
||||
{
|
||||
base.Load(KEYMAP_PREFIX, dictionary);
|
||||
base.Load(DICTIONARY_PREFIX, dictionary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert module names with underscores to dots.
|
||||
/// </summary>
|
||||
private string ConvertUnderscore(string key)
|
||||
{
|
||||
return key.Replace(UNDERSCORE, DOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,12 +62,21 @@ namespace PSRule.Configuration
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A set of rules to include for execution.
|
||||
/// </summary>
|
||||
[DefaultValue(null)]
|
||||
public string[] Include { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A set of rules to exclude for execution.
|
||||
/// </summary>
|
||||
[DefaultValue(null)]
|
||||
public string[] Exclude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A set of rule tags to include for execution.
|
||||
/// </summary>
|
||||
[DefaultValue(null)]
|
||||
public Hashtable Tag { get; set; }
|
||||
}
|
||||
|
|
|
@ -86,6 +86,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
|
||||
$option.Rule.Include | Should -BeIn 'rule1';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_RULE_INCLUDE = 'rule1';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Rule.Include | Should -BeIn 'rule1';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_RULE_INCLUDE = 'rule1;rule2';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Rule.Include | Should -BeIn 'rule1', 'rule2';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_RULE_INCLUDE' -Force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Read Rule.Exclude' {
|
||||
|
@ -117,6 +134,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
|
||||
$option.Rule.Exclude | Should -BeIn 'rule3';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_RULE_EXCLUDE = 'rule3';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Rule.Exclude | Should -BeIn 'rule3';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_RULE_EXCLUDE = 'rule3;rule4';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Rule.Exclude | Should -BeIn 'rule3', 'rule4';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_RULE_EXCLUDE' -Force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Read Rule.Tag' {
|
||||
|
@ -141,7 +175,7 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
}
|
||||
}
|
||||
|
||||
Context 'Read Baseline.Configuration' {
|
||||
Context 'Read Configuration' {
|
||||
It 'from default' {
|
||||
$option = New-PSRuleOption -Default;
|
||||
$option.Configuration.Count | Should -Be 0;
|
||||
|
@ -160,6 +194,20 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Configuration.option2 | Should -Be 2;
|
||||
$option.Configuration.option3 | Should -BeIn 'option3a', 'option3b';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_CONFIGURATION_OPTION1 = 'value1';
|
||||
$Env:PSRULE_CONFIGURATION_OPTION2_NAME = 'value2';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Configuration.option1 | Should -Be 'value1';
|
||||
$option.Configuration.option2_name | Should -Be 'value2';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_CONFIGURATION_OPTION1' -Force;
|
||||
Remove-Item 'Env:PSRULE_CONFIGURATION_OPTION2_NAME' -Force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Read Binding.Field' {
|
||||
|
@ -205,6 +253,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.IgnoreCase | Should -Be $False;
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With bool
|
||||
$Env:PSRULE_BINDING_IGNORECASE = 'false';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.IgnoreCase | Should -Be $False;
|
||||
|
||||
# With int
|
||||
$Env:PSRULE_BINDING_IGNORECASE = '0';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.IgnoreCase | Should -Be $False;
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_IGNORECASE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -BindingIgnoreCase $False -Path $emptyOptionsFilePath;
|
||||
$option.Binding.IgnoreCase | Should -Be $False;
|
||||
|
@ -227,6 +292,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.NameSeparator | Should -Be '::';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_BINDING_NAMESEPARATOR = '::';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.NameSeparator | Should -Be '::';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_NAMESEPARATOR' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -BindingNameSeparator 'zz' -Path $emptyOptionsFilePath;
|
||||
$option.Binding.NameSeparator | Should -Be 'zz';
|
||||
|
@ -249,6 +325,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.PreferTargetInfo | Should -Be $True;
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With bool
|
||||
$Env:PSRULE_BINDING_PREFERTARGETINFO = 'true';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.PreferTargetInfo | Should -Be $True;
|
||||
|
||||
# With int
|
||||
$Env:PSRULE_BINDING_PREFERTARGETINFO = '1';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.PreferTargetInfo | Should -Be $True;
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_PREFERTARGETINFO' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -BindingPreferTargetInfo $True -Path $emptyOptionsFilePath;
|
||||
$option.Binding.PreferTargetInfo | Should -Be $True;
|
||||
|
@ -286,6 +379,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.TargetName | Should -BeIn 'ResourceName';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_BINDING_TARGETNAME = 'ResourceName';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.TargetName | Should -BeIn 'ResourceName';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_BINDING_TARGETNAME = 'ResourceName;AlternateName';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_TARGETNAME' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -TargetName 'ResourceName', 'AlternateName' -Path $emptyOptionsFilePath;
|
||||
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
|
||||
|
@ -323,6 +433,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.TargetType | Should -BeIn 'ResourceType';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_BINDING_TARGETTYPE = 'ResourceType';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.TargetType | Should -BeIn 'ResourceType';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_BINDING_TARGETTYPE = 'ResourceType;Kind';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_TARGETTYPE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -TargetType 'ResourceType', 'Kind' -Path $emptyOptionsFilePath;
|
||||
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
|
||||
|
@ -345,6 +472,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Binding.UseQualifiedName | Should -Be $True;
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With bool
|
||||
$Env:PSRULE_BINDING_USEQUALIFIEDNAME = 'true';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.UseQualifiedName | Should -Be $True;
|
||||
|
||||
# With int
|
||||
$Env:PSRULE_BINDING_USEQUALIFIEDNAME = '1';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Binding.UseQualifiedName | Should -Be $True;
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_BINDING_USEQUALIFIEDNAME' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -BindingUseQualifiedName $True -Path $emptyOptionsFilePath;
|
||||
$option.Binding.UseQualifiedName | Should -Be $True;
|
||||
|
@ -382,6 +526,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Convention.Include | Should -BeIn 'Convention3';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_CONVENTION_INCLUDE = 'Convention1';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Convention.Include | Should -Be 'Convention1';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_CONVENTION_INCLUDE = 'Convention1;Convention2';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Convention.Include | Should -Be 'Convention1', 'Convention2';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_CONVENTION_INCLUDE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -Convention 'Convention1', 'Convention2' -Path $emptyOptionsFilePath;
|
||||
$option.Convention.Include | Should -BeIn 'Convention1', 'Convention2';
|
||||
|
@ -403,6 +564,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
|
||||
$option.Execution.LanguageMode | Should -Be 'ConstrainedLanguage';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_EXECUTION_LANGUAGEMODE = 'ConstrainedLanguage';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Execution.LanguageMode | Should -Be 'ConstrainedLanguage';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_EXECUTION_LANGUAGEMODE' -Force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Read Execution.InconclusiveWarning' {
|
||||
|
@ -421,6 +593,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Execution.InconclusiveWarning | Should -Be $False;
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With bool
|
||||
$Env:PSRULE_EXECUTION_INCONCLUSIVEWARNING = 'false';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Execution.InconclusiveWarning | Should -Be $False;
|
||||
|
||||
# With int
|
||||
$Env:PSRULE_EXECUTION_INCONCLUSIVEWARNING = '0';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Execution.InconclusiveWarning | Should -Be $False;
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_EXECUTION_INCONCLUSIVEWARNING' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -InconclusiveWarning $False -Path $emptyOptionsFilePath;
|
||||
$option.Execution.InconclusiveWarning | Should -Be $False;
|
||||
|
@ -443,6 +632,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Execution.NotProcessedWarning | Should -Be $False;
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With bool
|
||||
$Env:PSRULE_EXECUTION_NOTPROCESSEDWARNING = 'false';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Execution.NotProcessedWarning | Should -Be $False;
|
||||
|
||||
# With int
|
||||
$Env:PSRULE_EXECUTION_NOTPROCESSEDWARNING = '0';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Execution.NotProcessedWarning | Should -Be $False;
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_EXECUTION_NOTPROCESSEDWARNING' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -NotProcessedWarning $False -Path $emptyOptionsFilePath;
|
||||
$option.Execution.NotProcessedWarning | Should -Be $False;
|
||||
|
@ -465,6 +671,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Input.Format | Should -Be 'Yaml';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_INPUT_FORMAT = 'Yaml';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.Format | Should -Be 'Yaml';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_INPUT_FORMAT' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -Format 'Yaml' -Path $emptyOptionsFilePath;
|
||||
$option.Input.Format | Should -Be 'Yaml';
|
||||
|
@ -487,6 +704,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Input.ObjectPath | Should -Be 'items';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_INPUT_OBJECTPATH = 'items';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.ObjectPath | Should -Be 'items';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_INPUT_OBJECTPATH' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -ObjectPath 'items' -Path $emptyOptionsFilePath;
|
||||
$option.Input.ObjectPath | Should -Be 'items';
|
||||
|
@ -509,6 +737,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Input.PathIgnore | Should -Be '*.Designer.cs';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_INPUT_PATHIGNORE = 'ignore.cs';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.PathIgnore | Should -Be 'ignore.cs';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_INPUT_PATHIGNORE = 'ignore.cs;*.Designer.cs';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.PathIgnore | Should -Be 'ignore.cs', '*.Designer.cs';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_INPUT_PATHIGNORE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -InputPathIgnore 'ignore.cs' -Path $emptyOptionsFilePath;
|
||||
$option.Input.PathIgnore | Should -Be 'ignore.cs';
|
||||
|
@ -546,6 +791,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Input.TargetType | Should -BeIn 'virtualMachine';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# With single item
|
||||
$Env:PSRULE_INPUT_TARGETTYPE = 'virtualMachine';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.TargetType | Should -Be 'virtualMachine';
|
||||
|
||||
# With array
|
||||
$Env:PSRULE_INPUT_TARGETTYPE = 'virtualMachine;virtualNetwork';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Input.TargetType | Should -Be 'virtualMachine', 'virtualNetwork';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_INPUT_TARGETTYPE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -InputTargetType 'virtualMachine', 'virtualNetwork' -Path $emptyOptionsFilePath;
|
||||
$option.Input.TargetType | Should -BeIn 'virtualMachine', 'virtualNetwork';
|
||||
|
@ -656,6 +918,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.As | Should -Be 'Summary';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_AS = 'Summary';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.As | Should -Be 'Summary';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_AS' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputAs 'Summary' -Path $emptyOptionsFilePath;
|
||||
$option.Output.As | Should -Be 'Summary';
|
||||
|
@ -692,6 +965,23 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Culture | Should -BeIn 'en-CC', 'en-DD';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
# Single
|
||||
$Env:PSRULE_OUTPUT_CULTURE = 'en-AA';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Culture | Should -BeIn 'en-AA';
|
||||
|
||||
# Array
|
||||
$Env:PSRULE_OUTPUT_CULTURE = 'en-AA;en-BB';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Culture | Should -BeIn 'en-AA', 'en-BB';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_CULTURE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
# Single
|
||||
$option = New-PSRuleOption -OutputCulture 'en-XX' -Path $emptyOptionsFilePath;
|
||||
|
@ -721,6 +1011,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Encoding | Should -Be 'UTF7';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_ENCODING = 'UTF7';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Encoding | Should -Be 'UTF7';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_ENCODING' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputEncoding 'UTF7' -Path $emptyOptionsFilePath;
|
||||
$option.Output.Encoding | Should -Be 'UTF7';
|
||||
|
@ -743,6 +1044,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Format | Should -Be 'Json';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_FORMAT = 'Yaml';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Format | Should -Be 'Yaml';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_FORMAT' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputFormat 'Yaml' -Path $emptyOptionsFilePath;
|
||||
$option.Output.Format | Should -Be 'Yaml';
|
||||
|
@ -765,6 +1077,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Outcome | Should -Be 'Pass';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_OUTCOME = 'Fail';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Outcome | Should -Be 'Fail';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_OUTCOME' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputOutcome 'Fail' -Path $emptyOptionsFilePath;
|
||||
$option.Output.Outcome | Should -Be 'Fail';
|
||||
|
@ -787,6 +1110,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Path | Should -Be 'out/OutputPath.txt';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_PATH = 'out/OutputPath.txt';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Path | Should -Be 'out/OutputPath.txt';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_PATH' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputPath 'out/OutputPath.txt' -Path $emptyOptionsFilePath;
|
||||
$option.Output.Path | Should -Be 'out/OutputPath.txt';
|
||||
|
@ -809,6 +1143,17 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option.Output.Style | Should -Be 'GitHubActions';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_OUTPUT_STYLE = 'AzurePipelines';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Output.Style | Should -Be 'AzurePipelines';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_OUTPUT_STYLE' -Force;
|
||||
}
|
||||
}
|
||||
|
||||
It 'from parameter' {
|
||||
$option = New-PSRuleOption -OutputStyle 'AzurePipelines' -Path $emptyOptionsFilePath;
|
||||
$option.Output.Style | Should -Be 'AzurePipelines';
|
||||
|
@ -830,6 +1175,20 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
|
|||
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests6.yml');
|
||||
$option.Requires.PSRule | Should -Be '>=0.18.0';
|
||||
}
|
||||
|
||||
It 'from Environment' {
|
||||
try {
|
||||
$Env:PSRULE_REQUIRES_PSRULE = '^0.1.0';
|
||||
$Env:PSRULE_REQUIRES_PSRULE_RULES_AZURE = '^0.2.0';
|
||||
$option = New-PSRuleOption;
|
||||
$option.Requires.PSRule | Should -Be '^0.1.0';
|
||||
$option.Requires.'PSRule.Rules.Azure' | Should -Be '^0.2.0';
|
||||
}
|
||||
finally {
|
||||
Remove-Item 'Env:PSRULE_REQUIRES_PSRULE' -Force;
|
||||
Remove-Item 'Env:PSRULE_REQUIRES_PSRULE_RULES_AZURE' -Force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Read Suppression' {
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace PSRule
|
|||
Assert.Null(builder.Build());
|
||||
}
|
||||
|
||||
#region Helper methods
|
||||
|
||||
private static Source[] GetSource()
|
||||
{
|
||||
var builder = new SourcePipelineBuilder(null, null);
|
||||
|
@ -106,5 +108,7 @@ namespace PSRule
|
|||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
|
||||
}
|
||||
|
||||
#endregion Helper methods
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче