-
Notifications
You must be signed in to change notification settings - Fork 25
/
createFromTemplate.ps1
282 lines (236 loc) · 9.81 KB
/
createFromTemplate.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# suppress warnings that we need to use
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidOverwritingBuiltInCmdlets', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingInvokeExpression', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingPositionalParameters', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidGlobalVars', ""
)]
param()
# include
. "$(Split-Path $MyInvocation.MyCommand.Path -Parent)/utils/formatJson.ps1"
. "$(Split-Path $MyInvocation.MyCommand.Path -Parent)/utils/replaceTasksInput.ps1"
$templateFolder = $args[0]
$projectName = $args[1]
$containerName = $args[2]
$location = $args[3]
# optional
$template = $args[4]
$vscode = $args[5]
$telemetry = $args[6]
# is enabled by default
if ([string]::IsNullOrEmpty($telemetry)) {
$_TELEMETRY = $true
} else {
$_TELEMETRY = ($telemetry -eq "true" ? $true : $false)
}
if ([string]::IsNullOrEmpty($template)) {
$template = "undefined"
}
if ([string]::IsNullOrEmpty($templateFolder)) {
$templateFolder = Read-Host "Template Folder"
if ($templateFolder -eq "") {
throw "❌ Template folder cannot be empty"
}
}
if ([string]::IsNullOrEmpty($projectName)) {
$projectName = Read-Host "Project Name"
if ($projectName -eq "") {
throw "❌ Project name cannot be empty"
}
}
if ([string]::IsNullOrEmpty($containerName)) {
$containerName = Read-Host "Container Name"
if ($containerName -eq "") {
throw "❌ Container name cannot be empty"
}
}
# container name needs to be lower case
$containerName = $containerName.ToLower()
if (-not [string]::IsNullOrEmpty($location)) {
# special case for automation
$location = "$location/$projectName"
} else {
$location = "$projectName"
}
Write-Host "Data::"
Write-Host "Template Folder -> $templateFolder"
Write-Host "Project Name -> $projectName"
Write-Host "Container Name -> $containerName"
# get the metadata
$_metadata = Get-Content "$templateFolder/../templates.json" | ConvertFrom-Json
$_templateMetadata =
$_metadata.Templates |
Where-Object { $_.folder -eq $template }
# send telemetry
if ($_TELEMETRY -eq $true) {
try {
$ProgressPreference = 'SilentlyContinue'
$_query = @{
template = $template
}
Invoke-WebRequest `
-UseBasicParsing `
-Uri `
"http://ec2-3-133-114-116.us-east-2.compute.amazonaws.com/api/template/plus" `
-Body $_query `
-Method Get | Out-Null
} catch {
Write-Host -ForegroundColor Red "Telemetry Error"
}
} else {
Write-Host -ForegroundColor Yellow "Telemetry disabled"
}
# create the copy
Write-Host -ForegroundColor Yellow "Creating from template ..."
Copy-Item $templateFolder $location -Recurse
Write-Host -ForegroundColor DarkGreen "✅ Folder copy done"
# apply the common tasks and inputs
if ($_templateMetadata.mergeCommon -ne $False) {
Write-Host -ForegroundColor Yellow "Applying common tasks ..."
$commonTasks =
Get-Content "$templateFolder/../assets/tasks/common.json" |
ConvertFrom-Json
$commonInputs =
Get-Content "$templateFolder/../assets/tasks/inputs.json" |
ConvertFrom-Json
$projTasks =
Get-Content "$location/.vscode/tasks.json" |
ConvertFrom-Json
$projTasks.tasks += $commonTasks.tasks
$projTasks.inputs += $commonInputs.inputs
ConvertTo-Json -Depth 100 -InputObject $projTasks | `
Format-Json | `
Out-File -FilePath "$location/.vscode/tasks.json"
Write-Host -ForegroundColor DarkGreen "✅ Common tasks applied"
}
# we have to also copy the scripts
Copy-Item "$templateFolder/../scripts/checkDeps.ps1" "$location/.conf/"
Copy-Item "$templateFolder/../scripts/runContainerIfNotExists.ps1" "$location/.conf/"
Copy-Item "$templateFolder/../scripts/shareWSLPorts.ps1" "$location/.conf/"
Copy-Item "$templateFolder/../scripts/createDockerComposeProduction.ps1" "$location/.conf"
Copy-Item "$templateFolder/../scripts/torizonPackages.ps1" "$location/.conf"
Copy-Item "$templateFolder/../scripts/tasks.ps1" "$location/.vscode"
Copy-Item "$templateFolder/../scripts/bash/tcb-env-setup.sh" "$location/.conf"
Copy-Item "$templateFolder/../scripts/torizonIO.ps1" "$location/.conf"
Copy-Item "$templateFolder/../scripts/checkCIEnv.ps1" "$location/.conf"
Copy-Item "$templateFolder/../scripts/validateDepsRunning.ps1" "$location/.conf"
$templateName = Split-Path -Path $templateFolder -Leaf
# tcb does not have the Dockerfile and Dockerfile.debug, and therefore torizonPackages.json
if ($templateName -ne "tcb") {
$_torPackagesJson = Get-Content -Path "$templateFolder/../assets/json/torizonPackages.json" | ConvertFrom-Json
# Check also the build part of Dockerfile, for the presence of torizon_packages_build
$dockerfileLines = Get-Content -Path "$templateFolder/Dockerfile"
$buildDepDockerfile = $false
foreach ($line in $dockerfileLines) {
if ($line.Contains("torizon_packages_build")) {
$buildDepDockerfile = $true
break
}
}
if ((Test-Path -Path "$templateFolder/Dockerfile.sdk") -Or ($buildDepDockerfile)) {
$_torPackagesJson | Add-Member -NotePropertyName buildDeps -NotePropertyValue @()
}
# Generic template does not have Dockerfile.debug
if (!(Test-Path -Path "$templateFolder/Dockerfile.debug") ) {
$_torPackagesJson.PSObject.Properties.Remove('devRuntimeDeps')
}
# Save the modified JSON object to a file
Set-Content -Path "$location/torizonPackages.json" -Value ($_torPackagesJson | ConvertTo-Json) -Encoding UTF8
}
# Check if there are scripts defined in the .conf/deps.json of the template and, if so,
# copy them to the .conf of the project
$_deps = Get-Content "$templateFolder/.conf/deps.json" | ConvertFrom-Json
# If there are installation scripts listed on the .conf/deps.json of the template
if (($_deps.installDepsScripts.Count -gt 0)) {
# Create the .conf/installDepsScripts if it doesn't exist and there are
# installation scripts that have the path .conf/installDepsScripts
if (-not (Test-Path -Path "$location/.conf/installDepsScripts" )){
New-Item -ItemType Directory -Path "$location/.conf/installDepsScripts"
}
# If there is no script in the .conf/installDepsScripts of the template, but there is some script defined in the
# installDepsScripts with the .conf/installDepsScripts path, then it comes from the scripts/installDepsScripts
# folder of the vscode-torizon-templates repo. This is useful when there are scripts that are common for many
# templates, like the installDotnetSDK8.sh one for example.
foreach ($script in $_deps.installDepsScripts) {
if ((-not (Test-Path -Path "$location/$script" )) -and
$script -match ".conf/installDepsScripts") {
# Copy the script from the scripts/installDepsScripts folder to the .conf/installDepsScripts folder of the template
$scriptSource = $script.Replace(".conf","scripts")
Copy-Item "$templateFolder/../$scriptSource" "$location/$script"
}
}
}
# copy the github actions if not exists
if (-not (Test-Path "$location/.github")) {
New-Item "$location/.github" -ItemType Directory
Copy-Item "$templateFolder/../assets/github/workflows" "$location/.github" -Recurse
}
# copy the .gitlab ci if not exits
if (-not (Test-Path "$location/.gitlab-ci.yml")) {
Copy-Item "$templateFolder/../assets/gitlab/.gitlab-ci.yml" "$location/.gitlab-ci.yml"
}
# create a dot file to store the template that was used
Write-Output "$template" | Out-File -FilePath "$location/.conf/.template"
Write-Output "$containerName" | Out-File -FilePath "$location/.conf/.container"
Write-Host -ForegroundColor DarkGreen "✅ Scripts copy done"
Set-Location $location
# change the folders that is needed
Write-Host -ForegroundColor Yellow "Renaming folders ..."
Get-ChildItem -Path . `
-Filter *__change__* -Recurse | ForEach-Object {
Write-Host $_
Rename-Item $_ ($_ -replace "__change__",$projectName)
}
Write-Host -ForegroundColor DarkGreen "✅ Project folders ok"
# change the contents
Write-Host -ForegroundColor Yellow "Renaming file contents ..."
Get-ChildItem -Force -File -Recurse * | ForEach-Object {
Write-Host $_
$a = $_.fullname;
# do not mess up with binary files
$mimeType = file --mime-encoding $a
if (-not $mimeType.Contains("binary")) {
# FIXME: we are not using key pair anymore, maintaining this for compatibility
# id_rsa is a special case, is ascii but we do not have permissions
if (-not $a.Contains("id_rsa")) {
if ($_ -isnot [System.IO.DirectoryInfo]) {
( Get-Content $a ) |
ForEach-Object {
$_ -replace "__change__",$projectName
} | Set-Content $a
( Get-Content $a ) |
ForEach-Object {
$_ -replace "__container__",$containerName
} | Set-Content $a
( Get-Content $a ) |
ForEach-Object {
$_ -replace "__home__",$env:HOME
} | Set-Content $a
( Get-Content $a ) |
ForEach-Object {
$_ -replace "__templateFolder__", $template
} | Set-Content $a
}
} elseif (-not $a.Contains("id_rsa.pub")) {
chmod 0400 $a
}
}
}
# the project updater does not need to change the contents
Copy-Item "$templateFolder/../scripts/projectUpdater.ps1" "$location/.conf"
# if from vscode we need to replace the inputs
if (-not [string]::IsNullOrEmpty($vscode)) {
Replace-Tasks-Input
}
Write-Host -ForegroundColor DarkGreen "✅ Renaming file contents ok"
# back
Set-Location -