Skip to content

Commit 6b70d04

Browse files
authored
Merge pull request #436 from PowerShellOrg/AddTests
2 parents f3f3184 + cca71cb commit 6b70d04

15 files changed

+4348
-183
lines changed

.vscode/settings.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
"files.trimTrailingWhitespace": true,
55
"files.insertFinalNewline": true,
66
"editor.insertSpaces": true,
7+
"editor.tabSize": 4,
78
// -------- Search configuration --------
89
// Exclude the Output folder from search results.
910
"search.exclude": {
10-
"Output/**": true,
11+
"Output": true,
1112
},
1213
//-------- PowerShell Configuration --------
1314
// Use a custom PowerShell Script Analyzer settings file for this workspace.
@@ -17,4 +18,4 @@
1718
"powershell.codeFormatting.preset": "OTBS",
1819
"editor.formatOnSave": true,
1920
"powershell.scriptAnalysis.enable": true
20-
}
21+
}

Plaster/Public/Get-ModuleExtension.ps1 renamed to Plaster/Private/Get-ModuleExtension.ps1

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
11
function Get-ModuleExtension {
2+
<#
3+
.SYNOPSIS
4+
Retrieves module extensions based on specified criteria.
5+
6+
.DESCRIPTION
7+
This function retrieves module extensions that match the specified module
8+
name and version criteria.
9+
10+
.PARAMETER ModuleName
11+
The name of the module to retrieve extensions for.
12+
13+
.PARAMETER ModuleVersion
14+
The version of the module to retrieve extensions for.
15+
16+
.PARAMETER ListAvailable
17+
Indicates whether to list all available modules or only the the latest
18+
version of each module.
19+
20+
.EXAMPLE
21+
Get-ModuleExtension -ModuleName "MyModule" -ModuleVersion "1.0.0"
22+
23+
Retrieves extensions for the module "MyModule" with version "1.0.0".
24+
.NOTES
25+
26+
#>
227
[CmdletBinding()]
328
param(
429
[string]
@@ -11,9 +36,9 @@ function Get-ModuleExtension {
1136
$ListAvailable
1237
)
1338

14-
#Only get the latest version of each module
39+
# Only get the latest version of each module
1540
$modules = Get-Module -ListAvailable
16-
if (!$ListAvailable) {
41+
if (!$ListAvailable.IsPresent) {
1742
$modules = $modules |
1843
Group-Object Name |
1944
ForEach-Object {
@@ -25,28 +50,6 @@ function Get-ModuleExtension {
2550

2651
Write-Verbose "Found $($modules.Length) installed modules to scan for extensions."
2752

28-
function ParseVersion($versionString) {
29-
$parsedVersion = $null
30-
31-
if ($versionString) {
32-
# We're targeting Semantic Versioning 2.0 so make sure the version has
33-
# at least 3 components (X.X.X). This logic ensures that the "patch"
34-
# (third) component has been specified.
35-
$versionParts = $versionString.Split('.')
36-
if ($versionParts.Length -lt 3) {
37-
$versionString = "$versionString.0"
38-
}
39-
40-
if ($PSVersionTable.PSEdition -eq "Core") {
41-
$parsedVersion = New-Object -TypeName "System.Management.Automation.SemanticVersion" -ArgumentList $versionString
42-
} else {
43-
$parsedVersion = New-Object -TypeName "System.Version" -ArgumentList $versionString
44-
}
45-
}
46-
47-
return $parsedVersion
48-
}
49-
5053
foreach ($module in $modules) {
5154
if ($module.PrivateData -and
5255
$module.PrivateData.PSData -and
@@ -58,8 +61,18 @@ function Get-ModuleExtension {
5861

5962
Write-Verbose "Comparing against module extension: $($extension.Module)"
6063

61-
$minimumVersion = ParseVersion $extension.MinimumVersion
62-
$maximumVersion = ParseVersion $extension.MaximumVersion
64+
if ([String]::IsNullOrEmpty($extension.MinimumVersion)) {
65+
# Fill with a default value if not specified
66+
$minimumVersion = $null
67+
} else {
68+
$minimumVersion = Resolve-ModuleVersionString $extension.MinimumVersion
69+
}
70+
if ([String]::IsNullOrEmpty($extension.MaximumVersion)) {
71+
# Fill with a default value if not specified
72+
$maximumVersion = $null
73+
} else {
74+
$maximumVersion = Resolve-ModuleVersionString $extension.MaximumVersion
75+
}
6376

6477
if (($extension.Module -eq $ModuleName) -and
6578
(!$minimumVersion -or $ModuleVersion -ge $minimumVersion) -and
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
function Get-PlasterManifestPathForCulture {
2+
<#
3+
.SYNOPSIS
4+
Returns the path to the Plaster manifest file for a specific culture.
5+
6+
.DESCRIPTION
7+
This function checks for the existence of a Plaster manifest file that
8+
matches the specified culture. It first looks for a culture-specific
9+
manifest, then checks for a parent culture manifest, and finally falls back
10+
to an invariant culture manifest if no specific match is found. The function
11+
returns the path to the manifest file if found, or $null if no matching
12+
manifest is found.
13+
14+
.PARAMETER TemplatePath
15+
The path to the template directory.
16+
This should be a fully qualified path to the directory containing the
17+
Plaster manifest files.
18+
19+
.PARAMETER Culture
20+
The culture information for which to retrieve the Plaster manifest file.
21+
22+
.EXAMPLE
23+
GetPlasterManifestPathForCulture -TemplatePath "C:\Templates" -Culture (Get-Culture)
24+
25+
This example retrieves the path to the Plaster manifest file for the current culture.
26+
.NOTES
27+
This is a private function used by Plaster to locate the appropriate
28+
manifest file based on the specified culture.
29+
#>
30+
[CmdletBinding()]
31+
[OutputType([String])]
32+
param (
33+
[string]
34+
$TemplatePath,
35+
[ValidateNotNull()]
36+
[CultureInfo]
37+
$Culture
38+
)
39+
if (![System.IO.Path]::IsPathRooted($TemplatePath)) {
40+
$TemplatePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($TemplatePath)
41+
}
42+
43+
# Check for culture-locale first.
44+
$plasterManifestBasename = "plasterManifest"
45+
$plasterManifestFilename = "${plasterManifestBasename}_$($culture.Name).xml"
46+
$plasterManifestPath = Join-Path $TemplatePath $plasterManifestFilename
47+
if (Test-Path $plasterManifestPath) {
48+
return $plasterManifestPath
49+
}
50+
51+
# Check for culture next.
52+
if ($culture.Parent.Name) {
53+
$plasterManifestFilename = "${plasterManifestBasename}_$($culture.Parent.Name).xml"
54+
$plasterManifestPath = Join-Path $TemplatePath $plasterManifestFilename
55+
if (Test-Path $plasterManifestPath) {
56+
return $plasterManifestPath
57+
}
58+
}
59+
60+
# Fallback to invariant culture manifest.
61+
$plasterManifestPath = Join-Path $TemplatePath "${plasterManifestBasename}.xml"
62+
if (Test-Path $plasterManifestPath) {
63+
return $plasterManifestPath
64+
}
65+
66+
# If no manifest is found, return $null.
67+
# TODO: Should we throw an error instead?
68+
return $null
69+
}

Plaster/Private/GetPlasterManifestPathForCulture.ps1

Lines changed: 0 additions & 38 deletions
This file was deleted.

Plaster/Private/InitializePredefinedVariables.ps1 renamed to Plaster/Private/Initialize-PredefinedVariables.ps1

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,37 @@
1-
function InitializePredefinedVariables {
1+
function Initialize-PredefinedVariables {
2+
<#
3+
.SYNOPSIS
4+
Initializes predefined variables used by Plaster.
5+
6+
.DESCRIPTION
7+
This function sets up several predefined variables that are used throughout
8+
the Plaster template processing. It includes variables for the template
9+
path, destination path, and other relevant information.
10+
11+
.PARAMETER TemplatePath
12+
The file system path to the Plaster template directory.
13+
14+
.PARAMETER DestPath
15+
The file system path to the destination directory.
16+
17+
.EXAMPLE
18+
Initialize-PredefinedVariables -TemplatePath "C:\Templates\MyTemplate" -DestPath "C:\Projects\MyProject"
19+
20+
This example initializes the predefined variables with the specified
21+
template and destination paths.
22+
.NOTES
23+
This function is typically called at the beginning of the Plaster template
24+
processing to ensure that all necessary variables are set up before any
25+
template processing occurs.
26+
#>
227
[CmdletBinding()]
328
param(
429
[string]
530
$TemplatePath,
631
[string]
732
$DestPath
833
)
34+
935
# Always set these variables, even if the command has been run with -WhatIf
1036
$WhatIfPreference = $false
1137

@@ -28,4 +54,4 @@ function InitializePredefinedVariables {
2854
Set-Variable -Name PLASTER_Date -Value ($now.ToShortDateString()) -Scope Script
2955
Set-Variable -Name PLASTER_Time -Value ($now.ToShortTimeString()) -Scope Script
3056
Set-Variable -Name PLASTER_Year -Value ($now.Year) -Scope Script
31-
}
57+
}
Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,59 @@
11
# Enhanced error handling wrapper
22
function Invoke-PlasterOperation {
3+
<#
4+
.SYNOPSIS
5+
Wraps the execution of a script block with enhanced error handling and
6+
logging capabilities.
7+
8+
.DESCRIPTION
9+
This function wraps the execution of a script block with enhanced error
10+
handling and logging capabilities.
11+
12+
.PARAMETER ScriptBlock
13+
The script block to execute.
14+
15+
.PARAMETER OperationName
16+
The name of the operation being performed.
17+
18+
.PARAMETER PassThru
19+
If specified, the output of the script block output will be returned.
20+
21+
.EXAMPLE
22+
Invoke-PlasterOperation -ScriptBlock { Get-Process } -OperationName 'GetProcesses' -PassThru
23+
24+
This example executes the `Get-Process` cmdlet within the context of the
25+
`Invoke-PlasterOperation` function, logging the operation and returning the
26+
output.
27+
28+
.NOTES
29+
This function is designed to be used within the Plaster module to ensure
30+
consistent logging and error handling across various operations.
31+
It is not intended for direct use outside of the Plaster context.
32+
#>
333
[CmdletBinding()]
434
param(
535
[Parameter(Mandatory)]
6-
[scriptblock]$ScriptBlock,
36+
[scriptblock]
37+
$ScriptBlock,
738

8-
[string]$OperationName = 'PlasterOperation',
39+
[string]
40+
$OperationName = 'PlasterOperation',
941

10-
[switch]$PassThru
42+
[switch]
43+
$PassThru
1144
)
1245

1346
try {
1447
Write-PlasterLog -Level Debug -Message "Starting operation: $OperationName"
1548
$result = & $ScriptBlock
1649
Write-PlasterLog -Level Debug -Message "Completed operation: $OperationName"
1750

18-
if ($PassThru) {
51+
if ($PassThru.IsPresent) {
1952
return $result
2053
}
2154
} catch {
2255
$errorMessage = "Operation '$OperationName' failed: $($_.Exception.Message)"
2356
Write-PlasterLog -Level Error -Message $errorMessage
2457
throw $_
2558
}
26-
}
59+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function Resolve-ModuleVersionString {
2+
<#
3+
.SYNOPSIS
4+
Resolve a module version string to a System.Version or
5+
System.Management.Automation.SemanticVersion object.
6+
7+
.DESCRIPTION
8+
This function takes a version string and returns a parsed version object.
9+
It ensures that the version string is in a valid format, particularly for
10+
Semantic Versioning 2.0, which requires at least three components
11+
(major.minor.patch). If the patch component is missing, the function will
12+
append ".0" to the version string.
13+
14+
.PARAMETER versionString
15+
The version string to resolve.
16+
17+
.EXAMPLE
18+
Resolve-ModuleVersionString -versionString "1.2"
19+
20+
This example resolves the version string "1.2" to a valid version object.
21+
.NOTES
22+
This function is designed to be used within the Plaster module to ensure consistent version handling.
23+
It is not intended for direct use outside of the Plaster context.
24+
#>
25+
param(
26+
[Parameter(Mandatory, Position = 0)]
27+
[ValidateNotNullOrEmpty()]
28+
$VersionString
29+
)
30+
31+
# We're targeting Semantic Versioning 2.0 so make sure the version has
32+
# at least 3 components (X.X.X). This logic ensures that the "patch"
33+
# (third) component has been specified.
34+
$versionParts = $VersionString.Split('.')
35+
if ($versionParts.Length -lt 3) {
36+
$VersionString = "$VersionString.0"
37+
}
38+
39+
if ($PSVersionTable.PSEdition -eq "Core") {
40+
$newObjectSplat = @{
41+
TypeName = "System.Management.Automation.SemanticVersion"
42+
ArgumentList = $VersionString
43+
}
44+
return New-Object @newObjectSplat
45+
} else {
46+
$newObjectSplat = @{
47+
TypeName = "System.Version"
48+
ArgumentList = $VersionString
49+
}
50+
return New-Object @newObjectSplat
51+
}
52+
}

0 commit comments

Comments
 (0)