Skip to content
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
4 changes: 0 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,4 @@ end_of_line = crlf

[*.{yml, yaml}]
indent_size = 2

# Makefiles require tab indentation
[{{M,m,GNU}akefile{,.*},*.mak,*.mk}]
indent_style = tab
end_of_line = lf
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI
Comment thread
coderabbitai[bot] marked this conversation as resolved.

on:
push:
pull_request:

permissions: {}

jobs:
test:
name: Tests
runs-on: windows-latest
defaults:
run:
shell: pwsh
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install dependencies
uses: potatoqualitee/psmodulecache@ee5e9494714abf56f6efbfa51527b2aec5c761b8 # v6.2.1
with:
modules-to-cache: PSScriptAnalyzer, Pester
shell: pwsh
- name: Run tests
run: ./tests/run.ps1
67 changes: 67 additions & 0 deletions .psformatrules.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@{
# OTBS
IncludeRules = @(
'PSPlaceOpenBrace',
'PSPlaceCloseBrace',
'PSUseConsistentWhitespace',
'PSUseConsistentIndentation',
'PSAlignAssignmentStatement',
'PSAvoidSemicolonsAsLineTerminators',
'PSAvoidUsingDoubleQuotesForConstantString',
'PSUseCorrectCasing'
)

Rules = @{
PSPlaceOpenBrace = @{
Enable = $true
OnSameLine = $true
NewLineAfter = $true
IgnoreOneLineBlock = $true
}

PSPlaceCloseBrace = @{
Enable = $true
NewLineAfter = $false
IgnoreOneLineBlock = $true
NoEmptyLineBefore = $false
}

PSUseConsistentIndentation = @{
Enable = $true
Kind = 'space'
PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
IndentationSize = 4
}

PSUseConsistentWhitespace = @{
Enable = $true
CheckInnerBrace = $true
CheckOpenBrace = $true
CheckOpenParen = $true
CheckOperator = $true
CheckPipe = $true
CheckPipeForRedundantWhitespace = $false
CheckSeparator = $true
CheckParameter = $false
IgnoreAssignmentOperatorInsideHashTable = $true
}

PSAlignAssignmentStatement = @{
Enable = $true
CheckHashtable = $true
}

PSAvoidSemicolonsAsLineTerminators = @{
Enable = $true
}

PSAvoidUsingDoubleQuotesForConstantString = @{
Enable = $true
}

PSUseCorrectCasing = @{
Enable = $true
}
}
}

31 changes: 31 additions & 0 deletions .pslintrules.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@{
# Only diagnostic records of the specified severity will be generated.
# Uncomment the following line if you only want Errors and Warnings but
# not Information diagnostic records.
Severity = @('Error', 'Warning')

# Analyze **only** the following rules. Use IncludeRules when you want
# to invoke only a small subset of the default rules.
# IncludeRules = @('PSAvoidDefaultValueSwitchParameter',
# 'PSMisleadingBacktick',
# 'PSMissingModuleManifestField',
# 'PSReservedCmdletChar',
# 'PSReservedParams',
# 'PSShouldProcess',
# 'PSUseApprovedVerbs',
# 'PSAvoidUsingCmdletAliases',
# 'PSUseDeclaredVarsMoreThanAssignments')

# Do not analyze the following rules. Use ExcludeRules when you have
# commented out the IncludeRules settings above and want to include all
# the default rules except for those you exclude below.
# Note: if a rule is in both IncludeRules and ExcludeRules, the rule
# will be excluded.
ExcludeRules = @(
# PSUseDeclaredVarsMoreThanAssignments doesn't currently work due to:
# https://github.com/PowerShell/PSScriptAnalyzer/issues/636
'PSUseDeclaredVarsMoreThanAssignments',
# `Write-Log` uses `Write-Host` currently.
'PSAvoidUsingWriteHost'
)
}
17 changes: 4 additions & 13 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
// Configure PSScriptAnalyzer settings
{
"powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1",
"[powershell]": {
"editor.formatOnSave": true,
},
"powershell.scriptAnalysis.settingsPath": ".pslintrules.psd1",
"powershell.codeFormatting.preset": "OTBS",
"powershell.codeFormatting.alignPropertyValuePairs": true,
"powershell.codeFormatting.ignoreOneLineBlock": true,
"powershell.codeFormatting.useConstantStrings": true,
"powershell.codeFormatting.useCorrectCasing": true,
"powershell.codeFormatting.whitespaceBetweenParameters": true,
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/tmp": true
}
}
75 changes: 75 additions & 0 deletions tests/Linter.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
Describe 'PowerShell Code Style' -Tag 'PSScriptAnalyzer' {
BeforeAll {
$formatSettings = "$PSScriptRoot\..\.psformatrules.psd1"
$lintSettings = "$PSScriptRoot\..\.pslintrules.psd1"
}

It 'PSScriptAnalyzer rules files should exist' {
$formatSettings | Should -Exist
$lintSettings | Should -Exist
}

Context 'PowerShell code formatting' {
BeforeAll {
$records = Invoke-ScriptAnalyzer -Path "$PSScriptRoot\..\" `
-Recurse -Settings $formatSettings
}
It 'Code should be formatted' {
$records.Count | Should -Be 0
}
AfterAll {
if ($records) {
foreach ($r in $records) {
$type = 'Unknown'
switch -wildCard ($r.ScriptName) {
'*.psm1' { $type = 'Module' }
'*.ps1' { $type = 'Script' }
'*.psd1' { $type = 'Manifest' }
default { $type = 'Unknown' }
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
$scriptPath = Resolve-Path -Relative $r.ScriptPath
$color = switch ($r.Severity) {
'Error' { 'Red' }
'Warning' { 'Yellow' }
'Information' { 'White' }
default { 'White' }
}
Write-Host -f $color " [!] $($r.Severity): $($r.Message)"
Write-Host -f $color " $($r.RuleName) in $type`: $($scriptPath):$($r.Line)"
}
}
}
}

Context 'PowerShell code linting' {
BeforeAll {
$records = Invoke-ScriptAnalyzer -Path "$PSScriptRoot\..\" `
-Recurse -Settings $lintSettings
}
It 'Code should be linted' {
$records.Count | Should -Be 0
}
AfterAll {
if ($records) {
foreach ($r in $records) {
$type = 'Unknown'
switch -wildCard ($r.ScriptName) {
'*.psm1' { $type = 'Module' }
'*.ps1' { $type = 'Script' }
'*.psd1' { $type = 'Manifest' }
default { $type = 'Unknown' }
}
$scriptPath = Resolve-Path -Relative $r.ScriptPath
$color = switch ($r.Severity) {
'Error' { 'Red' }
'Warning' { 'Yellow' }
'Information' { 'White' }
default { 'White' }
}
Write-Host -f $color " [!] $($r.Severity): $($r.Message)"
Write-Host -f $color " $($r.RuleName) in $type`: $($scriptPath):$($r.Line)"
}
}
}
}
}
22 changes: 22 additions & 0 deletions tests/run.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#Requires -Version 5.1
#Requires -Modules Pester
#Requires -Modules PSScriptAnalyzer

$pesterConfig = New-PesterConfiguration -Hashtable @{
Run = @{
Path = "$PSScriptRoot"
PassThru = $true
}
Should = @{
# Continue running tests even if some assertions fail. This allows
# Pester to collect and report all failures at the end of a test
# instead of stopping at the first failing assertion.
ErrorAction = 'Continue'
}
Output = @{
StackTraceVerbosity = 'None'
Verbosity = 'Detailed'
}
}
$result = Invoke-Pester -Configuration $pesterConfig
exit $result.FailedCount
Loading