Skip to content

Commit

Permalink
Merge pull request #26 from EvotecIT/PlaceHolders
Browse files Browse the repository at this point in the history
Add custom and builtin place holders replacement functionality
  • Loading branch information
PrzemyslawKlys authored Aug 14, 2024
2 parents e2d5e4f + 81c09a1 commit 3d1f926
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Build/Build-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# We need to rmeove library before we start, as it may contain old files, which will be in use once PSD1 loads
# This is only required for PSPublisModule, as it's the only module that is being built by itself
Remove-Item -Path "C:\Support\GitHub\PSPublishModule\Lib" -Recurse -Force -ErrorAction Stop
Remove-Item -Path "C:\Support\GitHub\PSPublishModule\Lib" -Recurse -Force -ErrorAction SilentlyContinue

Import-Module "$PSScriptRoot\..\PSPublishModule.psd1" -Force

Expand Down Expand Up @@ -114,6 +114,7 @@ Build-Module -ModuleName 'PSPublishModule' {
#CertificatePFXBase64 = $BasePfx
#CertificatePFXPassword = "zGT"
DoNotAttemptToFixRelativePaths = $false
SkipBuiltinReplacements = $true

# required for Cmdlet/Alias functionality
NETProjectPath = "$PSScriptRoot\..\Sources\PSPublishModule\PSPublishModule"
Expand Down
9 changes: 6 additions & 3 deletions Build/Build-ModuleLegacy.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Import-Module "$PSScriptRoot\..\PSPublishModule.psd1" -Force

$Configuration = @{
Information = @{
Information = @{
ModuleName = 'PSPublishModule'
#DirectoryProjects = 'C:\Support\GitHub'

Expand Down Expand Up @@ -65,7 +65,7 @@ $Configuration = @{
DotNetFrameworkVersion = '4.5.2'
}
}
Options = @{
Options = @{
Merge = @{
Sort = 'None'
FormatCodePSM1 = @{
Expand Down Expand Up @@ -168,7 +168,10 @@ $Configuration = @{
CertificateThumbprint = '36A8A2D0E227D81A2D3B60DCE0CFCF23BEFC343B'
}
}
Steps = @{
PlaceHolderOptions = @{
SkipBuiltinReplacements = $true
}
Steps = @{
BuildLibraries = @{
Enable = $false # build once every time nuget gets updated
Configuration = 'Release'
Expand Down
3 changes: 2 additions & 1 deletion Build/Build-ModuleSimplified.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# This version is for local building
# We need to rmeove library before we start, as it may contain old files, which will be in use once PSD1 loads
# This is only required for PSPublisModule, as it's the only module that is being built by itself
Remove-Item -Path "C:\Support\GitHub\PSPublishModule\Lib" -Recurse -Force -ErrorAction Stop
Remove-Item -Path "C:\Support\GitHub\PSPublishModule\Lib" -Recurse -Force -ErrorAction SilentlyContinue

Import-Module "$PSScriptRoot\..\PSPublishModule.psd1" -Force

Expand Down Expand Up @@ -114,6 +114,7 @@ Build-Module -ModuleName 'PSPublishModule' {
#CertificatePFXBase64 = $BasePfx
#CertificatePFXPassword = "zGT"
DoNotAttemptToFixRelativePaths = $false
SkipBuiltinReplacements = $true

# required for Cmdlet/Alias functionality
NETProjectPath = "$PSScriptRoot\..\Sources\PSPublishModule\PSPublishModule"
Expand Down
2 changes: 1 addition & 1 deletion PSPublishModule.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Copyright = '(c) 2011 - 2024 Przemyslaw Klys @ Evotec. All rights reserved.'
Description = 'Simple project allowing preparing, managing, building and publishing modules to PowerShellGallery'
DotNetFrameworkVersion = '4.5.2'
FunctionsToExport = @('Convert-CommandsToList', 'Get-MissingFunctions', 'Get-PowerShellAssemblyMetadata', 'Initialize-PortableModule', 'Initialize-PortableScript', 'Initialize-ProjectManager', 'Invoke-ModuleBuild', 'New-ConfigurationArtefact', 'New-ConfigurationBuild', 'New-ConfigurationCommand', 'New-ConfigurationDocumentation', 'New-ConfigurationExecute', 'New-ConfigurationFormat', 'New-ConfigurationImportModule', 'New-ConfigurationInformation', 'New-ConfigurationManifest', 'New-ConfigurationModule', 'New-ConfigurationModuleSkip', 'New-ConfigurationPublish', 'New-ConfigurationTest', 'Register-Certificate', 'Remove-Comments', 'Send-GitHubRelease', 'Test-BasicModule', 'Test-ScriptFile', 'Test-ScriptModule')
FunctionsToExport = @('Convert-CommandsToList', 'Get-MissingFunctions', 'Get-PowerShellAssemblyMetadata', 'Initialize-PortableModule', 'Initialize-PortableScript', 'Initialize-ProjectManager', 'Invoke-ModuleBuild', 'New-ConfigurationArtefact', 'New-ConfigurationBuild', 'New-ConfigurationCommand', 'New-ConfigurationDocumentation', 'New-ConfigurationExecute', 'New-ConfigurationFormat', 'New-ConfigurationImportModule', 'New-ConfigurationInformation', 'New-ConfigurationManifest', 'New-ConfigurationModule', 'New-ConfigurationModuleSkip', 'New-ConfigurationPlaceHolder', 'New-ConfigurationPublish', 'New-ConfigurationTest', 'Register-Certificate', 'Remove-Comments', 'Send-GitHubRelease', 'Test-BasicModule', 'Test-ScriptFile', 'Test-ScriptModule')
GUID = 'eb76426a-1992-40a5-82cd-6480f883ef4d'
ModuleVersion = '2.0.14'
PowerShellVersion = '5.1'
Expand Down
5 changes: 5 additions & 0 deletions Private/Merge-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ function Merge-Module {
return $false
}

$Success = Repair-CustomPlaceHolders -Path $PSM1FilePath -Configuration $Configuration
if ($Success -eq $false) {
return $false
}

# Format standard PSM1 file
$Success = Format-Code -FilePath $PSM1FilePath -FormatCode $FormatCodePSM1
if ($Success -eq $false) {
Expand Down
14 changes: 14 additions & 0 deletions Private/New-PrepareStructure.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@
# Variables to export from this module
#$Configuration.Information.Manifest.VariablesToExport = @()

# This is to store custom placeholders
if (-not $Configuration.PlaceHolder) {
$Configuration.PlaceHolder = [System.Collections.Generic.List[System.Collections.IDictionary]]::new()
}
if (-not $Configuration.PlaceHolderOption) {
$Configuration.PlaceHolderOption = [ordered] @{}
}

Write-TextWithTime -Text "Reading configuration" {
if ($Settings) {
$ExecutedSettings = & $Settings
Expand Down Expand Up @@ -234,6 +242,12 @@
$Configuration.Options[$Key][$Entry] = $Setting.Options[$Key][$Entry]
}
}
} elseif ($Setting.Type -eq 'PlaceHolder') {
$Configuration.PlaceHolder.Add($Setting.Configuration)
} elseif ($Setting.Type -eq 'PlaceHolderOption') {
foreach ($Key in $Setting.PlaceHolderOption.Keys) {
$Configuration.PlaceHolderOption[$Key] = $Setting.PlaceHolderOption[$Key]
}
}
}
}
Expand Down
48 changes: 48 additions & 0 deletions Private/Repair-CustomPlaceHolders.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function Repair-CustomPlaceHolders {
[CmdletBinding()]
param(
[Parameter(Mandatory)][string] $Path,
[System.Collections.IDictionary] $Configuration
)

$ModuleName = $Configuration.Information.ModuleName
$ModuleVersion = $Configuration.Information.Manifest.ModuleVersion
$TagName = "v$($ModuleVersion)"
if ($Configuration.CurrentSettings.PreRelease) {
$ModuleVersionWithPreRelease = "$($ModuleVersion)-$($Configuration.CurrentSettings.PreRelease)"
$TagModuleVersionWithPreRelease = "v$($ModuleVersionWithPreRelease)"
} else {
$ModuleVersionWithPreRelease = $ModuleVersion
$TagModuleVersionWithPreRelease = "v$($ModuleVersion)"
}

$BuiltinPlaceHolders = @(
@{ Find = '{ModuleName}'; Replace = $ModuleName }
@{ Find = '<ModuleName>'; Replace = $ModuleName }
@{ Find = '{ModuleVersion}'; Replace = $ModuleVersion }
@{ Find = '<ModuleVersion>'; Replace = $ModuleVersion }
@{ Find = '{ModuleVersionWithPreRelease}'; Replace = $ModuleVersionWithPreRelease }
@{ Find = '<ModuleVersionWithPreRelease>'; Replace = $ModuleVersionWithPreRelease }
@{ Find = '{TagModuleVersionWithPreRelease}'; Replace = $TagModuleVersionWithPreRelease }
@{ Find = '<TagModuleVersionWithPreRelease>'; Replace = $TagModuleVersionWithPreRelease }
@{ Find = '{TagName}'; Replace = $TagName }
@{ Find = '<TagName>'; Replace = $TagName }
)

Write-TextWithTime -Text "Replacing built-in and custom placeholders" -Color Yellow {
$PSM1Content = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 -ErrorAction Stop

# Replace built-in placeholders
if ($Configuration.PlaceHolderOption.SkipBuiltinReplacements -ne $true) {
foreach ($PlaceHolder in $BuiltinPlaceHolders) {
$PSM1Content = $PSM1Content.Replace($PlaceHolder.Find, $PlaceHolder.Replace)
}
}
# Replace custom placeholders provided by the user
foreach ($PlaceHolder in $Configuration.PlaceHolders) {
$PSM1Content = $PSM1Content.Replace($PlaceHolder.Find, $PlaceHolder.Replace)
}

Set-Content -LiteralPath $Path -Value $PSM1Content -Encoding UTF8 -ErrorAction Stop -Force
} -PreAppend Plus -SpacesBefore ' '
}
25 changes: 25 additions & 0 deletions Public/New-ConfigurationBuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@
.PARAMETER NETSearchClass
Provide a name for class when using NETResolveBinaryConflicts or NETResolveBinaryConflictsName. By default it uses `$LibraryName.Initialize` however that may not be always the case
.PARAMETER SkipBuiltinReplacements
Skip builtin replacements option disables builtin replacements that are done by module builder.
This is useful if you use any of known replacements and you don't want them to be replaced by module builder.
This has to be used on the PSPublishModule by default, as it would break the module on publish.
Current known replacements are:
- <ModuleName> / {ModuleName} - the name of the module i.e PSPublishModule
- <ModuleVersion> / {ModuleVersion} - the version of the module i.e 1.0.0
- <ModuleVersionWithPreRelease> / {ModuleVersionWithPreRelease} - the version of the module with pre-release tag i.e 1.0.0-Preview1
- <TagModuleVersionWithPreRelease> / {TagModuleVersionWithPreRelease} - the version of the module with pre-release tag i.e v1.0.0-Preview1
- <TagName> / {TagName} - the name of the tag - i.e. v1.0.0
.EXAMPLE
$newConfigurationBuildSplat = @{
Enable = $true
Expand Down Expand Up @@ -150,6 +162,7 @@
[switch] $UseWildcardForFunctions,
[switch] $LocalVersioning,

[switch] $SkipBuiltinReplacements,
[switch] $DoNotAttemptToFixRelativePaths,

[string] $CertificateThumbprint,
Expand Down Expand Up @@ -459,4 +472,16 @@
}
}
}

# This logic disables built-in replacements that are done by module builder
# It's nessecary to prevent replacements that are done by module builder when module builder builds itself
# but can be used in other cases as well
if ($PSBoundParameters.ContainsKey('SkipBuiltinReplacements')) {
[ordered] @{
Type = 'PlaceHolderOption'
PlaceHolderOption = [ordered]@{
SkipBuiltinReplacements = $true
}
}
}
}
53 changes: 53 additions & 0 deletions Public/New-ConfigurationPlaceHolder.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function New-ConfigurationPlaceHolder {
<#
.SYNOPSIS
Command helping define custom placeholders replacing content within a script or module during the build process.
.DESCRIPTION
Command helping define custom placeholders replacing content within a script or module during the build process.
It modifies only the content of the script or module (PSM1) and does not modify the sources.
.PARAMETER CustomReplacement
Hashtable array with custom placeholders to replace. Each hashtable must contain two keys: Find and Replace.
.PARAMETER Find
The string to find in the script or module content.
.PARAMETER Replace
The string to replace the Find string in the script or module content.
.EXAMPLE
New-ConfigurationPlaceHolder -Find '{CustomName}' -Replace 'SpecialCase'
.EXAMPLE
New-ConfigurationPlaceHolder -CustomReplacement @(
@{ Find = '{CustomName}'; Replace = 'SpecialCase' }
@{ Find = '{CustomVersion}'; Replace = '1.0.0' }
)
.NOTES
General notes
#>
[CmdletBinding(DefaultParameterSetName = 'FindAndReplace')]
param(
[Parameter(Mandatory, ParameterSetName = 'CustomReplacement')][System.Collections.IDictionary[]] $CustomReplacement,
[Parameter(Mandatory, ParameterSetName = 'FindAndReplace')][string] $Find,
[Parameter(Mandatory, ParameterSetName = 'FindAndReplace')][string] $Replace
)

foreach ($Replacement in $CustomReplacement) {
[ordered] @{
Type = 'PlaceHolder'
Configuration = $Replacement
}
}
if ($PSBoundParameters.ContainsKey("Find") -and $PSBoundParameters.ContainsKey("Replace")) {
[ordered] @{
Type = 'PlaceHolder'
Configuration = @{
Find = $Find
Replace = $Replace
}
}
}
}

0 comments on commit 3d1f926

Please sign in to comment.