Skip to content

Commit 6621427

Browse files
committed
Extract (and test) InitializeBuild
This is purely an internal function to make it easier to test
1 parent c9c0793 commit 6621427

3 files changed

Lines changed: 147 additions & 37 deletions

File tree

Source/Private/InitializeBuild.ps1

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
function InitializeBuild {
2+
<#
3+
.SYNOPSIS
4+
Loads build.psd1 and the module manifest and combines them with the parameter values of the calling function. Pushes location to the module source location.
5+
.DESCRIPTION
6+
This function is for internal use from Build-Module only
7+
It does two things that make it really only work properly there:
8+
9+
1. It calls Push-Location without Pop-Location to push the SourcePath into the "Build-Module" stack
10+
2. It reads the ParameterValues from the PARENT MyInvocation
11+
.NOTES
12+
Depends on the internal ResolveModuleSource and ResolveModuleManifest
13+
Depends on the Configuration module Update-Object and (the built in Import-LocalizedData and Get-Module)
14+
#>
15+
[CmdletBinding()]
16+
param(
17+
# The root folder where the module source is (including the Build.psd1 and the module Manifest.psd1)
18+
[string]$SourcePath
19+
)
20+
# Read the caller's parameter values
21+
$ParameterValues = @{}
22+
foreach($parameter in (Get-Variable MyInvocation -Scope 1 -ValueOnly).MyCommand.Parameters.GetEnumerator()) {
23+
$key = $parameter.Key
24+
if($null -ne ($value = Get-Variable -Name $key -ValueOnly -ErrorAction Ignore )) {
25+
if($value -ne ($null -as $parameter.Value.ParameterType)) {
26+
$ParameterValues[$key] = $value
27+
}
28+
}
29+
}
30+
31+
$ModuleSource = ResolveModuleSource $SourcePath
32+
Push-Location $ModuleSource -StackName Build-Module
33+
34+
# These errors are caused by trying to parse valid module manifests without compiling the module first
35+
$ErrorsWeIgnore = "^" + @(
36+
"Modules_InvalidRequiredModulesinModuleManifest"
37+
"Modules_InvalidRootModuleInModuleManifest"
38+
) -join "|^"
39+
40+
# Read a build.psd1 configuration file for default parameter values
41+
$BuildInfo = Import-Metadata -Path (Join-Path $ModuleSource [Bb]uild.psd1)
42+
# Combine the defaults with parameter values
43+
$BuildInfo = $BuildInfo | Update-Object $ParameterValues
44+
45+
# Make sure the Path is set and points at the actual manifest
46+
$BuildInfo.Path = ResolveModuleManifest $ModuleSource $BuildInfo.Path
47+
48+
# Finally, add all the information in the module manifest to the return object
49+
$ModuleInfo = Get-Module $BuildInfo.Path -ListAvailable -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -ErrorVariable Problems
50+
51+
# If there are any problems that count, fail
52+
if ($Problems = $Problems.Where({$_.FullyQualifiedErrorId -notmatch $ErrorsWeIgnore})) {
53+
foreach ($problem in $Problems) {
54+
Write-Error $problem
55+
}
56+
throw "Unresolvable problems in module manifest"
57+
}
58+
59+
# Update the ModuleManifest with our build configuration
60+
$ModuleInfo = Update-Object -InputObject $ModuleInfo -UpdateObject $BuildInfo
61+
62+
# Ensure OutputDirectory
63+
if (!$ModuleInfo.OutputDirectory) {
64+
$OutputRoot = if($OutputRoot = Split-Path $ModuleSource) { $OutputRoot } else { $ModuleSource}
65+
$OutputDirectory = Join-Path $OutputRoot "$($ModuleInfo.Version)"
66+
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
67+
} elseif (![IO.Path]::IsPathRooted($ModuleInfo.OutputDirectory)) {
68+
$OutputRoot = if($OutputRoot = Split-Path $ModuleSource) { $OutputRoot } else { $ModuleSource}
69+
$OutputDirectory = Join-Path $OutputRoot $ModuleInfo.OutputDirectory
70+
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
71+
}
72+
73+
$ModuleInfo
74+
}

