1+ function Invoke-PsmdTemplateV1
2+ {
3+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute (" PSUseShouldProcessForStateChangingFunctions" , " " )]
4+ [CmdletBinding ()]
5+ param (
6+ $TemplateInfo ,
7+
8+ [string ]
9+ $OutPath ,
10+
11+ [bool ]
12+ $NoFolder ,
13+
14+ [hashtable ]
15+ $Parameters ,
16+
17+ [bool ]
18+ $Raw ,
19+
20+ [bool ]
21+ $Silent
22+ )
23+ Write-PSFMessage - Level Verbose - Message " Processing template $ ( $item ) " - Tag ' template' , ' invoke' - FunctionName Invoke-PSMDTemplate
24+
25+ # region Helper Function
26+ function Write-TemplateItem
27+ {
28+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute (" PSUseShouldProcessForStateChangingFunctions" , " " )]
29+ [CmdletBinding ()]
30+ param (
31+ [PSModuleDevelopment.Template.TemplateItemBase ]
32+ $Item ,
33+
34+ [string ]
35+ $Path ,
36+
37+ [hashtable ]
38+ $ParameterFlat ,
39+
40+ [hashtable ]
41+ $ParameterScript ,
42+
43+ [bool ]
44+ $Raw
45+ )
46+
47+ Write-PSFMessage - Level Verbose - Message " Creating file: $ ( $Item.Name ) ($ ( $Item.RelativePath ) )" - FunctionName Invoke-PSMDTemplate - ModuleName PSModuleDevelopment - Tag ' create' , ' template'
48+
49+ $identifier = $Item.Identifier
50+ $isFile = $Item.GetType ().Name -eq ' TemplateItemFile'
51+
52+ # region File
53+ if ($isFile )
54+ {
55+ $fileName = $Item.Name
56+ if (-not $Raw )
57+ {
58+ foreach ($param in $Item.FileSystemParameterFlat )
59+ {
60+ $fileName = $fileName -replace " $ ( $identifier ) $ ( [regex ]::Escape($param )) $ ( $identifier ) " , $ParameterFlat [$param ]
61+ }
62+ foreach ($param in $Item.FileSystemParameterScript )
63+ {
64+ $fileName = $fileName -replace " $ ( $identifier ) !$ ( [regex ]::Escape($param )) !$ ( $identifier ) " , $ParameterScript [$param ]
65+ }
66+ }
67+ $destPath = Join-Path $Path $fileName
68+
69+ if ($Item.PlainText )
70+ {
71+ $text = $Item.Value
72+ if (-not $Raw )
73+ {
74+ foreach ($param in $Item.ContentParameterFlat )
75+ {
76+ $text = $text -replace " $ ( $identifier ) $ ( [regex ]::Escape($param )) $ ( $identifier ) " , $ParameterFlat [$param ]
77+ }
78+ foreach ($param in $Item.ContentParameterScript )
79+ {
80+ $text = $text -replace " $ ( $identifier ) !$ ( [regex ]::Escape($param )) !$ ( $identifier ) " , $ParameterScript [$param ]
81+ }
82+ }
83+ [System.IO.File ]::WriteAllText($destPath , $text )
84+ }
85+ else
86+ {
87+ $bytes = [System.Convert ]::FromBase64String($Item.Value )
88+ [System.IO.File ]::WriteAllBytes($destPath , $bytes )
89+ }
90+ }
91+ # endregion File
92+
93+ # region Folder
94+ else
95+ {
96+ $folderName = $Item.Name
97+ if (-not $Raw )
98+ {
99+ foreach ($param in $Item.FileSystemParameterFlat )
100+ {
101+ $folderName = $folderName -replace " $ ( $identifier ) $ ( [regex ]::Escape($param )) $ ( $identifier ) " , $ParameterFlat [$param ]
102+ }
103+ foreach ($param in $Item.FileSystemParameterScript )
104+ {
105+ $folderName = $folderName -replace " $ ( $identifier ) !$ ( [regex ]::Escape($param )) !$ ( $identifier ) " , $ParameterScript [$param ]
106+ }
107+ }
108+ $folder = New-Item - Path $Path - Name $folderName - ItemType Directory
109+
110+ foreach ($child in $Item.Children )
111+ {
112+ Write-TemplateItem - Item $child - Path $folder.FullName - ParameterFlat $ParameterFlat - ParameterScript $ParameterScript - Raw $Raw
113+ }
114+ }
115+ # endregion Folder
116+ }
117+ # endregion Helper Function
118+
119+ $templateData = Import-Clixml - Path $TemplateInfo.Path - ErrorAction Stop
120+ # region Process Parameters
121+ foreach ($parameter in $templateData.Parameters )
122+ {
123+ if (-not $parameter ) { continue }
124+ if (-not $Parameters.ContainsKey ($parameter ))
125+ {
126+ if ($Silent ) { throw " Parameter not specified: $parameter " }
127+ try
128+ {
129+ $value = Read-Host - Prompt " Enter value for parameter '$parameter '" - ErrorAction Stop
130+ $Parameters [$parameter ] = $value
131+ }
132+ catch { throw }
133+ }
134+ }
135+ # endregion Process Parameters
136+
137+ # region Scripts
138+ $scriptParameters = @ { }
139+
140+ if (-not $Raw )
141+ {
142+ foreach ($scriptParam in $templateData.Scripts.Values )
143+ {
144+ if (-not $scriptParam ) { continue }
145+ try { $scriptParameters [$scriptParam.Name ] = " $ ( [scriptblock ]::Create($scriptParam.StringScript ).Invoke()) " }
146+ catch
147+ {
148+ if ($Silent ) { throw (New-Object System.Exception(" Scriptblock $ ( $scriptParam.Name ) failed during execution: $_ " , $_.Exception )) }
149+ else
150+ {
151+ Write-PSFMessage - Level Warning - Message " Scriptblock $ ( $scriptParam.Name ) failed during execution. Please specify a custom value or use CTRL+C to terminate creation" - ErrorRecord $_ - FunctionName " Invoke-PSMDTemplate" - ModuleName ' PSModuleDevelopment'
152+ $scriptParameters [$scriptParam.Name ] = Read-Host - Prompt " Value for script $ ( $scriptParam.Name ) "
153+ }
154+ }
155+ }
156+ }
157+ # endregion Scripts
158+
159+ switch ($templateData.Type.ToString ())
160+ {
161+ # region File
162+ " File"
163+ {
164+ foreach ($child in $templateData.Children )
165+ {
166+ Write-TemplateItem - Item $child - Path $OutPath - ParameterFlat $Parameters - ParameterScript $scriptParameters - Raw $Raw
167+ }
168+ if ($Raw -and $templateData.Scripts.Values )
169+ {
170+ $templateData.Scripts.Values | Export-Clixml - Path (Join-Path $OutPath " _PSMD_ParameterScripts.xml" )
171+ }
172+ }
173+ # endregion File
174+
175+ # region Project
176+ " Project"
177+ {
178+ # region Resolve output folder
179+ if (-not $NoFolder )
180+ {
181+ if ($Parameters [" Name" ])
182+ {
183+ $projectName = $Parameters [" Name" ]
184+ $projectFullName = Join-Path $OutPath $projectName
185+ if ((Test-Path $projectFullName ) -and (-not $Force ))
186+ {
187+ throw " Project root folder already exists: $projectFullName "
188+ }
189+ $newFolder = New-Item - Path $OutPath - Name $Parameters [" Name" ] - ItemType Directory - ErrorAction Stop - Force
190+ }
191+ else
192+ {
193+ throw " Parameter Name is needed to create a project without setting the -NoFolder parameter!"
194+ }
195+ }
196+ else { $newFolder = Get-Item $OutPath }
197+ # endregion Resolve output folder
198+
199+ foreach ($child in $templateData.Children )
200+ {
201+ Write-TemplateItem - Item $child - Path $newFolder.FullName - ParameterFlat $Parameters - ParameterScript $scriptParameters - Raw $Raw
202+ }
203+
204+ # region Write Config File (Raw)
205+ if ($Raw )
206+ {
207+ $guid = [System.Guid ]::NewGuid().ToString()
208+ $optionsTemplate = @"
209+ @{
210+ TemplateName = "$ ( $TemplateInfo.Name ) "
211+ Version = ([Version]"$ ( $TemplateInfo.Version ) ")
212+ Tags = $ ( ($TemplateInfo.Tags | ForEach-Object { " '$_ '" }) -join " ," )
213+ Author = "$ ( $TemplateInfo.Author ) "
214+ Description = "$ ( $TemplateInfo.Description ) "
215+ þþþPLACEHOLDER-$ ( $guid ) þþþ
216+ }
217+ "@
218+ if ($params = $templateData.Scripts.Values )
219+ {
220+ $list = @ ()
221+ foreach ($param in $params )
222+ {
223+ $list += @"
224+ $ ( $param.Name ) = {
225+ $ ( $param.StringScript )
226+ }
227+ "@
228+ }
229+ $optionsTemplate = $optionsTemplate -replace " þþþPLACEHOLDER-$ ( $guid ) þþþ" , ($list -join " `n`n " )
230+ }
231+ else
232+ {
233+ $optionsTemplate = $optionsTemplate -replace " þþþPLACEHOLDER-$ ( $guid ) þþþ" , " "
234+ }
235+
236+ $configFile = Join-Path $newFolder.FullName " PSMDTemplate.ps1"
237+ Set-Content - Path $configFile - Value $optionsTemplate - Encoding UTF8
238+ }
239+ # endregion Write Config File (Raw)
240+ }
241+ # endregion Project
242+ }
243+ }
0 commit comments