diff --git a/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1 b/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1 index 4652ffe..ec72d48 100644 --- a/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1 +++ b/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1 @@ -1,5 +1,5 @@ function Invoke-PSMDTemplate { -<# + <# .SYNOPSIS Creates a project/file from a template. @@ -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. @@ -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')] @@ -119,6 +123,9 @@ [switch] $Raw, + [switch] + $GenerateObjects, + [switch] $Force, @@ -175,6 +182,9 @@ [bool] $Raw, + [switch] + $GenerateObjects, + [bool] $Silent ) @@ -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") @@ -227,8 +238,7 @@ #endregion File #region Project - "Project" - { + "Project" { #region Resolve output folder if (-not $NoFolder) { if ($Parameters["Name"]) { @@ -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) @@ -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 ( @@ -297,9 +318,6 @@ [string] $Path, - [PSFEncoding] - $Encoding, - [hashtable] $ParameterFlat, @@ -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' @@ -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) @@ -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 @@ -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) { @@ -391,4 +449,4 @@ } -EnableException $EnableException -PSCmdlet $PSCmdlet -Continue } } -} \ No newline at end of file +} diff --git a/PSModuleDevelopment/internal/classes/TemplateResult.ps1 b/PSModuleDevelopment/internal/classes/TemplateResult.ps1 new file mode 100644 index 0000000..2ca7c27 --- /dev/null +++ b/PSModuleDevelopment/internal/classes/TemplateResult.ps1 @@ -0,0 +1,7 @@ +class TemplateResult { + [string]$Filename + [string]$Path + [string]$FullPath + $Content + [bool]$IsText=$true +} \ No newline at end of file diff --git a/PSModuleDevelopment/internal/scripts/preimport.ps1 b/PSModuleDevelopment/internal/scripts/preimport.ps1 index 6d065ae..c0197f4 100644 --- a/PSModuleDevelopment/internal/scripts/preimport.ps1 +++ b/PSModuleDevelopment/internal/scripts/preimport.ps1 @@ -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" \ No newline at end of file +. 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 +} \ No newline at end of file