Skip to content

Commit 3718339

Browse files
authored
#4: feat(#4): enhance local module path resolution and add regression tests (#28)
- Refactor Get-LocalModulePath for improved maintainability - Introduce Find-LocalModulePathMatch for path matching logic - Add Get-LocalModulePathEntryList, Get-LocalModulePathPattern, and Get-LocalModulePathErrorMessage functions - Implement tests for local module path retrieval and error handling
1 parent e627d4c commit 3718339

7 files changed

Lines changed: 109 additions & 21 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ The format follows the principles from Keep a Changelog and the project aims to
7070
- Fixed generated help activation so module and command help can be loaded with `Get-Help` after build/import.
7171
- Fixed manifest handling so unsupported `Manifest` keys now fail fast with a clear validation error instead of being
7272
silently tolerated.
73+
- Fixed local module path resolution maintainability by refactoring `Get-LocalModulePath` to Code Health `10.0` and
74+
adding regression coverage for both the matching and error paths.
7375

7476
### Documentation
7577

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function Find-LocalModulePathMatch {
2+
param(
3+
[Parameter(Mandatory)][string[]]$ModulePaths,
4+
[Parameter(Mandatory)][string]$MatchPattern,
5+
[Parameter(Mandatory)][string]$ErrorMessage
6+
)
7+
8+
$result = $ModulePaths |
9+
Where-Object {$_ -match $MatchPattern} |
10+
Select-Object -First 1
11+
12+
if ($result -and (Test-Path $result)) {
13+
return $result
14+
}
15+
16+
throw $ErrorMessage
17+
}
Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,7 @@
11
function Get-LocalModulePath {
2-
$sep = [IO.Path]::PathSeparator
3-
4-
$ModulePaths = $env:PSModulePath -split $sep | ForEach-Object { $_.Trim() } | Select-Object -Unique
2+
$modulePaths = Get-LocalModulePathEntryList
3+
$matchPattern = Get-LocalModulePathPattern
4+
$errorMessage = Get-LocalModulePathErrorMessage -MatchPattern $matchPattern
55

6-
if ($IsWindows) {
7-
$MatchPattern = '\\Documents\\PowerShell\\Modules'
8-
$Result = $ModulePaths | Where-Object { $_ -match $MatchPattern } | Select-Object -First 1
9-
if ($Result -and (Test-Path $Result)) {
10-
return $Result
11-
} else {
12-
throw "No windows module path matching $MatchPattern found"
13-
}
14-
} else {
15-
# For Mac and Linux
16-
$MatchPattern = '/\.local/share/powershell/Modules$'
17-
$Result = $ModulePaths | Where-Object { $_ -match $MatchPattern } | Select-Object -First 1
18-
if ($Result -and (Test-Path $Result)) {
19-
return $Result
20-
} else {
21-
throw "No macOS/Linux module path matching $MatchPattern found in PSModulePath."
22-
}
23-
}
6+
return Find-LocalModulePathMatch -ModulePaths $modulePaths -MatchPattern $matchPattern -ErrorMessage $errorMessage
247
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function Get-LocalModulePathEntryList {
2+
$separator = [IO.Path]::PathSeparator
3+
4+
return @(
5+
$env:PSModulePath -split $separator |
6+
ForEach-Object {$_.Trim()} |
7+
Select-Object -Unique
8+
)
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function Get-LocalModulePathErrorMessage {
2+
param(
3+
[Parameter(Mandatory)][string]$MatchPattern
4+
)
5+
6+
if ($IsWindows) {
7+
return "No windows module path matching $MatchPattern found"
8+
}
9+
10+
return "No macOS/Linux module path matching $MatchPattern found in PSModulePath."
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function Get-LocalModulePathPattern {
2+
if ($IsWindows) {
3+
return '\\Documents\\PowerShell\\Modules'
4+
}
5+
6+
return '/\.local/share/powershell/Modules$'
7+
}

tests/NovaCommandModel.Tests.ps1

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,65 @@ title: Invoke-NovaBuild
227227
}
228228
}
229229

230+
It 'Get-LocalModulePath returns the first matching local module path for the current platform' {
231+
InModuleScope $script:moduleName {
232+
$originalModulePath = $env:PSModulePath
233+
$script:expectedModulePath = if ($IsWindows) {
234+
'C:\Users\Stiwi\Documents\PowerShell\Modules'
235+
}
236+
else {
237+
'/Users/stiwi.courage/.local/share/powershell/Modules'
238+
}
239+
240+
$env:PSModulePath = if ($IsWindows) {
241+
'C:\Program Files\PowerShell\Modules;C:\Users\Stiwi\Documents\PowerShell\Modules;C:\Temp\Modules'
242+
}
243+
else {
244+
'/usr/local/share/powershell/Modules:/Users/stiwi.courage/.local/share/powershell/Modules:/tmp/modules'
245+
}
246+
247+
Mock Test-Path {
248+
param($Path)
249+
return $Path -eq $script:expectedModulePath
250+
}
251+
252+
try {
253+
Get-LocalModulePath | Should -Be $script:expectedModulePath
254+
}
255+
finally {
256+
$env:PSModulePath = $originalModulePath
257+
}
258+
}
259+
}
260+
261+
It 'Get-LocalModulePath throws a platform-specific error when no matching path exists' {
262+
InModuleScope $script:moduleName {
263+
$originalModulePath = $env:PSModulePath
264+
$env:PSModulePath = if ($IsWindows) {
265+
'C:\Program Files\PowerShell\Modules;C:\Temp\Modules'
266+
}
267+
else {
268+
'/usr/local/share/powershell/Modules:/tmp/modules'
269+
}
270+
271+
Mock Test-Path {$false}
272+
273+
$expectedError = if ($IsWindows) {
274+
'No windows module path matching*'
275+
}
276+
else {
277+
'No macOS/Linux module path matching*'
278+
}
279+
280+
try {
281+
{Get-LocalModulePath} | Should -Throw $expectedError
282+
}
283+
finally {
284+
$env:PSModulePath = $originalModulePath
285+
}
286+
}
287+
}
288+
230289
It 'built module keeps Publish-NovaModule local path resolution before build and test' {
231290
$packagedModulePath = (Get-Module $script:moduleName).Path
232291

0 commit comments

Comments
 (0)