Source/Public/Build-Module.ps1

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -108,47 +108,16 @@ function Build-Module {
108108
}
109109
process {
110110
try {
111-
$ModuleSource = ResolveModuleSource $SourcePath
112-
Push-Location $ModuleSource -StackName Optimize-Module
113-
114-
# Read a build.psd1 configuration file for default parameter values
115-
$BuildInfo = @{} + (Import-LocalizedData -BaseDirectory $ModuleSource -FileName Build -ErrorAction SilentlyContinue)
116-
# Then update it from PSBoundParameters + default parameter values
117-
$BuildInfo = $BuildInfo | Update-Object $MyInvocation.ParameterValues
118-
$BuildInfo.Path = ResolveModuleManifest $ModuleSource $BuildInfo.Path
119-
120-
# Read the Module Manifest
121-
$ModuleInfo = Get-Module $BuildInfo.Path -ListAvailable -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -ErrorVariable Problems
122-
if ($Problems) {
123-
$Problems = $Problems.Where{ $_.FullyQualifiedErrorId -notmatch "^Modules_InvalidRequiredModulesinModuleManifest|^Modules_InvalidRootModuleInModuleManifest"}
124-
if ($Problems) {
125-
foreach ($problem in $Problems) {
126-
Write-Error $problem
127-
}
128-
throw "Unresolvable problems in module manifest"
129-
}
130-
}
131-
# Update the ModuleManifest with our build configuration
132-
$ModuleInfo = Update-Object -InputObject $ModuleInfo -UpdateObject $BuildInfo
133-
134-
# Ensure OutputDirectory
135-
if (!$ModuleInfo.OutputDirectory) {
136-
$OutputDirectory = Join-Path (Split-Path $ModuleInfo.ModuleBase -Parent) "$($ModuleInfo.Version)"
137-
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
138-
} elseif (![IO.Path]::IsPathRooted($ModuleInfo.OutputDirectory)) {
139-
$OutputDirectory = Join-Path (Split-Path $ModuleInfo.ModuleBase -Parent) $ModuleInfo.OutputDirectory
140-
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
141-
}
142-
111+
# Push into the module source (it may be a subfolder)
112+
$ModuleInfo = InitializeBuild $SourcePath
113+
# Output file names
143114
$OutputDirectory = $ModuleInfo.OutputDirectory
115+
$RootModule = Join-Path $OutputDirectory "$($ModuleInfo.Name).psm1"
116+
$OutputManifest = Join-Path $OutputDirectory "$($ModuleInfo.Name).psd1"
144117

145118
Write-Progress "Building $($ModuleInfo.Name)" -Status "Use -Verbose for more information"
146119
Write-Verbose "Building $($ModuleInfo.Name)"
147-
Write-Verbose " Output to: $OutputDirectory"
148-
149-
# File names
150-
$RootModule = Join-Path $OutputDirectory "$($ModuleInfo.Name).psm1"
151-
$OutputManifest = Join-Path $OutputDirectory "$($ModuleInfo.Name).psd1"
120+
Write-Verbose "Output to: $OutputDirectory"
152121

153122
if ($Target -match "Clean") {
154123
Write-Verbose "Cleaning $OutputDirectory"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Describe "InitializeBuild" {
2+
Context "It collects the initial data" {
3+
Mock ResolveModuleSource -ModuleName ModuleBuilder { $SourcePath }
4+
Mock ResolveModuleManifest -ModuleName ModuleBuilder { "TestDrive:\Source\MyModule.psd1" }
5+
Mock Push-Location -ModuleName ModuleBuilder {}
6+
Mock Import-Metadata -ModuleName ModuleBuilder { @{Path = "MyModule.psd1"} }
7+
#Mock Update-Object -ModuleName ModuleBuilder { $InputObject }
8+
Mock Get-Variable -ParameterFilter {
9+
$Name -eq "MyInvocation"
10+
} -ModuleName ModuleBuilder {
11+
@{
12+
MyCommand = @{
13+
Parameters = @{
14+
Encoding = @{ParameterType = "string"}
15+
Target = @{ParameterType = "string"}
16+
SourcePath = @{ParameterType = "string"}
17+
SourceDirectories = @{ParameterType = "string[]"}
18+
}
19+
}
20+
}
21+
}
22+
Mock Get-Module -ModuleName ModuleBuilder {
23+
[PSCustomObject]@{
24+
ModuleBase = "TestDrive:\Source\"
25+
Author = "Test Manager"
26+
Version = [Version]"1.0.0"
27+
Name = "MyModule"
28+
RootModule = "MyModule.psm1"
29+
}
30+
}
31+
New-Item "TestDrive:\Source\" -Type Directory
32+
33+
$Result = InModuleScope -ModuleName ModuleBuilder {
34+
InitializeBuild -SourcePath TestDrive:\Source\
35+
}
36+
37+
It "Resolves the module source path" {
38+
Assert-MockCalled ResolveModuleSource -ModuleName ModuleBuilder -ParameterFilter {
39+
$SourcePath -eq "TestDrive:\Source\"
40+
}
41+
}
42+
43+
It "Pushes the module source path" {
44+
Assert-MockCalled Push-Location -ModuleName ModuleBuilder -ParameterFilter {
45+
$StackName -eq "Build-Module" -and $Path -eq "TestDrive:\Source\"
46+
}
47+
}
48+
49+
It "Parses the build.psd1" {
50+
Assert-MockCalled Import-Metadata -ModuleName ModuleBuilder -ParameterFilter {
51+
$Path -eq "TestDrive:\Source\[Bb]uild.psd1"
52+
}
53+
}
54+
55+
It "Calls Get-Module with a fully-qualified path to the manifest" {
56+
Assert-MockCalled Get-Module -ModuleName ModuleBuilder -ParameterFilter {
57+
$Name -eq "TestDrive:\Source\MyModule.psd1"
58+
}
59+
}
60+
61+
It "Returns the ModuleInfo combined with an OutputDirectory and Path" {
62+
$Result.ModuleBase | Should -be "TestDrive:\Source\"
63+
$Result.Path | Should -be "TestDrive:\Source\MyModule.psd1"
64+
$Result.OutputDirectory | Should -be "TestDrive:\1.0.0"
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)