Skip to content
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
118 changes: 88 additions & 30 deletions PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function Invoke-PSMDTemplate {
<#
<#
.SYNOPSIS
Creates a project/file from a template.

Expand Down Expand Up @@ -49,6 +49,10 @@
By default, all parameters will be replaced during invocation.
In Raw mode, this is skipped, reproducing mostly the original template input (dynamic scriptblocks will now be named scriptblocks)).

.PARAMETER GenerateObjects
By default, Invoke-PSMDTemplate generates files.
In GenerateObjects mode, no file but objects are created.

.PARAMETER Force
If the target path the template should be written to (filename or folder name within $OutPath), then overwrite it.
By default, this function will fail if an overwrite is required.
Expand Down Expand Up @@ -78,7 +82,7 @@
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSPossibleIncorrectUsageOfAssignmentOperator", "")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
[Alias('imt')]
[Alias('imt')]
[CmdletBinding(SupportsShouldProcess = $true)]
param (
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'NameStore')]
Expand Down Expand Up @@ -119,6 +123,9 @@
[switch]
$Raw,

[switch]
$GenerateObjects,

[switch]
$Force,

Expand Down Expand Up @@ -175,6 +182,9 @@
[bool]
$Raw,

[switch]
$GenerateObjects,

[bool]
$Silent
)
Expand Down Expand Up @@ -212,13 +222,14 @@
}
}
#endregion Scripts

