diff --git a/Source/Private/InitializeBuild.ps1 b/Source/Private/InitializeBuild.ps1 index 05927bc..bdd0c42 100644 --- a/Source/Private/InitializeBuild.ps1 +++ b/Source/Private/InitializeBuild.ps1 @@ -33,6 +33,28 @@ function InitializeBuild { ) -join ' ')" $BuildInfo = GetBuildInfo -BuildManifest $BuildManifest -BuildCommandInvocation $BuildCommandInvocation + # Normalize the version (if it was passed in via build.psd1) + if ($BuildInfo.SemVer) { + Write-Verbose "Update the Version, Prerelease, and BuildMetadata from the SemVer (in case it was passed in via build.psd1)" + $BuildInfo = $BuildInfo | Update-Object @{ + Version = if (($V = $BuildInfo.SemVer.Split("+")[0].Split("-", 2)[0])) { + [version]$V + } + Prerelease = $BuildInfo.SemVer.Split("+")[0].Split("-", 2)[1] + BuildMetadata = $BuildInfo.SemVer.Split("+", 2)[1] + } + } elseif($BuildInfo.Version) { + Write-Verbose "Calculate the Semantic Version from the Version - Prerelease + BuildMetadata" + $SemVer = "$($BuildInfo.Version)" + if ($BuildInfo.Prerelease) { + $SemVer = "$SemVer-$($BuildInfo.Prerelease)" + } + if ($BuildInfo.BuildMetadata) { + $SemVer = "$SemVer+$($BuildInfo.BuildMetadata)" + } + $BuildInfo = $BuildInfo | Update-Object @{ SemVer = $SemVer } + } + # Override VersionedOutputDirectory with UnversionedOutputDirectory if ($BuildInfo.UnversionedOutputDirectory -and $BuildInfo.VersionedOutputDirectory) { $BuildInfo.VersionedOutputDirectory = $false diff --git a/Source/Public/Build-Module.ps1 b/Source/Public/Build-Module.ps1 index 88bf6ef..f2c80c4 100644 --- a/Source/Public/Build-Module.ps1 +++ b/Source/Public/Build-Module.ps1 @@ -32,8 +32,6 @@ function Build-Module { Build-Module -SemVer $gitVersion This example shows how to use a semantic version from gitversion to version your build. - Note, this is how we version ModuleBuilder, so if you want to see it in action, check out our azure-pipelines.yml - https://github.com/PoshCode/ModuleBuilder/blob/master/azure-pipelines.yml #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Build is approved now")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseCmdletCorrectly", "")] @@ -150,18 +148,6 @@ function Build-Module { } process { try { - # 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" - if($Prerelease) { - $SemVer = "$Version-$Prerelease" - } - if($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" @@ -169,7 +155,7 @@ function Build-Module { # Ensure the OutputDirectory (exists for build, or is cleaned otherwise) $OutputDirectory = $ModuleInfo | ResolveOutputFolder - if ($Target -notmatch "Build") { + if ($ModuleInfo.Target -notmatch "Build") { return } $RootModule = Join-Path $OutputDirectory "$($ModuleInfo.Name).psm1" @@ -177,7 +163,7 @@ function Build-Module { Write-Verbose "Output to: $OutputDirectory" # Skip the build if it's up to date already - Write-Verbose "Target $Target" + Write-Verbose "Target $($ModuleInfo.Target)" $NewestBuild = (Get-Item $RootModule -ErrorAction SilentlyContinue).LastWriteTime $IsNew = Get-ChildItem $ModuleInfo.ModuleBase -Recurse | Where-Object LastWriteTime -gt $NewestBuild | @@ -185,7 +171,7 @@ function Build-Module { if ($null -eq $IsNew) { # This is mostly for testing ... - if ($Passthru) { + if ($ModuleInfo.Passthru) { Get-Module $OutputManifest -ListAvailable } return # Skip the build @@ -240,31 +226,31 @@ function Build-Module { } try { - if ($Version) { - Write-Verbose "Update Manifest at $OutputManifest with version: $Version" - Update-Metadata -Path $OutputManifest -PropertyName ModuleVersion -Value $Version + if ($ModuleInfo.Version) { + Write-Verbose "Update Manifest at $OutputManifest with version: $($ModuleInfo.Version)" + Update-Metadata -Path $OutputManifest -PropertyName ModuleVersion -Value $ModuleInfo.Version } } catch { - Write-Warning "Failed to update version to $Version. $_" + Write-Warning "Failed to update version to $($ModuleInfo.Version). $_" } 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 + if ($ModuleInfo.Prerelease) { + Write-Verbose "Update Manifest at $OutputManifest with Prerelease: $($ModuleInfo.Prerelease)" + Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value $ModuleInfo.Prerelease } elseif ($PSCmdlet.ParameterSetName -eq "SemanticVersion" -or $PSBoundParameters.ContainsKey("Prerelease")) { Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value "" } - } elseif($Prerelease) { + } elseif ($ModuleInfo.Prerelease) { Write-Warning ("Cannot set Prerelease in module manifest. Add an empty Prerelease to your module manifest, like:`n" + ' PrivateData = @{ PSData = @{ Prerelease = "" } }') } - if ($BuildMetadata) { - Write-Verbose "Update Manifest at $OutputManifest with metadata: $BuildMetadata from $SemVer" + if ($ModuleInfo.BuildMetadata) { + Write-Verbose "Update Manifest at $OutputManifest with metadata: $($ModuleInfo.BuildMetadata) from $($ModuleInfo.SemVer)" $RelNote = Get-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.ReleaseNotes -ErrorAction SilentlyContinue if ($null -ne $RelNote) { - $Line = "$($ModuleInfo.Name) v$($SemVer)" + $Line = "$($ModuleInfo.Name) v$($($ModuleInfo.SemVer))" if ([string]::IsNullOrWhiteSpace($RelNote)) { Write-Verbose "New ReleaseNotes:`n$Line" Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.ReleaseNotes -Value $Line @@ -284,7 +270,7 @@ function Build-Module { } # This is mostly for testing ... - if ($Passthru) { + if ($ModuleInfo.Passthru) { Get-Module $OutputManifest -ListAvailable } } finally { diff --git a/Tests/Integration/Parameters.Tests.ps1 b/Tests/Integration/Parameters.Tests.ps1 new file mode 100644 index 0000000..6206696 --- /dev/null +++ b/Tests/Integration/Parameters.Tests.ps1 @@ -0,0 +1,29 @@ +#requires -Module ModuleBuilder +. $PSScriptRoot\..\Convert-FolderSeparator.ps1 + +Describe "Parameters.Set in build manifest" -Tag Integration { + BeforeAll { + New-Item $PSScriptRoot\Result3\Parameters\ReadMe.md -ItemType File -Force + $Output = Build-Module $PSScriptRoot\Parameters\build.psd1 + if ($Output) { + $Module = [IO.Path]::ChangeExtension($Output.Path, "psm1") + $Metadata = Import-Metadata $Output.Path + } + } + + It "Passthru works" { + $Output | Should -Not -BeNullOrEmpty + } + + It "The Target is Build" { + "$PSScriptRoot\Result3\Parameters\ReadMe.md" | Should -Exist + } + + It "The version is set" { + $Metadata.ModuleVersion | Should -Be "3.0.0" + } + + It "The PreRelease is set" { + $Metadata.PrivateData.PSData.Prerelease | Should -Be 'alpha001' + } +} diff --git a/Tests/Integration/Parameters/Parameters.psd1 b/Tests/Integration/Parameters/Parameters.psd1 new file mode 100644 index 0000000..fa936e4 --- /dev/null +++ b/Tests/Integration/Parameters/Parameters.psd1 @@ -0,0 +1,56 @@ +@{ + # The module version should be SemVer.org compatible + ModuleVersion = "1.0.0" + + # PrivateData is where all third-party metadata goes + PrivateData = @{ + # PrivateData.PSData is the PowerShell Gallery data + PSData = @{ + # Prerelease string should be here, so we can set it + Prerelease = '' + + # Release Notes have to be here, so we can update them + ReleaseNotes = ' + A test module + ' + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = 'Authoring','Build','Development','BestPractices' + + # A URL to the license for this module. + LicenseUri = 'https://github.com/PoshCode/ModuleBuilder/blob/master/LICENSE' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/PoshCode/ModuleBuilder' + + # A URL to an icon representing this module. + IconUri = 'https://github.com/PoshCode/ModuleBuilder/blob/resources/ModuleBuilder.png?raw=true' + } # End of PSData + } # End of PrivateData + + # The main script module that is automatically loaded as part of this module + RootModule = 'Parameters.psm1' + + # Modules that must be imported into the global environment prior to importing this module + RequiredModules = @() + + # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. + DefaultCommandPrefix = 'Param' + + # Always define FunctionsToExport as an empty @() which will be replaced on build + FunctionsToExport = @() + AliasesToExport = @() + + # ID used to uniquely identify this module + GUID = 'a264e183-e0f7-4219-bc80-c30d14e0e98e' + Description = 'A module for authoring and building PowerShell modules' + + # Common stuff for all our modules: + CompanyName = 'PoshCode' + Author = 'Joel Bennett' + Copyright = "Copyright 2024 Joel Bennett" + + # Minimum version of the Windows PowerShell engine required by this module + PowerShellVersion = '5.1' + CompatiblePSEditions = @('Core','Desktop') +} diff --git a/Tests/Integration/Parameters/Private/GetFinale.ps1 b/Tests/Integration/Parameters/Private/GetFinale.ps1 new file mode 100644 index 0000000..b6ed530 --- /dev/null +++ b/Tests/Integration/Parameters/Private/GetFinale.ps1 @@ -0,0 +1,7 @@ +using module ModuleBuilder + +function GetFinale { + [CmdletBinding()] + # [Alias("gf")] + param() +} diff --git a/Tests/Integration/Parameters/Private/GetMyAlias.ps1 b/Tests/Integration/Parameters/Private/GetMyAlias.ps1 new file mode 100644 index 0000000..dcfd009 --- /dev/null +++ b/Tests/Integration/Parameters/Private/GetMyAlias.ps1 @@ -0,0 +1 @@ +New-Alias -Name 'Get-MyAlias' -Value 'Get-ChildItem' diff --git a/Tests/Integration/Parameters/Private/GetPreview.ps1 b/Tests/Integration/Parameters/Private/GetPreview.ps1 new file mode 100644 index 0000000..1c822c5 --- /dev/null +++ b/Tests/Integration/Parameters/Private/GetPreview.ps1 @@ -0,0 +1,7 @@ +using module ModuleBuilder + +function GetPreview { + [CmdletBinding()] + # [Alias("gp")] + param() +} diff --git a/Tests/Integration/Parameters/Private/TestUnExportedAliases.ps1 b/Tests/Integration/Parameters/Private/TestUnExportedAliases.ps1 new file mode 100644 index 0000000..10e9fa0 --- /dev/null +++ b/Tests/Integration/Parameters/Private/TestUnExportedAliases.ps1 @@ -0,0 +1,13 @@ +function TestUnExportedAliases { + [CmdletBinding()] + param() + + New-Alias -Name 'New-NotExportedAlias1' -Value 'Write-Verbose' + Set-Alias -Name 'New-NotExportedAlias2' -Value 'Write-Verbose' +} + +New-Alias -Name 'New-NotExportedAlias3' -Value 'Write-Verbose' -Scope Global +Set-Alias -Name 'New-NotExportedAlias4' -Value 'Write-Verbose' -Scope Global + +New-Alias -Name 'New-NotExportedAlias5' -Value 'Write-Verbose' +Remove-Alias -Name 'New-NotExportedAlias5' diff --git a/Tests/Integration/Parameters/Public/Get-Source.ps1 b/Tests/Integration/Parameters/Public/Get-Source.ps1 new file mode 100644 index 0000000..dd4f19d --- /dev/null +++ b/Tests/Integration/Parameters/Public/Get-Source.ps1 @@ -0,0 +1,7 @@ +using module ModuleBuilder + +function Get-Source { + [CmdletBinding()] + [Alias("gs","gsou")] + param() +} diff --git a/Tests/Integration/Parameters/Public/Set-Source.ps1 b/Tests/Integration/Parameters/Public/Set-Source.ps1 new file mode 100644 index 0000000..c4c9cb5 --- /dev/null +++ b/Tests/Integration/Parameters/Public/Set-Source.ps1 @@ -0,0 +1,6 @@ +function Set-Source { + [CmdletBinding()] + [Alias("ss", "ssou")] + param() + "sto͞o′pĭd" +} diff --git a/Tests/Integration/Parameters/build.psd1 b/Tests/Integration/Parameters/build.psd1 new file mode 100644 index 0000000..67c7be4 --- /dev/null +++ b/Tests/Integration/Parameters/build.psd1 @@ -0,0 +1,7 @@ +@{ + Path = "Parameters.psd1" + OutputDirectory = "..\Result3" + SemVer = "3.0.0-alpha001" + Target = "Build" + Passthru = $true +} diff --git a/Tests/Integration/Result3/Parameters/ReadMe.md b/Tests/Integration/Result3/Parameters/ReadMe.md new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Public/Build-Module.Tests.ps1 b/Tests/Public/Build-Module.Tests.ps1 index de766ea..268e9fe 100644 --- a/Tests/Public/Build-Module.Tests.ps1 +++ b/Tests/Public/Build-Module.Tests.ps1 @@ -257,14 +257,14 @@ Describe "Build-Module" { New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule/$ExpectedVersion" -Force - Mock InitializeBuild { - # These are actually all the values that we need + Mock ResolveBuildManifest { "TestDrive:/MyModule/build.psd1" } + + Mock GetBuildInfo { [PSCustomObject]@{ OutputDirectory = "TestDrive:/Output" - Name = "MyModule" - Version = $Version + SourcePath = "TestDrive:/MyModule/" + SemVer = $SemVer Target = $Target - ModuleBase = "TestDrive:/MyModule/" CopyPaths = @() Encoding = "UTF8" PublicFilter = "Public/*.ps1" @@ -272,6 +272,13 @@ Describe "Build-Module" { } } + Mock ImportModuleManifest { + [PSCustomObject]@{ + Name = "MyModule" + ModuleBase = "TestDrive:/MyModule/" + } + } + $global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/Output/MyModule/$ExpectedVersion" Mock Get-ChildItem { @@ -356,22 +363,31 @@ Describe "Build-Module" { $global:ExpectedVersion = "1.0.0" Push-Location TestDrive:/ -StackName BuildModuleTest New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force - New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule/$ExpectedVersion" -Force + New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule" -Force - Mock InitializeBuild { - # These are actually all the values that we need + Mock ResolveBuildManifest { "TestDrive:/MyModule/build.psd1" } + + Mock GetBuildInfo { [PSCustomObject]@{ OutputDirectory = "TestDrive:/Output" - Name = "MyModule" - Version = $Version - Target = $Target - ModuleBase = "TestDrive:/MyModule/" - CopyPaths = @() + SourcePath = "TestDrive:/MyModule/" + Version = "1.0.0" + Prerelease = "beta03" + BuildMetadata = "Sha.22c35ffff166f34addc49a3b80e622b543199cc5.Date.2018-10-11" + Target = "CleanBuild" + CopyPaths = @() Encoding = "UTF8" PublicFilter = "Public/*.ps1" } } + Mock ImportModuleManifest { + [PSCustomObject]@{ + Name = "MyModule" + ModuleBase = "TestDrive:/MyModule/" + } + } + $global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/Output/MyModule" Mock Get-ChildItem { [IO.FileInfo]"$TestDrive/MyModule/Public/Get-MyInfo.ps1" @@ -510,20 +526,28 @@ Describe "Build-Module" { New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force New-Item -ItemType Directory -Path "TestDrive:/$ExpectedVersion/" -Force - Mock InitializeBuild { + Mock GetBuildInfo { # These are actually all the values that we need [PSCustomObject]@{ OutputDirectory = "TestDrive:/$Version" Name = "MyModule" Version = $Version + PreRelease = $PreRelease Target = $Target - ModuleBase = "TestDrive:/MyModule/" + SourcePath = "TestDrive:/MyModule/" CopyPaths = @() Encoding = "UTF8" PublicFilter = "Public/*.ps1" } } + Mock ImportModuleManifest { + [PSCustomObject]@{ + Name = "MyModule" + ModuleBase = "TestDrive:/MyModule/" + } + } + $global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/MyModule/$ExpectedVersion" Mock Get-ChildItem {