tasks/Build-Module.ModuleBuilder.build.ps1
Param ( [Parameter()] [string] $ProjectName = (property ProjectName $( #Find the module manifest to deduce the Project Name (Get-ChildItem $BuildRoot\*\*.psd1 | Where-Object { ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } ).BaseName ) ), [Parameter()] [string] $SourcePath = (property SourcePath ((Get-ChildItem $BuildRoot\*\*.psd1 | Where-Object { ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch { $false }) } ).Directory.FullName) ), [Parameter()] [string] $OutputDirectory = (property OutputDirectory (Join-Path $BuildRoot "output")), [Parameter()] [string] $BuildModuleOutput = (property BuildModuleOutput (Join-Path $OutputDirectory $ProjectName)), [Parameter()] $ReleaseNotesPath = (property ReleaseNotesPath (Join-Path $OutputDirectory 'ReleaseNotes.md')), [Parameter()] [string] $ModuleVersion = (property ModuleVersion $( try { (gitversion | ConvertFrom-Json -ErrorAction Stop).InformationalVersion } catch { Write-Verbose "Error attempting to use GitVersion $($_)" '' } )), [Parameter()] $BuildInfo = (property BuildInfo @{}) ) # Synopsis: Build the Module based on its Build.psd1 definition Task Build_Module_ModuleBuilder { " Project Name = $ProjectName" " ModuleVersion = $ModuleVersion" " Source Path = $SourcePath" " OutputDirectory = $OutputDirectory" " BuildModuleOutput = $BuildModuleOutput" # because of a bug in ModuleBuilder, and I want to leave using build.psd1 # an option, we only override Source path if Build.psd1 does not target source if(Test-Path $SourcePath -PathType Container) { $BuildPsd1 = Join-Path $SourcePath '[Bb]uild.psd1' if (Test-Path $BuildPsd1) { $data = Import-Metadata $BuildPsd1 if (!$data.containsKey('SourcePath')) { $SourcePath = Join-Path $SourcePath "$ProjectName.psd1" " Source Path = $SourcePath" } } } if (!(Split-Path -isAbsolute $ReleaseNotesPath)) { $ReleaseNotesPath = Join-path $OutputDirectory $ReleaseNotesPath } Import-Module ModuleBuilder -ErrorAction Stop $BuildModuleParams = @{} foreach ($ParamName in (Get-Command Build-Module).Parameters.Keys) { # If Build-Module parameters are available in current session, use those # otherwise use params from BuildInfo if specified if ($ValueFromBuildParam = Get-Variable -Name $ParamName -ValueOnly -ErrorAction SilentlyContinue) { Write-Build -Color DarkGray "Adding $ParamName with value $ValueFromBuildParam from current Variables" if ($ParamName -eq 'OutputDirectory') { $BuildModuleParams.add($ParamName, $BuildModuleOutput) } else { $BuildModuleParams.Add($ParamName, $ValueFromBuildParam) } } elseif ($ValueFromBuildInfo = $BuildInfo[$ParamName]) { Write-Build -Color DarkGray "Adding $ParamName with value $ValueFromBuildInfo from Build Info" $BuildModuleParams.Add($ParamName, $ValueFromBuildInfo) } else { Write-Debug -Message "No value specified for $ParamName" } } Write-Build -Color Green "Building Module to $($BuildModuleParams['OutputDirectory'])..." $BuiltModule = Build-Module @BuildModuleParams -SemVer $ModuleVersion -Passthru if (Test-Path $ReleaseNotesPath) { $RelNote = Get-Content -raw $ReleaseNotesPath $OutputManifest = $BuiltModule.Path Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.ReleaseNotes -Value $RelNote } } Task Build_NestedModules_ModuleBuilder { " Project Name = $ProjectName" " Source Path = $SourcePath" " OutputDirectory = $OutputDirectory" " BuildModuleOutput = $BuildModuleOutput" Import-Module ModuleBuilder -ErrorAction Stop $BuiltModuleManifest = "$OutputDirectory/$ProjectName/*/$ProjectName.psd1" $ModuleInfo = Import-PowerShellDataFile $BuiltModuleManifest -ErrorAction Stop if ([String]::IsNullOrEmpty($ModuleVersion)) { if ($PreReleaseTag = $ModuleInfo.PrivateData.PSData.Prerelease) { $ModuleVersionFolder = $ModuleInfo.ModuleVersion $ModuleVersion = $ModuleVersionFolder + "-" + $PreReleaseTag } else { $ModuleVersionFolder = $ModuleInfo.ModuleVersion $ModuleVersion = $ModuleInfo.ModuleVersion } } else { # Remove metadata from ModuleVersion $ModuleVersion, $BuildMetadata = $ModuleVersion -split '\+', 2 # Remove Prerelease tag from ModuleVersionFolder $ModuleVersionFolder, $PreReleaseTag = $ModuleVersion -split '\-', 2 } " ModuleVersion = $ModuleVersion" " ModuleVersionFolder = $ModuleVersionFolder" " PreReleaseTag = $PreReleaseTag" $NestedModule = $BuildInfo.NestedModule $NestedModulesToAdd = @() foreach ($NestedModuleName in $NestedModule.Keys) { $cmdParam = $NestedModule[$NestedModuleName] $AddToManifest = [bool]$cmdParam['AddToManifest'] # either copy only or Build if ([bool]$cmdParam['CopyOnly']) { Write-Debug "Using parameters to copy nested module from Source to Destination" $cmd = Get-Command Copy-Item if (!$cmdParam.ContainsKey('Path')) { $cmdParam['Path'] = '$SourcePath/Modules/$NestedModuleName' } if (!$cmdParam.ContainsKey('Recurse')) { $cmdParam['Recurse'] = $true } # Set default Destination (substitute later) if (!$cmdParam.ContainsKey('Destination')) { $cmdParam['Destination'] = './output/$ProjectName/$ModuleVersionFolder/Modules/$NestedModuleName' } Write-Build -color yellow "Copying Nested Module files for $NestedModuleName" } else { $cmd = Get-Command Build-Module Write-Build -color yellow "Building Nested Module $NestedModuleName" } $cmdParamKeys = @() + $cmdParam.Keys foreach ($ParamName in $cmdParamKeys) { # remove param not available in command if ($ParamName -notin @($cmd.Parameters.keys + $cmd.Parameters.values.aliases) ) { Write-Build White "Removing Parameter $ParamName for $($cmd.Name)" $cmdParam.remove($ParamName) } elseif ($ParamName -in @('Path', 'Destination', 'OutputDirectory','SemVer')) { # Substitute & Resolve Resolve Path to absolutes (relative assumed is $BuildRoot) Write-Build White "Resolving Absolute path for $ParamName $($cmdParam[$ParamName])" $cmdParam[$ParamName] = $ExecutionContext.InvokeCommand.ExpandString($cmdParam[$ParamName]) if (!(Split-Path -IsAbsolute $cmdParam[$ParamName]) -and $ParamName -ne 'SemVer') { $cmdParam[$ParamName] = Join-Path -Path $BuildRoot -ChildPath $cmdParam[$ParamName] } Write-Build -color White " The $ParamName is: $($cmdParam[$ParamName])" } } $BuiltModuleBase = Split-Path -Parent -Path $BuiltModuleManifest Write-Build -color Green "$($cmd.Verb) $NestedModuleName..." if ($cmdParam.Verbose) { Write-Verbose ($CmdParam | ConvertTo-Json) -Verbose } &$cmd @cmdParam if ($AddToManifest) { Write-Build DarkMagenta " Preparing to Add to Manifest" if ($cmd.Name -eq 'Copy-Item') { $NestedModulePath = $cmdParam['Destination'] } else { $NestedModulePath = $cmdParam['OutputDirectory'] } Write-Build DarkMagenta " Looking in $NestedModulePath" $NestedModuleFile = (Get-ChildItem -Path $NestedModulePath -Recurse -Include *.psd1 | Where-Object { ($_.Directory.Name -eq $_.BaseName -or $_.Directory.Name -as [version]) -and $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop } catch { $false }) } ).FullName -replace [Regex]::Escape($BuiltModuleBase), ".$([io.path]::DirectorySeparatorChar)" if (!$NestedModuleFile) { $NestedModuleFile = Get-ChildItem -Path $NestedModulePath -Recurse -Include *.psm1 | ForEach-Object { $_.FullName -replace [Regex]::Escape($BuiltModuleBase), ".$([io.path]::DirectorySeparatorChar)" } } Write-Build DarkMagenta "Found $($NestedModuleFile -join ';')" $NestedModulesToAdd += $NestedModuleFile } Write-Build -color Green "Done `r`n" } # Add to NestedModules to ModuleManifest if ($ModuleInfo.containsKey('NestedModules') -and $NestedModulesToAdd) { Write-Build -color Green "Updating the Module Manifest's NestedModules key..." $NestedModulesToAdd = $ModuleInfo.NestedModules + $NestedModulesToAdd # Get Nested Module Manifest or PSM1 $updateMetadataParams = @{ Path = (Get-Item $BuiltModuleManifest).FullName PropertyName = 'NestedModules' Value = $NestedModulesToAdd ErrorAction = 'Stop' } Write-Build Green " Adding $($NestedModuleToAdd -join ', ') to Module Manifest $($updateMetadataParams.Path)" Update-Metadata @updateMetadataParams } } |