diff --git a/.gitattributes b/.gitattributes index df492b0..5a3d63b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,10 @@ +# Normalize line endings to LF in both the repo and the working tree, regardless of +# the contributor's global core.autocrlf setting. PowerShell on Windows handles LF +# fine, and the devcontainer runs Linux. Without this, Windows clones with +# core.autocrlf=true emit "LF will be replaced by CRLF the next time Git touches it" +# warnings on every commit when files are edited by tooling that writes LF (most +# editors and AI agents do). +* text=auto eol=lf + # The docs are generated by the build script and should be considered artifacts docs/en-US/* linguist-generated diff --git a/build.ps1 b/build.ps1 index 8887f8f..c76be82 100644 --- a/build.ps1 +++ b/build.ps1 @@ -40,6 +40,7 @@ param( @() } })] + [ValidateNotNullOrEmpty()] [string[]]$Task = 'default', # Bootstrap dependencies diff --git a/tests/Help.tests.ps1 b/tests/Help.tests.ps1 index 4f1a16c..ea99c57 100644 --- a/tests/Help.tests.ps1 +++ b/tests/Help.tests.ps1 @@ -57,10 +57,10 @@ BeforeDiscovery { } # PowerShellBuild outputs to Output///, override BHBuildOutput - $projectRoot = Split-Path -Parent $PSScriptRoot - $sourceManifest = Join-Path $projectRoot "$Env:BHProjectName/$Env:BHProjectName.psd1" + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + $sourceManifest = Join-Path -Path $projectRoot -ChildPath "$Env:BHProjectName/$Env:BHProjectName.psd1" $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $Env:BHBuildOutput = Join-Path $projectRoot "Output/$Env:BHProjectName/$moduleVersion" + $Env:BHBuildOutput = Join-Path -Path $projectRoot -ChildPath "Output/$Env:BHProjectName/$moduleVersion" # Define the path to the module manifest $moduleManifestFilename = $Env:BHProjectName + '.psd1' @@ -72,18 +72,18 @@ BeforeDiscovery { 'Classes' ) | ForEach-Object { $path = Join-Path -Path $Env:BHBuildOutput -ChildPath $_ - if (Test-Path $path) { + if (Test-Path -Path $path) { $global:CustomTypes += (Get-ChildItem -Path $path -Recurse -ErrorAction 'SilentlyContinue').BaseName } } # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' + Get-Module -Name $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' Import-Module -Name $moduleManifestPath -Verbose:$false -ErrorAction 'Stop' # Get module commands $getCommandParameters = @{ - Module = (Get-Module $Env:BHProjectName) + Module = (Get-Module -Name $Env:BHProjectName) CommandType = [System.Management.Automation.CommandTypes[]]'Cmdlet, Function' # Not alias } if ($PSVersionTable.PSVersion.Major -lt 6) { diff --git a/tests/Manifest.tests.ps1 b/tests/Manifest.tests.ps1 index fe6e3f6..0762051 100644 --- a/tests/Manifest.tests.ps1 +++ b/tests/Manifest.tests.ps1 @@ -69,10 +69,10 @@ BeforeDiscovery { } # PowerShellBuild outputs to Output///, override BHBuildOutput - $projectRoot = Split-Path -Parent $PSScriptRoot - $sourceManifest = Join-Path $projectRoot "$Env:BHProjectName/$Env:BHProjectName.psd1" + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + $sourceManifest = Join-Path -Path $projectRoot -ChildPath "$Env:BHProjectName/$Env:BHProjectName.psd1" $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $Env:BHBuildOutput = Join-Path $projectRoot "Output/$Env:BHProjectName/$moduleVersion" + $Env:BHBuildOutput = Join-Path -Path $projectRoot -ChildPath "Output/$Env:BHProjectName/$moduleVersion" # Define the path to the module manifest $moduleManifestFilename = $Env:BHProjectName + '.psd1' @@ -108,10 +108,10 @@ BeforeAll { } # PowerShellBuild outputs to Output///, override BHBuildOutput - $projectRoot = Split-Path -Parent $PSScriptRoot - $sourceManifest = Join-Path $projectRoot "$Env:BHProjectName/$Env:BHProjectName.psd1" + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + $sourceManifest = Join-Path -Path $projectRoot -ChildPath "$Env:BHProjectName/$Env:BHProjectName.psd1" $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $Env:BHBuildOutput = Join-Path $projectRoot "Output/$Env:BHProjectName/$moduleVersion" + $Env:BHBuildOutput = Join-Path -Path $projectRoot -ChildPath "Output/$Env:BHProjectName/$moduleVersion" # Define the path to the module manifest $moduleManifestFilename = $Env:BHProjectName + '.psd1' @@ -135,12 +135,12 @@ BeforeAll { Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'ManifestHelpers.psm1') -Verbose:$false -Force $requirementsPath = Join-Path -Path $env:BHProjectPath -ChildPath 'requirements.psd1' - $requirements = Import-PowerShellDataFile -Path $requirementsPath -ErrorAction Stop + $requirements = Import-PowerShellDataFile -Path $requirementsPath -ErrorAction 'Stop' # Parse the version from the changelog $changelogPath = Join-Path -Path $Env:BHProjectPath -ChildPath 'CHANGELOG.md' $changelogVersionPattern = '^##\s\\?\[(?(\d+\.){1,3}\d+)\\?\]' # Matches on a line that starts with '## [Version]' or '## \[Version\]' - $changelogVersion = Get-Content $changelogPath | ForEach-Object { + $changelogVersion = Get-Content -Path $changelogPath | ForEach-Object { if ($_ -match $changelogVersionPattern) { $changelogVersion = $matches.Version break diff --git a/tests/ManifestHelpers.psm1 b/tests/ManifestHelpers.psm1 index b797866..533824b 100644 --- a/tests/ManifestHelpers.psm1 +++ b/tests/ManifestHelpers.psm1 @@ -36,13 +36,10 @@ function Split-SemVerString { [OutputType([hashtable])] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$VersionString ) - if ([string]::IsNullOrEmpty($VersionString)) { - throw "VersionString cannot be empty or null" - } - # Strip build metadata per SemVer 2.0.0 — it does not affect precedence and is # not valid for [System.Version], so it must be removed before further parsing. $coreVersion = ($VersionString -split '\+', 2)[0] @@ -92,9 +89,11 @@ function Compare-SemVerPrerelease { [OutputType([int])] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$FirstPrerelease, [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$SecondPrerelease ) @@ -208,6 +207,7 @@ function Test-VersionComparison { [OutputType([bool])] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$FirstVersion, [Parameter(Mandatory = $false)] @@ -215,6 +215,7 @@ function Test-VersionComparison { [string]$FirstPrerelease, [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$SecondVersion, [Parameter(Mandatory = $false)] @@ -325,9 +326,11 @@ function Test-VersionConstraint { [OutputType([bool])] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$ManifestVersion, [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$RequirementsVersion, [Parameter(Mandatory = $true)] @@ -337,14 +340,14 @@ function Test-VersionConstraint { # Validate input versions are not empty if ([string]::IsNullOrWhiteSpace($ManifestVersion)) { - throw "ManifestVersion cannot be empty or whitespace" + throw 'ManifestVersion cannot be empty or whitespace' } if ([string]::IsNullOrWhiteSpace($RequirementsVersion)) { - throw "RequirementsVersion cannot be empty or whitespace" + throw 'RequirementsVersion cannot be empty or whitespace' } - $manifestParts = Split-SemVerString $ManifestVersion - $requirementsParts = Split-SemVerString $RequirementsVersion + $manifestParts = Split-SemVerString -VersionString $ManifestVersion + $requirementsParts = Split-SemVerString -VersionString $RequirementsVersion $comparisonParameters = @{ FirstVersion = $requirementsParts.Version diff --git a/tests/Meta.tests.ps1 b/tests/Meta.tests.ps1 index 68298f0..c1813ec 100644 --- a/tests/Meta.tests.ps1 +++ b/tests/Meta.tests.ps1 @@ -9,11 +9,11 @@ BeforeAll { $projectRoot = $PSScriptRoot } - $allTextFiles = Get-TextFilesList $projectRoot + $allTextFiles = Get-TextFilesList -Root $projectRoot $unicodeFilesCount = 0 $totalTabsCount = 0 foreach ($textFile in $allTextFiles) { - if (Test-FileUnicode $textFile) { + if (Test-FileUnicode -FileInfo $textFile) { $unicodeFilesCount++ Write-Warning ( "File $($textFile.FullName) contains 0x00 bytes." + @@ -24,7 +24,7 @@ BeforeAll { $unicodeFilesCount | Should -Be 0 $fileName = $textFile.FullName - (Get-Content $fileName -Raw) | Select-String "`t" | Foreach-Object { + (Get-Content -Path $fileName -Raw) | Select-String -Pattern "`t" | Foreach-Object { Write-Warning ( "There are tabs in $fileName." + ' Use Fixer "Get-TextFilesList `$pwd | ConvertTo-SpaceIndentation".' diff --git a/tests/MetaFixers.psm1 b/tests/MetaFixers.psm1 index 7dec0c8..43da225 100644 --- a/tests/MetaFixers.psm1 +++ b/tests/MetaFixers.psm1 @@ -27,6 +27,7 @@ function ConvertTo-UTF8 { [OutputType([void])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ValidateNotNull()] [System.IO.FileInfo]$FileInfo ) @@ -56,6 +57,7 @@ function ConvertTo-SpaceIndentation { [OutputType([void])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ValidateNotNull()] [System.IO.FileInfo]$FileInfo ) @@ -85,6 +87,7 @@ function Get-TextFilesList { [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ValidateNotNullOrEmpty()] [string]$Root ) @@ -159,10 +162,11 @@ function Get-UnicodeFilesList { [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [string]$Root ) $root | Get-TextFilesList | Where-Object { - Test-FileUnicode $_ + Test-FileUnicode -FileInfo $_ } } diff --git a/tests/Unit/Private/Invoke-{{Prefix}}Helper.tests.ps1 b/tests/Unit/Private/Invoke-{{Prefix}}Helper.tests.ps1 index e4879ca..250662c 100644 --- a/tests/Unit/Private/Invoke-{{Prefix}}Helper.tests.ps1 +++ b/tests/Unit/Private/Invoke-{{Prefix}}Helper.tests.ps1 @@ -17,20 +17,20 @@ BeforeDiscovery { } # PowerShellBuild outputs to Output/// - $projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) - $sourceManifest = Join-Path $projectRoot "$Env:BHProjectName/$Env:BHProjectName.psd1" + $projectRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -Parent + $sourceManifest = Join-Path -Path $projectRoot -ChildPath "$Env:BHProjectName/$Env:BHProjectName.psd1" $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $Env:BHBuildOutput = Join-Path $projectRoot "Output/$Env:BHProjectName/$moduleVersion" + $Env:BHBuildOutput = Join-Path -Path $projectRoot -ChildPath "Output/$Env:BHProjectName/$moduleVersion" } BeforeAll { # Import the module from the build output $moduleManifestPath = Join-Path -Path $Env:BHBuildOutput -ChildPath "$Env:BHProjectName.psd1" - Get-Module $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' + Get-Module -Name $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' Import-Module -Name $moduleManifestPath -Force -ErrorAction 'Stop' } -InModuleScope $Env:BHProjectName { +InModuleScope -ModuleName $Env:BHProjectName -ScriptBlock { Describe 'Invoke-{{Prefix}}Helper' { Context 'Basic functionality' { diff --git a/tests/Unit/Public/Get-{{Prefix}}Example.tests.ps1 b/tests/Unit/Public/Get-{{Prefix}}Example.tests.ps1 index 47fdbc0..051affa 100644 --- a/tests/Unit/Public/Get-{{Prefix}}Example.tests.ps1 +++ b/tests/Unit/Public/Get-{{Prefix}}Example.tests.ps1 @@ -17,16 +17,16 @@ BeforeDiscovery { } # PowerShellBuild outputs to Output/// - $projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) - $sourceManifest = Join-Path $projectRoot "$Env:BHProjectName/$Env:BHProjectName.psd1" + $projectRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -Parent + $sourceManifest = Join-Path -Path $projectRoot -ChildPath "$Env:BHProjectName/$Env:BHProjectName.psd1" $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $Env:BHBuildOutput = Join-Path $projectRoot "Output/$Env:BHProjectName/$moduleVersion" + $Env:BHBuildOutput = Join-Path -Path $projectRoot -ChildPath "Output/$Env:BHProjectName/$moduleVersion" } BeforeAll { # Import the module from the build output $moduleManifestPath = Join-Path -Path $Env:BHBuildOutput -ChildPath "$Env:BHProjectName.psd1" - Get-Module $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' + Get-Module -Name $Env:BHProjectName | Remove-Module -Force -ErrorAction 'Ignore' Import-Module -Name $moduleManifestPath -Force -ErrorAction 'Stop' } diff --git a/{{ModuleName}}/Public/Get-{{Prefix}}Example.ps1 b/{{ModuleName}}/Public/Get-{{Prefix}}Example.ps1 index ea095b9..e3879fd 100644 --- a/{{ModuleName}}/Public/Get-{{Prefix}}Example.ps1 +++ b/{{ModuleName}}/Public/Get-{{Prefix}}Example.ps1 @@ -37,7 +37,7 @@ function Get-{{Prefix}}Example { ) begin { - Write-Verbose "Starting Get-{{Prefix}}Example" + Write-Verbose 'Starting Get-{{Prefix}}Example' } process { @@ -51,6 +51,6 @@ function Get-{{Prefix}}Example { } end { - Write-Verbose "Completed Get-{{Prefix}}Example" + Write-Verbose 'Completed Get-{{Prefix}}Example' } }