Skip to content

Commit

Permalink
update build process
Browse files Browse the repository at this point in the history
  • Loading branch information
jazuntee committed Mar 24, 2023
1 parent 14b0403 commit dcc8623
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 33 deletions.
71 changes: 71 additions & 0 deletions build/Add-PSModuleHeader.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
param
(
# Path to Module Manifest
[Parameter(Mandatory = $false)]
[string] $ModuleManifestPath = ".\release\*\*.*.*",
#
[Parameter(Mandatory = $false)]
[string] $OutputModulePath
)

## Initialize
Import-Module "$PSScriptRoot\CommonFunctions.psm1" -Force -WarningAction SilentlyContinue -ErrorAction Stop

[System.IO.FileInfo] $ModuleManifestFileInfo = Get-PathInfo $ModuleManifestPath -DefaultFilename "*.psd1" -ErrorAction Stop

## Read Module Manifest
$ModuleManifest = Import-PowerShellDataFile $ModuleManifestFileInfo.FullName

if ($OutputModulePath) {
[System.IO.FileInfo] $OutputModuleFileInfo = Get-PathInfo $OutputModulePath -InputPathType File -DefaultFilename "$($ModuleManifestFileInfo.BaseName).psm1" -ErrorAction SilentlyContinue
}
else {
[System.IO.FileInfo] $OutputModuleFileInfo = Get-PathInfo $ModuleManifest['RootModule'] -InputPathType File -DefaultDirectory $ModuleManifestFileInfo.DirectoryName -ErrorAction SilentlyContinue
}

if ($OutputModuleFileInfo.Extension -eq ".psm1") {
## Add Requires Statements
$RequiresStatements = ""
if ($ModuleManifest['PowerShellVersion']) { $RequiresStatements += "#Requires -Version {0}`r`n" -f $ModuleManifest['PowerShellVersion'] }
if ($ModuleManifest['CompatiblePSEditions']) { $RequiresStatements += "#Requires -PSEdition {0}`r`n" -f ($ModuleManifest['CompatiblePSEditions'] -join ',') }
foreach ($RequiredAssembly in $ModuleManifest['RequiredAssemblies']) {
$RequiresStatements += "#Requires -Assembly $_`r`n"
}
foreach ($RequiredModule in $ModuleManifest['RequiredModules']) {
$RequiresStatements += ConvertTo-PsString $ModuleManifest['RequiredModules'] -Compact -RemoveTypes ([hashtable], [string]) | ForEach-Object { "#Requires -Module $_`r`n" }
}

## Build Module Comment Header
[string] $CommentHeader = "<#`r`n"
$CommentHeader += ".SYNOPSIS`r`n {0}`r`n" -f $ModuleManifestFileInfo.BaseName

if ($ModuleManifest['Description']) {
$CommentHeader += ".DESCRIPTION`r`n {0}`r`n" -f $ModuleManifest['Description']
}

[string]$ModuleVersion = if ($ModuleManifest.PrivateData.PSData['Prerelease']) { '{0}-{1}' -f $ModuleManifest['ModuleVersion'], $ModuleManifest.PrivateData.PSData['Prerelease'] } else { $ModuleManifest['ModuleVersion'] }
$CommentHeader += ".NOTES`r`n"
$CommentHeader += " ModuleVersion: {0}`r`n" -f $ModuleVersion
if ($ModuleManifest['GUID']) { $CommentHeader += " GUID: {0}`r`n" -f $ModuleManifest['GUID'] }
if ($ModuleManifest['Author']) { $CommentHeader += " Author: {0}`r`n" -f $ModuleManifest['Author'] }
if ($ModuleManifest['CompanyName']) { $CommentHeader += " CompanyName: {0}`r`n" -f $ModuleManifest['CompanyName'] }
if ($ModuleManifest['Copyright']) { $CommentHeader += " Copyright: {0}`r`n" -f $ModuleManifest['Copyright'] }
if ($ModuleManifest['FunctionsToExport']) {
## ToDo: Account for modules with functions and/or cmdlets.
$CommentHeader += ".FUNCTIONALITY`r`n {0}`r`n" -f ($ModuleManifest['FunctionsToExport'] -join ', ')
}
if ($ModuleManifest.PrivateData.PSData['ProjectUri']) {
$CommentHeader += ".LINK`r`n {0}`r`n" -f $ModuleManifest.PrivateData.PSData['ProjectUri']
}
$CommentHeader += "#>"

## Add Comment Header to Script Module
if ($OutputModuleFileInfo.Exists) {
$RootModuleContent = (Get-Content $OutputModuleFileInfo.FullName -Raw)
}
else {
$RootModuleContent = $null
}

$RequiresStatements, $CommentHeader, $RootModuleContent | Set-Content $OutputModuleFileInfo.FullName -Encoding utf8BOM
}
89 changes: 89 additions & 0 deletions build/Build-PSModule.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
param
(
# Directory used to base all relative paths
[Parameter(Mandatory = $false)]
[string] $BaseDirectory = "..\",
#
[Parameter(Mandatory = $false)]
[string] $OutputDirectory = ".\build\release\",
#
[Parameter(Mandatory = $false)]
[string] $SourceDirectory = ".\src\",
#
[Parameter(Mandatory = $false)]
[string] $ModuleManifestPath,
#
[Parameter(Mandatory = $false)]
[string] $PackagesConfigPath = ".\packages.config",
#
[Parameter(Mandatory = $false)]
[string] $PackagesDirectory = ".\build\packages",
#
[Parameter(Mandatory = $false)]
[string] $LicensePath = ".\LICENSE",
#
[Parameter(Mandatory = $false)]
[switch] $SkipMergingNestedModuleScripts
)