$createdTemplateItems=@()
switch ($templateData.Type.ToString()) {
#region File
"File"
{
"File" {
foreach ($child in $templateData.Children) {
Write-TemplateItem -Item $child -Path $OutPath -Encoding $Encoding -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
$createdTemplateItems += New-TemplateItem -Item $child -Path $OutPath -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
# Write-PSFMessage "`$createdTemplateItems=$($createdTemplateItems|convertto-json)"
# Write-TemplateResult -TemplateResult $createdTemplateItems -Encoding $Encoding
}
if ($Raw -and $templateData.Scripts.Values) {
$templateData.Scripts.Values | Export-Clixml -Path (Join-Path $OutPath "_PSMD_ParameterScripts.xml")
Expand All @@ -227,8 +238,7 @@
#endregion File

#region Project
"Project"
{
"Project" {
#region Resolve output folder
if (-not $NoFolder) {
if ($Parameters["Name"]) {
Expand All @@ -247,7 +257,9 @@
#endregion Resolve output folder

foreach ($child in $templateData.Children) {
Write-TemplateItem -Item $child -Path $newFolder.FullName -Encoding $Encoding -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
$createdTemplateItems += New-TemplateItem -Item $child -Path $newFolder.FullName -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
# Write-PSFMessage "`$createdTemplateItems=$($createdTemplateItems|convertto-json)"
# Write-TemplateResult -TemplateResult $createdTemplateItems -Encoding $Encoding
}

#region Write Config File (Raw)
Expand Down Expand Up @@ -278,16 +290,25 @@
$optionsTemplate = $optionsTemplate -replace "þþþPLACEHOLDER-$($guid)þþþ", ""
}

$configFile = Join-Path $newFolder.FullName "PSMDTemplate.ps1"
Set-Content -Path $configFile -Value $optionsTemplate -Encoding ([PSFEncoding]'utf-8').Encoding
$createdTemplateItems += [TemplateResult]@{
Filename = "PSMDTemplate.ps1"
Path = $newFolder.FullName
FullPath = (Join-Path $newFolder.FullName "PSMDTemplate.ps1")
Content = $optionsTemplate
}
# Set-Content -Path $configFile -Value $optionsTemplate -Encoding ([PSFEncoding]'utf-8').Encoding
}
#endregion Write Config File (Raw)
}
#endregion Project
}
If($GenerateObjects){
return $createdTemplateItems
}
Write-TemplateResult -TemplateResult $createdTemplateItems -Encoding $Encoding
}

function Write-TemplateItem {
function New-TemplateItem {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[CmdletBinding()]
param (
Expand All @@ -297,9 +318,6 @@
[string]
$Path,

[PSFEncoding]
$Encoding,

[hashtable]
$ParameterFlat,

Expand All @@ -309,8 +327,7 @@
[bool]
$Raw
)

Write-PSFMessage -Level Verbose -Message "Creating file: $($Item.Name) ($($Item.RelativePath))" -FunctionName Invoke-PSMDTemplate -ModuleName PSModuleDevelopment -Tag 'create', 'template'
Write-PSFMessage -Level Verbose -Message "Creating Template-Item: $($Item.Name) ($($Item.RelativePath))" -FunctionName Invoke-PSMDTemplate -ModuleName PSModuleDevelopment -Tag 'create', 'template'

$identifier = $Item.Identifier
$isFile = $Item.GetType().Name -eq 'TemplateItemFile'
Expand All @@ -320,7 +337,7 @@
$fileName = $Item.Name
if (-not $Raw) {
foreach ($param in $Item.FileSystemParameterFlat) {
$fileName = [PSModuleDevelopment.Utility.UtilityHost]::Replace($fileName,"$($identifier)$($param)$($identifier)", $ParameterFlat[$param], $false)
$fileName = [PSModuleDevelopment.Utility.UtilityHost]::Replace($fileName, "$($identifier)$($param)$($identifier)", $ParameterFlat[$param], $false)
}
foreach ($param in $Item.FileSystemParameterScript) {
$fileName = [PSModuleDevelopment.Utility.UtilityHost]::Replace($fileName, "$($identifier)$($param)$($identifier)", $ParameterScript[$param], $false)
Expand All @@ -338,11 +355,22 @@
$text = [PSModuleDevelopment.Utility.UtilityHost]::Replace($text, "$($identifier)!$($param)!$($identifier)", $ParameterScript[$param], $false)
}
}
[System.IO.File]::WriteAllText($destPath, $text, $Encoding)
return [TemplateResult]@{
Filename = $fileName
Path = $Path
FullPath = $destPath
Content = $text
}
}
else {
$bytes = [System.Convert]::FromBase64String($Item.Value)
[System.IO.File]::WriteAllBytes($destPath, $bytes)
return [TemplateResult]@{
Filename = $fileName
Path = $Path
FullPath = $destPath
Content = $bytes
IsText = $false
}
}
}
#endregion File
Expand All @@ -358,26 +386,56 @@
$folderName = $folderName -replace "$($identifier)!$([regex]::Escape($param))!$($identifier)", $ParameterScript[$param]
}
}
$folder = New-Item -Path $Path -Name $folderName -ItemType Directory

$folder = Join-Path -Path $Path -ChildPath $folderName
# $folder = New-Item -Path $Path -Name $folderName -ItemType Directory
$createdTemplateItems = @()
foreach ($child in $Item.Children) {
Write-TemplateItem -Item $child -Path $folder.FullName -Encoding $Encoding -ParameterFlat $ParameterFlat -ParameterScript $ParameterScript -Raw $Raw
$createdTemplateItems += New-TemplateItem -Item $child -Path $folder -ParameterFlat $ParameterFlat -ParameterScript $ParameterScript -Raw $Raw
}
return $createdTemplateItems
}
#endregion Folder
}
function Write-TemplateResult {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[CmdletBinding()]
param (
[TemplateResult[]]
$TemplateResult,

[PSFEncoding]
$Encoding
)
foreach ($item in $TemplateResult) {
Write-PSFMessage -Level Verbose -Message "Creating file: $($Item.FullPath)" -FunctionName Invoke-PSMDTemplate -ModuleName PSModuleDevelopment -Tag 'create', 'template'
# Write-PSFMessage -Level Verbose -Message "Creating file: $($Item |convertto-json)" -FunctionName Invoke-PSMDTemplate -ModuleName PSModuleDevelopment -Tag 'create', 'template'
if (-not (Test-Path $Item.Path)) {
Write-PSFMessage -Level Verbose -Message "Creating Folder $($Item.Path)"
New-Item -Path $Item.Path -ItemType Directory | Out-Null
}
if ($Item.IsText) {
Write-PSFMessage -Level Verbose -Message "Creating as a Text-File"
[System.IO.File]::WriteAllText($Item.FullPath, $Item.Content, $Encoding)
}
else {
Write-PSFMessage -Level Verbose -Message "Creating as a Binary-File"
[System.IO.File]::WriteAllBytes($Item.FullPath, $Item.Content)
}
}
}
#endregion Helper function
}
process {
if (Test-PSFFunctionInterrupt) { return }

$invokeParam = @{
Parameters = $Parameters.Clone()
OutPath = Resolve-PSFPath -Path $OutPath
NoFolder = $NoFolder
Encoding = $Encoding
Raw = $Raw
Silent = $Silent
Parameters = $Parameters.Clone()
OutPath = Resolve-PSFPath -Path $OutPath
NoFolder = $NoFolder
Encoding = $Encoding
Raw = $Raw
Silent = $Silent
GenerateObjects = $GenerateObjects
}

foreach ($item in $Template) {
Expand All @@ -391,4 +449,4 @@
} -EnableException $EnableException -PSCmdlet $PSCmdlet -Continue
}
}
}
}
7 changes: 7 additions & 0 deletions PSModuleDevelopment/internal/classes/TemplateResult.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class TemplateResult {
[string]$Filename
[string]$Path
[string]$FullPath
$Content
[bool]$IsText=$true
}
8 changes: 7 additions & 1 deletion PSModuleDevelopment/internal/scripts/preimport.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ foreach ($file in (Get-ChildItem "$($script:ModuleRoot)\internal\configurations\
}

# Load additional resources needed during import
. Import-ModuleFile -Path "$($script:ModuleRoot)\internal\scripts\initialize.ps1"
. Import-ModuleFile -Path "$($script:ModuleRoot)\internal\scripts\initialize.ps1"

# Load all classes
foreach ($file in (Get-ChildItem "$($script:ModuleRoot)\internal\classes\*.ps1" -ErrorAction Ignore))
{
. Import-ModuleFile -Path $file.FullName
}