Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions 39 Source/Private/InitializeBuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,8 @@ function InitializeBuild {
$Invocation = $(Get-Variable MyInvocation -Scope 1 -ValueOnly)
)
# NOTE: This reads the parameter values from Build-Module!
$ParameterValues = @{}
foreach($parameter in $Invocation.MyCommand.Parameters.GetEnumerator()) {
$key = $parameter.Key
if($null -ne ($value = Get-Variable -Name $key -ValueOnly -ErrorAction Ignore )) {
if($value -ne ($null -as $parameter.Value.ParameterType)) {
$ParameterValues[$key] = $value
}
}
}
# BUG BUG: needs to prioritize build.psd1 values over build-module *defaults*, but user-provided parameters over build.psd1 values
Write-Debug "Initializing build variables"

$ModuleSource = ResolveModuleSource $SourcePath
Push-Location $ModuleSource -StackName Build-Module
Expand All @@ -44,6 +37,20 @@ function InitializeBuild {
# Read a build.psd1 configuration file for default parameter values
$BuildInfo = Import-Metadata -Path (Join-Path $ModuleSource [Bb]uild.psd1)
# Combine the defaults with parameter values
$ParameterValues = @{}
foreach ($parameter in $Invocation.MyCommand.Parameters.GetEnumerator()) {
$key = $parameter.Key
# set if it doesn't exist, overwrite if the value is bound as a parameter
if (!$BuildInfo.ContainsKey($key) -or ($Invocation.BoundParameters -and $Invocation.BoundParameters.ContainsKey($key))) {
if ($null -ne ($value = Get-Variable -Name $key -ValueOnly -ErrorAction Ignore )) {
if ($value -ne ($null -as $parameter.Value.ParameterType)) {
Write-Debug " $key = $value"
$ParameterValues[$key] = $value
}
}
}
}

$BuildInfo = $BuildInfo | Update-Object $ParameterValues

# Make sure the Path is set and points at the actual manifest
Expand All @@ -63,15 +70,11 @@ function InitializeBuild {
# Update the ModuleManifest with our build configuration
$ModuleInfo = Update-Object -InputObject $ModuleInfo -UpdateObject $BuildInfo

# Ensure OutputDirectory
if (!$ModuleInfo.OutputDirectory) {
$OutputRoot = if($OutputRoot = Split-Path $ModuleSource) { $OutputRoot } else { $ModuleSource}
$OutputDirectory = Join-Path $OutputRoot "$($ModuleInfo.Version)"
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
} elseif (![IO.Path]::IsPathRooted($ModuleInfo.OutputDirectory)) {
$OutputRoot = if($OutputRoot = Split-Path $ModuleSource) { $OutputRoot } else { $ModuleSource}
$OutputDirectory = Join-Path $OutputRoot $ModuleInfo.OutputDirectory
Add-Member -Input $ModuleInfo -Type NoteProperty -Name OutputDirectory -Value $OutputDirectory -Force
# Ensure the OutputDirectory makes sense (it's never blank anymore)
if (![IO.Path]::IsPathRooted($ModuleInfo.OutputDirectory)) {
# Relative paths are relative to the build.psd1 now
$OutputDirectory = Join-Path $ModuleSource $ModuleInfo.OutputDirectory
$ModuleInfo.OutputDirectory = $OutputDirectory
}

$ModuleInfo
Expand Down
28 changes: 28 additions & 0 deletions 28 Source/Private/ResolveOutputFolder.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function ResolveOutputFolder {
[CmdletBinding()]
param(
# Where to build the module.
# Defaults to an \output folder, adjacent to the "SourcePath" folder
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$OutputDirectory,

# If set (true) adds a folder named after the version number to the OutputDirectory
[Parameter(ValueFromPipelineByPropertyName)]
[switch]$VersionedOutputDirectory,

# specifies the module version for use in the output path if -VersionedOutputDirectory is true
[Parameter(ValueFromPipelineByPropertyName)]
[Alias("ModuleVersion")]
[string]$Version
)
process {
Write-Verbose "Resolve OutputDirectory path: $OutputDirectory"
# Make sure the OutputDirectory exists (assumes we're in the module source directory)
$OutputDirectory = New-Item $OutputDirectory -ItemType Directory -Force | Convert-Path
if ($VersionedOutputDirectory -and $OutputDirectory.TrimEnd("/\") -notmatch "\d+\.\d+\.\d+$") {
$OutputDirectory = New-Item (Join-Path $OutputDirectory $Version) -ItemType Directory -Force | Convert-Path
Write-Verbose "Added ModuleVersion to OutputDirectory path: $OutputDirectory"
}
$OutputDirectory
}
}
1 change: 1 addition & 0 deletions 1 Source/Private/SetModuleContent.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function SetModuleContent {
# The FIRST and LAST items can be text content instead of file paths.
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Alias("PSPath", "FullName")]
[AllowEmptyCollection()]
[string[]]$SourceFile,

# The working directory (allows relative paths for other values)
Expand Down
45 changes: 29 additions & 16 deletions 45 Source/Public/Build-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ function Build-Module {
[string]$SourcePath = $(Get-Location -PSProvider FileSystem),

# Where to build the module.
# Defaults to a version number folder, adjacent to the module folder
# Defaults to an ..\output folder (adjacent to the "SourcePath" folder)
[Alias("Destination")]
[string]$OutputDirectory,
[string]$OutputDirectory = "..\Output",

# If set (true) adds a folder named after the version number to the OutputDirectory
[switch]$VersionedOutputDirectory,

# Semantic version, like 1.0.3-beta01+sha.22c35ffff166f34addc49a3b80e622b543199cc5
# If the SemVer has metadata (after a +), then the full Semver will be added to the ReleaseNotes
Expand Down Expand Up @@ -131,30 +134,35 @@ function Build-Module {
# BEFORE we InitializeBuild we need to "fix" the version
if($PSCmdlet.ParameterSetName -ne "SemanticVersion") {
Write-Verbose "Calculate the Semantic Version from the $Version - $Prerelease + $BuildMetadata"
$SemVer = $Version
$SemVer = "$Version"
if($Prerelease) {
$SemVer = $Version + '-' + $Prerelease
$SemVer = "$Version-$Prerelease"
}
if($BuildMetadata) {
$SemVer = $SemVer + '+' + $BuildMetadata
$SemVer = "$SemVer+$BuildMetadata"
}
}

# Push into the module source (it may be a subfolder)
$ModuleInfo = InitializeBuild $SourcePath
Write-Progress "Building $($ModuleInfo.Name)" -Status "Use -Verbose for more information"
Write-Verbose "Building $($ModuleInfo.Name)"

# Output file names
$OutputDirectory = $ModuleInfo.OutputDirectory
$OutputDirectory = $ModuleInfo | ResolveOutputFolder
$RootModule = Join-Path $OutputDirectory "$($ModuleInfo.Name).psm1"
$OutputManifest = Join-Path $OutputDirectory "$($ModuleInfo.Name).psd1"

Write-Progress "Building $($ModuleInfo.Name)" -Status "Use -Verbose for more information"
Write-Verbose "Building $($ModuleInfo.Name)"
Write-Verbose "Output to: $OutputDirectory"

if ($Target -match "Clean") {
Write-Verbose "Cleaning $OutputDirectory"
if (Test-Path $OutputDirectory) {
Remove-Item $OutputDirectory -Recurse -Force
if (Test-Path $OutputDirectory -PathType Leaf) {
throw "Unable to build. There is a file in the way at $OutputDirectory"
}
if (Test-Path $OutputDirectory -PathType Container) {
if (Get-ChildItem $OutputDirectory\*) {
Remove-Item $OutputDirectory\* -Recurse -Force
}
}
if ($Target -notmatch "Build") {
return # No build, just cleaning
Expand Down Expand Up @@ -207,11 +215,16 @@ function Build-Module {
Write-Warning "Failed to update version to $Version. $_"
}

if ($Prerelease) {
Write-Verbose "Update Manifest at $OutputManifest with Prerelease: $Prerelease"
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value $Prerelease
} else {
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value ""
if ($null -ne (Get-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -ErrorAction SilentlyContinue)) {
if ($Prerelease) {
Write-Verbose "Update Manifest at $OutputManifest with Prerelease: $Prerelease"
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value $Prerelease
} else {
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value ""
}
} elseif($Prerelease) {
Write-Warning ("Cannot set Prerelease in module manifest. Add an empty Prerelease to your module manifest, like:`n" +
' PrivateData = @{ PSData = @{ Prerelease = "" } }')
}

if ($BuildMetadata) {
Expand Down
2 changes: 2 additions & 0 deletions 2 Source/build.psd1
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@{
Path = "ModuleBuilder.psd1"
OutputDirectory = "..\"
VersionedOutputDirectory = $true
}
32 changes: 28 additions & 4 deletions 32 Tests/Private/InitializeBuild.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ Describe "InitializeBuild" {
Mock ResolveModuleSource -ModuleName ModuleBuilder { $SourcePath }
Mock ResolveModuleManifest -ModuleName ModuleBuilder { "TestDrive:\Source\MyModule.psd1" }
Mock Push-Location -ModuleName ModuleBuilder {}
Mock Import-Metadata -ModuleName ModuleBuilder { @{Path = "MyModule.psd1"} }
Mock Import-Metadata -ModuleName ModuleBuilder {
@{
Path = "MyModule.psd1"
SourceDirectories = "Classes", "Public"
}
}
#Mock Update-Object -ModuleName ModuleBuilder { $InputObject }
Mock Get-Variable -ParameterFilter {
$Name -eq "MyInvocation"
Expand All @@ -14,6 +19,7 @@ Describe "InitializeBuild" {
Target = @{ParameterType = "string"}
SourcePath = @{ParameterType = "string"}
SourceDirectories = @{ParameterType = "string[]"}
OutputDirectory = @{ParameterType = "string"}
}
}
}
Expand All @@ -33,6 +39,8 @@ Describe "InitializeBuild" {
New-Item "TestDrive:\Source\" -Type Directory

$Result = InModuleScope -ModuleName ModuleBuilder {
[CmdletBinding()]
param( $SourceDirectories = @("Enum", "Classes", "Private", "Public"), $OutputDirectory = "..\Output")
InitializeBuild -SourcePath TestDrive:\Source\
}

Expand Down Expand Up @@ -63,7 +71,11 @@ Describe "InitializeBuild" {
It "Returns the ModuleInfo combined with an OutputDirectory and Path" {
$Result.ModuleBase | Should -be "TestDrive:\Source\"
$Result.Path | Should -be "TestDrive:\Source\MyModule.psd1"
$Result.OutputDirectory | Should -be "TestDrive:\1.0.0"

Push-Location TestDrive:\
New-Item $Result.OutputDirectory -ItemType Directory -Force | Resolve-Path -Relative | Should -be ".\Output"
Pop-Location
$Result.SourceDirectories | Should -be @("Classes", "Public")
}
}

Expand Down Expand Up @@ -99,13 +111,19 @@ Describe "InitializeBuild" {
}

$Result = InModuleScope -ModuleName ModuleBuilder {
[CmdletBinding()]
param( $SourceDirectories = @("Enum", "Classes", "Private", "Public"), $OutputDirectory = "..\Output")

InitializeBuild -SourcePath TestDrive:\Source\
}

It "Treats the output path as relative to the (parent of the) ModuleSource" {
$Result.ModuleBase | Should -be "TestDrive:\Source\"
$Result.Path | Should -be "TestDrive:\Source\MyModule.psd1"
$Result.OutputDirectory | Should -be "TestDrive:\.\Output"
# Note that Build-Module will call ResolveOutputFolder with this, so the relative path here is ok
Push-Location TestDrive:\
New-Item $Result.OutputDirectory -ItemType Directory -Force | Resolve-Path -Relative | Should -be ".\Source\Output"
Pop-Location
}
}

Expand Down Expand Up @@ -147,13 +165,19 @@ Describe "InitializeBuild" {
}
}
$Result = InModuleScope -ModuleName ModuleBuilder {
[CmdletBinding()]
param( $SourceDirectories = @("Enum", "Classes", "Private", "Public"), $OutputDirectory = "..\Output")

InitializeBuild -SourcePath TestDrive:\
}

It "Treats the output path as relative to the (parent of the) ModuleSource" {
$Result.ModuleBase | Should -be "TestDrive:\"
$Result.Path | Should -be "TestDrive:\MyModule.psd1"
$Result.OutputDirectory | Should -be "TestDrive:\.\Output"
# Note that Build-Module will call ResolveOutputFolder with this, so the relative path here is ok
Push-Location TestDrive:\
New-Item $Result.OutputDirectory -ItemType Directory -Force | Resolve-Path -Relative | Should -be ".\Output"
Pop-Location
}
}
}
53 changes: 53 additions & 0 deletions 53 Tests/Private/ResolveOutputFolder.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Describe "ResolveOutputFolder" {
Import-Module ModuleBuilder -DisableNameChecking -Verbose:$False

Context "Given an OutputDirectory only" {

$Result = InModuleScope -ModuleName ModuleBuilder {
ResolveOutputFolder -OutputDirectory TestDrive:\Output
}

It "Creates the Output directory" {
$Result | Should -Be (Convert-Path "TestDrive:\Output")
$Result | Should -Exist
}
}

Context "Given an OutputDirectory and ModuleVersion but no switch" {

$Result = InModuleScope -ModuleName ModuleBuilder {
ResolveOutputFolder -OutputDirectory TestDrive:\Output -ModuleVersion "1.0.0"
}

It "Creates the Output directory" {
"TestDrive:\Output" | Should -Exist
}

It "Returns the Output directory" {
$Result | Should -Be (Convert-Path "TestDrive:\Output")
}

It "Does not creates children in Output" {
Get-ChildItem $Result | Should -BeNullOrEmpty
}
}

Context "Given an OutputDirectory, ModuleVersion and switch" {

$Result = InModuleScope -ModuleName ModuleBuilder {
ResolveOutputFolder -OutputDirectory TestDrive:\Output -ModuleVersion "1.0.0" -VersionedOutput
}

It "Creates the Output directory" {
"TestDrive:\Output" | Should -Exist
}

It "Creates the version directory" {
"TestDrive:\Output\1.0.0" | Should -Exist
}

It "Returns the Output directory" {
$Result | Should -Be (Convert-Path "TestDrive:\Output\1.0.0")
}
}
}
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.