## Initialize
Import-Module "$PSScriptRoot\CommonFunctions.psm1" -Force -WarningAction SilentlyContinue -ErrorAction Stop

[System.IO.DirectoryInfo] $BaseDirectoryInfo = Get-PathInfo $BaseDirectory -InputPathType Directory -ErrorAction Stop
[System.IO.DirectoryInfo] $OutputDirectoryInfo = Get-PathInfo $OutputDirectory -InputPathType Directory -DefaultDirectory $BaseDirectoryInfo.FullName -ErrorAction SilentlyContinue
[System.IO.DirectoryInfo] $SourceDirectoryInfo = Get-PathInfo $SourceDirectory -InputPathType Directory -DefaultDirectory $BaseDirectoryInfo.FullName -ErrorAction Stop
[System.IO.FileInfo] $ModuleManifestFileInfo = Get-PathInfo $ModuleManifestPath -DefaultDirectory $SourceDirectoryInfo.FullName -DefaultFilename "*.psd1" -ErrorAction Stop
[System.IO.FileInfo] $PackagesConfigFileInfo = Get-PathInfo $PackagesConfigPath -DefaultDirectory $BaseDirectoryInfo.FullName -DefaultFilename "packages.config" -ErrorAction SilentlyContinue
[System.IO.DirectoryInfo] $PackagesDirectoryInfo = Get-PathInfo $PackagesDirectory -InputPathType Directory -DefaultDirectory $BaseDirectoryInfo.FullName -ErrorAction SilentlyContinue
[System.IO.FileInfo] $LicenseFileInfo = Get-PathInfo $LicensePath -DefaultDirectory $BaseDirectoryInfo.FullName -DefaultFilename "LICENSE" -ErrorAction SilentlyContinue

## Read Module Manifest
$ModuleManifest = Import-PowerShellDataFile $ModuleManifestFileInfo.FullName
[System.IO.DirectoryInfo] $ModuleOutputDirectoryInfo = Join-Path $OutputDirectoryInfo.FullName (Join-Path $ModuleManifestFileInfo.BaseName $ModuleManifest['ModuleVersion'])
[System.IO.FileInfo] $OutputModuleManifestFileInfo = Join-Path $ModuleOutputDirectoryInfo.FullName $ModuleManifestFileInfo.Name

## Copy Source Module Code to Module Output Directory
Assert-DirectoryExists $ModuleOutputDirectoryInfo -ErrorAction Stop | Out-Null
Copy-Item ("{0}\*" -f $SourceDirectoryInfo.FullName) -Destination $ModuleOutputDirectoryInfo.FullName -Recurse -Force
if (!$SkipMergingNestedModuleScripts) {
[System.IO.FileInfo] $OutputRootModuleFileInfo = (Join-Path $ModuleOutputDirectoryInfo.FullName $ModuleManifest['RootModule'])
&$PSScriptRoot\Merge-PSModuleNestedModuleScripts.ps1 -ModuleManifestPath $OutputModuleManifestFileInfo.FullName -OutputModulePath $OutputRootModuleFileInfo.FullName -MergeWithRootModule -RemoveNestedModuleScriptFiles
}
if ($LicenseFileInfo.Exists) {
Copy-Item $LicenseFileInfo.FullName -Destination (Join-Path $ModuleOutputDirectoryInfo.FullName License.txt) -Force
}

