resource/scripts/Get-MFTestDependency.ps1
|
<# .SYNOPSIS Find the source files a Pester test needs, by file name, so the test can dot-source them. .DESCRIPTION Tests in a ModuleForge project load the functions they depend on from source, rather than importing the module. This finds each file by name anywhere under the source folder, so a test keeps working when files move between folders. Returns full paths in the order given, which is the order to load them in. Throws, rather than warns, when a name is: - not found under the source folder - found more than once, so the file a test would get depends on search order - listed more than once Run it with & so it can't change the test's variables, then dot-source what it returns: $dependencies = & $helperPath -SourcePath $sourcePath -Name 'Get-Thing.ps1','Set-Thing.ps1' $dependencies.ForEach{ . $_ } Does not import or depend on ModuleForge. .EXAMPLE & .\scripts\Get-MFTestDependency.ps1 -SourcePath .\source -Name 'Get-MFFolderItems.ps1' Return the full path of Get-MFFolderItems.ps1, wherever it is under source. .OUTPUTS [string] - The full path of each file, in the order given .NOTES Author: Adrian Andersson #> [CmdletBinding()] [OutputType([string])] PARAM( #The project's source folder [Parameter(Mandatory)] [string]$SourcePath, #File names to find anywhere under the source folder, such as Get-Thing.ps1. Returned in this order [Parameter(Mandatory)] [string[]]$Name ) $listedTwice = @($Name | Group-Object | Where-Object { $_.Count -gt 1 }) if($listedTwice) { throw "Dependencies listed more than once: $($listedTwice.Name -join ', ')" } if(!(Test-Path -LiteralPath $SourcePath)) { throw "Source folder not found: $SourcePath" } #File names match case-insensitively, as they do on Windows, so a test behaves the same on every platform $sourceFiles = @{} Get-ChildItem -LiteralPath $SourcePath -Recurse -File -Filter '*.ps1' | ForEach-Object { $key = $_.Name.ToLower() if(!$sourceFiles.ContainsKey($key)){ $sourceFiles[$key] = [System.Collections.Generic.List[string]]::new() } $sourceFiles[$key].Add($_.FullName) } foreach($fileName in $Name) { $found = $sourceFiles[$fileName.ToLower()] if(!$found) { throw "Dependency $fileName not found under $SourcePath" } if($found.Count -gt 1) { throw "Dependency $fileName found more than once under $SourcePath, so which one loads is unclear: $($found -join ', ')" } $found[0] } |