if ($PackagesConfigFileInfo.Exists) {
## NuGet Restore
&$PSScriptRoot\Restore-NugetPackages.ps1 -PackagesConfigPath $PackagesConfigFileInfo.FullName -OutputDirectory $PackagesDirectoryInfo.FullName

## Read Packages Configuration
$xmlPackagesConfig = New-Object xml
$xmlPackagesConfig.Load($PackagesConfigFileInfo.FullName)

## Copy Packages to Module Output Directory
foreach ($package in $xmlPackagesConfig.packages.package) {
[string[]] $targetFrameworks = $package.targetFramework
if (!$targetFrameworks) { [string[]] $targetFrameworks = "net45", "netcoreapp2.1" }
foreach ($targetFramework in $targetFrameworks) {
[System.IO.DirectoryInfo] $PackageDirectory = Join-Path $PackagesDirectoryInfo.FullName ("{0}.{1}\lib\{2}" -f $package.id, $package.version, $targetFramework)
[System.IO.DirectoryInfo] $PackageOutputDirectory = "{0}\{1}.{2}\{3}" -f $ModuleOutputDirectoryInfo.FullName, $package.id, $package.version, $targetFramework
$PackageOutputDirectory
Assert-DirectoryExists $PackageOutputDirectory -ErrorAction Stop | Out-Null
Copy-Item ("{0}\*" -f $PackageDirectory) -Destination $PackageOutputDirectory.FullName -Recurse -Force
}
}
}

## Get Module Output FileList
#$ModuleFileListFileInfo = Get-ChildItem $ModuleOutputDirectoryInfo.FullName -Recurse -File
#$ModuleManifestOutputFileInfo = $ModuleFileListFileInfo | Where-Object Name -EQ $ModuleManifestFileInfo.Name

## Update Module Manifest in Module Output Directory
&$PSScriptRoot\Update-PSModuleManifest.ps1 -ModuleManifestPath $OutputModuleManifestFileInfo.FullName
if (!$SkipMergingNestedModuleScripts) {
&$PSScriptRoot\Add-PSModuleHeader.ps1 -ModuleManifestPath $OutputModuleManifestFileInfo.FullName
}

## Sign Module
&$PSScriptRoot\Sign-PSModule.ps1 -ModuleManifestPath $OutputModuleManifestFileInfo.FullName | Format-Table Path, Status, StatusMessage
22 changes: 14 additions & 8 deletions build/CommonFunctions.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,10 @@ function Get-PathInfo {
if ($Path) {
## Look for existing path
try {
$ResolvePath = Resolve-FullPath $Path -BaseDirectory $DefaultDirectory -ErrorAction SilentlyContinue
$OutputPath = Get-Item $ResolvePath -ErrorAction SilentlyContinue
$ResolvePath = Resolve-FullPath $Path -BaseDirectory $DefaultDirectory -ErrorAction Ignore
if ($ResolvePath) {
$OutputPath = Get-Item $ResolvePath -ErrorAction Ignore
}
}
catch { }
if ($OutputPath -is [array]) {
Expand All @@ -189,6 +191,7 @@ function Get-PathInfo {
return
}

[string] $AbsolutePath = $null
## If path could not be found and there are no wildcards, then create a FileSystemInfo object for the path.
if (!$OutputPath -and $Path -notmatch '[*?]') {
## Get Absolute Path
Expand All @@ -206,8 +209,10 @@ function Get-PathInfo {
[string] $AbsolutePath = (Join-Path $OutputPath.FullName $DefaultFileName)
$OutputPath = $null
try {
$ResolvePath = Resolve-FullPath $AbsolutePath -BaseDirectory $DefaultDirectory -ErrorAction SilentlyContinue
$OutputPath = Get-Item $ResolvePath -ErrorAction SilentlyContinue
$ResolvePath = Resolve-FullPath $AbsolutePath -BaseDirectory $DefaultDirectory -ErrorAction Ignore
if ($ResolvePath) {
$OutputPath = Get-Item $ResolvePath -ErrorAction Ignore
}
}
catch { }
if (!$OutputPath -and $AbsolutePath -notmatch '[*?]') {
Expand All @@ -216,8 +221,9 @@ function Get-PathInfo {
}

if (!$OutputPath -or !$OutputPath.Exists) {
if ($OutputPath) { Write-Error -Exception (New-Object System.Management.Automation.ItemNotFoundException -ArgumentList ('Cannot find path ''{0}'' because it does not exist.' -f $OutputPath.FullName)) -TargetObject $OutputPath.FullName -ErrorId 'PathNotFound' -Category ObjectNotFound }
else { Write-Error -Exception (New-Object System.Management.Automation.ItemNotFoundException -ArgumentList ('Cannot find path ''{0}'' because it does not exist.' -f $AbsolutePath)) -TargetObject $AbsolutePath -ErrorId 'PathNotFound' -Category ObjectNotFound }
if ($OutputPath) { Write-Error -Exception (New-Object System.Management.Automation.ItemNotFoundException -ArgumentList ('Cannot find path ''{0}'' because it does not exist.' -f $OutputPath.FullName)) -TargetObject $OutputPath.FullName -ErrorId 'PathNotFound' -Category ObjectNotFound -ErrorAction $ErrorActionPreference }
elseif ($AbsolutePath) { Write-Error -Exception (New-Object System.Management.Automation.ItemNotFoundException -ArgumentList ('Cannot find path ''{0}'' because it does not exist.' -f $AbsolutePath)) -TargetObject $AbsolutePath -ErrorId 'PathNotFound' -Category ObjectNotFound -ErrorAction $ErrorActionPreference }
else { Write-Error -Exception (New-Object System.Management.Automation.ItemNotFoundException -ArgumentList ('Cannot find path ''{0}'' because it does not exist.' -f $Path)) -TargetObject $Path -ErrorId 'PathNotFound' -Category ObjectNotFound -ErrorAction $ErrorActionPreference }
}
}

Expand Down Expand Up @@ -658,7 +664,7 @@ function ConvertTo-PsString {
break
}
## Convert objects with object initializers
{ $_ -is [object] -and ($_.GetConstructors() | foreach { if ($_.IsPublic -and !$_.GetParameters()) { $true } }) } {
{ $_ -is [object] -and ($_.GetConstructors() | ForEach-Object { if ($_.IsPublic -and !$_.GetParameters()) { $true } }) } {
[void]$OutputString.Append('@{')
$iInput = 0
foreach ($Item in ($InputObject | Get-Member -MemberType Property, NoteProperty)) {
Expand Down Expand Up @@ -790,7 +796,7 @@ function Select-PsBoundParameters {
if ($CommandParameterSets) {
[System.Collections.Generic.List[string]] $listCommandParameters = New-Object System.Collections.Generic.List[string]
foreach ($CommandParameterSet in $CommandParameterSets) {
$listCommandParameters.AddRange([string[]]($CommandInfo.ParameterSets | Where-Object Name -eq $CommandParameterSet | Select-Object -ExpandProperty Parameters | Select-Object -ExpandProperty Name))
$listCommandParameters.AddRange([string[]]($CommandInfo.ParameterSets | Where-Object Name -EQ $CommandParameterSet | Select-Object -ExpandProperty Parameters | Select-Object -ExpandProperty Name))
}
$CommandParameters = $listCommandParameters | Select-Object -Unique
}
Expand Down
2 changes: 1 addition & 1 deletion build/Get-PSModuleInfo.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Write-Host ('##vso[task.setvariable variable=moduleName;isOutput=true]{0}' -f $e
Write-Host ('##[debug] {0} = {1}' -f 'moduleName', $env:moduleName)

## Output moduleVersion Azure Pipelines
$env:moduleVersion = $ModuleManifest.ModuleVersion
$env:moduleVersion = $ModuleManifest['ModuleVersion']
Write-Host ('##vso[task.setvariable variable=moduleVersion;isOutput=true]{0}' -f $env:moduleVersion)
Write-Host ('##[debug] {0} = {1}' -f 'moduleVersion', $env:moduleVersion)

Expand Down
80 changes: 80 additions & 0 deletions build/Merge-PSModuleNestedModuleScripts.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
param
(
# Path to Module Manifest
[Parameter(Mandatory = $false)]
[string] $ModuleManifestPath = ".\release\*\*.*.*",
#
[Parameter(Mandatory = $false)]
[string] $OutputModulePath,
#
[Parameter(Mandatory = $false)]
[switch] $MergeWithRootModule,
#
[Parameter(Mandatory = $false)]
[switch] $RemoveNestedModuleScriptFiles
)

## Initialize
Import-Module "$PSScriptRoot\CommonFunctions.psm1" -Force -WarningAction SilentlyContinue -ErrorAction Stop

[System.IO.FileInfo] $ModuleManifestFileInfo = Get-PathInfo $ModuleManifestPath -DefaultFilename "*.psd1" -ErrorAction Stop
#[System.IO.DirectoryInfo] $ModuleSourceDirectoryInfo = $ModuleManifestFileInfo.Directory
#[System.IO.DirectoryInfo] $ModuleOutputDirectoryInfo = $OutputModuleFileInfo.Directory

## Read Module Manifest
$ModuleManifest = Import-PowerShellDataFile $ModuleManifestFileInfo.FullName

if ($OutputModulePath) {
[System.IO.FileInfo] $OutputModuleFileInfo = Get-PathInfo $OutputModulePath -InputPathType File -DefaultFilename "$($ModuleManifestFileInfo.BaseName).psm1" -ErrorAction SilentlyContinue
}
else {
[System.IO.FileInfo] $OutputModuleFileInfo = Get-PathInfo $ModuleManifest['RootModule'] -InputPathType File -DefaultDirectory $ModuleManifestFileInfo.DirectoryName -ErrorAction SilentlyContinue
if (!$PSBoundParameters.ContainsKey('MergeWithRootModule')) { $MergeWithRootModule = $true }
}

if ($OutputModuleFileInfo.Extension -eq ".psm1") {

[System.IO.FileInfo] $RootModuleFileInfo = Get-PathInfo $ModuleManifest['RootModule'] -InputPathType File -DefaultDirectory $ModuleManifestFileInfo.DirectoryName -ErrorAction SilentlyContinue
[System.IO.FileInfo[]] $NestedModulesFileInfo = $ModuleManifest['NestedModules'] | Get-PathInfo -InputPathType File -DefaultDirectory $ModuleManifestFileInfo.DirectoryName -ErrorAction SilentlyContinue
[System.IO.FileInfo[]] $ScriptsToProcessFileInfo = $ModuleManifest['ScriptsToProcess'] | Get-PathInfo -InputPathType File -DefaultDirectory $ModuleManifestFileInfo.DirectoryName -ErrorAction SilentlyContinue

if ($MergeWithRootModule) {
## Split module parameters from the rest of the module content
[string] $RootModuleParameters = $null
[string] $RootModuleContent = $null
if ($RootModuleFileInfo.Extension -eq ".psm1" -and (Get-Content $RootModuleFileInfo.FullName -Raw) -match "(?s)^(.*\n?\s*param\s*[(](?:[^()]|(?'Nested'[(])|(?'-Nested'[)]))*[)]\s*)?(.*)$") {
$RootModuleParameters = $Matches[1]
$RootModuleContent = $Matches[2]
}

$NestedModuleRegion = "#region NestedModules Script(s)`r`n"

$RootModuleParameters, $NestedModuleRegion | Set-Content $OutputModuleFileInfo.FullName -Encoding utf8BOM
}

## Add Nested Module Scripts
$NestedModulesFileInfo | Where-Object Extension -EQ '.ps1' | ForEach-Object { "#region $($_.Name)`r`n`r`n$(Get-Content $_ -Raw)`r`n#endregion`r`n" } | Add-Content $OutputModuleFileInfo.FullName -Encoding utf8BOM

if ($MergeWithRootModule) {
function Join-ModuleMembers ([string[]]$Members) {
if ($Members.Count -gt 0) {
return "'{0}'" -f ($Members -join "','")
}
else { return "" }
}

## Add remainder of root module content
$NestedModuleEndRegion = "#endregion`r`n"
$ExportModuleMember += "Export-ModuleMember -Function @({0}) -Cmdlet @({1}) -Variable @({2}) -Alias @({3})" -f (Join-ModuleMembers $ModuleManifest['FunctionsToExport']), (Join-ModuleMembers $ModuleManifest['CmdletsToExport']), (Join-ModuleMembers $ModuleManifest['VariablesToExport']), (Join-ModuleMembers $ModuleManifest['AliasesToExport'])

$NestedModuleEndRegion, $RootModuleContent, $ExportModuleMember | Add-Content $OutputModuleFileInfo.FullName -Encoding utf8BOM
}

if ($RemoveNestedModuleScriptFiles) {
## Remove Nested Module Scripts
$NestedModulesFileInfo | Where-Object Extension -EQ '.ps1' | Where-Object { !$ScriptsToProcessFileInfo -or $_.FullName -notin $ScriptsToProcessFileInfo.FullName } | Remove-Item

## Remove Empty Directories
Get-ChildItem $ModuleManifestFileInfo.DirectoryName -Recurse -Directory | Where-Object { !(Get-ChildItem $_.FullName -Recurse -File) } | Remove-Item -Recurse
}
}
Loading

0 comments on commit dcc8623

Please sign in to comment.