forked from meteor/meteor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate-dev-bundle.ps1
443 lines (341 loc) · 14.8 KB
/
generate-dev-bundle.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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
$ErrorActionPreference = "Stop"
$DebugPreference = "Continue"
Import-Module -Force "$PSScriptRoot\windows\dev-bundle-lib.psm1"
$PLATFORM = Get-MeteorPlatform
$PYTHON_VERSION = "2.7.14" # For node-gyp
$dirCheckout = (Get-Item $PSScriptRoot).parent.FullName
$shCommon = Join-Path $PSScriptRoot 'build-dev-bundle-common.sh'
$tempSrcNode = Join-Path $(Join-Path $dirCheckout 'temp_build_src') 'node.7z'
# This will be the temporary directory we build the dev bundle in.
$DIR = Join-Path $dirCheckout 'gdbXXX'
# extract the bundle version from the meteor bash script
$BUNDLE_VERSION = Read-VariableFromShellScript "${dirCheckout}\meteor" 'BUNDLE_VERSION'
# extract the major package versions from the build-dev-bundle-common script.
$MONGO_VERSION_64BIT = Read-VariableFromShellScript $shCommon 'MONGO_VERSION_64BIT'
$MONGO_VERSION_32BIT = Read-VariableFromShellScript $shCommon 'MONGO_VERSION_32BIT'
$NODE_VERSION = Read-VariableFromShellScript $shCommon 'NODE_VERSION'
$NPM_VERSION = Read-VariableFromShellScript $shCommon 'NPM_VERSION'
# 7-zip path.
$system7zip = "C:\Program Files\7-zip\7z.exe"
# Since we reuse the same temp directory, cleanup from previous failed runs.
Remove-DirectoryRecursively $DIR
# Some commonly used paths in this script.
$dirBin = Join-Path $DIR 'bin'
$dirLib = Join-Path $DIR 'lib'
$dirServerLib = Join-Path $DIR 'server-lib'
$dirTemp = Join-Path $DIR 'temp'
# Use a cache just for this build.
$dirNpmCache = Join-Path $dirTemp 'npm-cache'
# Build our directory framework.
New-Item -ItemType Directory -Force -Path $DIR | Out-Null
New-Item -ItemType Directory -Force -Path $dirTemp | Out-Null
New-Item -ItemType Directory -Force -Path $dirBin | Out-Null
New-Item -ItemType Directory -Force -Path $dirLib | Out-Null
New-Item -ItemType Directory -Force -Path $dirServerLib | Out-Null
$webclient = New-Object System.Net.WebClient
$shell = New-Object -com shell.application
Function Invoke-Install7ZipApplication {
Write-Host "Downloading 7-zip..." -ForegroundColor Magenta
$7zMsiPath = Join-Path $dirTemp '7z.msi'
# 32-bit, right now. But this does not go in the bundle.
$webclient.DownloadFile("http://www.7-zip.org/a/7z1604.msi", $7zMsiPath)
Write-Host "Installing 7-zip system-wide..." -ForegroundColor Magenta
& "msiexec.exe" /i $7zMsiPath /quiet /qn /norestart | Out-Null
# Cleanup.
Remove-Item $7zMsiPath
}
Function Add-7ZipTool {
Write-Host "Downloading 7-zip 'extra'..." -ForegroundColor Magenta
$extraArchive = Join-Path $dirTemp 'extra.7z'
$webclient.DownloadFile("http://www.7-zip.org/a/7z1604-extra.7z", $extraArchive)
$pathToExtract = 'x64/7za.exe'
if ($PLATFORM -eq "windows_x86") {
$pathToExtract = '7za.exe'
}
Write-Host 'Placing 7za.exe from extra.7z in \bin...' -ForegroundColor Magenta
& "$system7zip" e $extraArchive -o"$dirTemp" $pathToExtract | Out-Null
Move-Item $(Join-Path $dirTemp '7za.exe') $(Join-Path $dirBin "7z.exe")
# Cleanup
Remove-Item $extraArchive
}
Function Add-Python {
# On Windows we provide a reliable version of python.exe for use by
# node-gyp (the tool that rebuilds binary node modules).
# This self-hosted 7z is created by archiving the result of running the
# Python MSI installer (from python.org), targeted at a temp directory, and
# only including: "Python" and "Utility Scripts". Then, 7z the temp directory.
$pythonUrl = "https://s3.amazonaws.com/com.meteor.static/windows-python/",
"$PLATFORM/python-${PYTHON_VERSION}.7z" -Join ''
$pythonArchive = Join-Path $dirTemp 'python.7z'
$webclient.DownloadFile($pythonUrl, $pythonArchive)
Expand-7zToDirectory $pythonArchive $DIR
$pythonDir = Join-Path $DIR 'python'
$pythonExe = Join-Path $pythonDir 'python.exe'
# Make sure the version is right, when python is called.
if (!(cmd /c python.exe --version '2>&1' -Eq "Python ${PYTHON_VERSION}")) {
throw "Python was not the version we expected it to be ($PYTHON_VERSION)"
}
Remove-Item $pythonArchive
"$pythonExe"
}
Function Add-NodeAndNpm {
$nodeUrlBase = 'https://nodejs.org/dist'
if ($PLATFORM -eq "windows_x86") {
$nodeArchitecture = 'win-x86'
} else {
$nodeArchitecture = 'win-x64'
}
# Various variables which are used as part of directory paths and
# inside Node release and header archives.
$nodeVersionSegment = "v${NODE_VERSION}"
$nodeNameVersionSegment = "node-${nodeVersionSegment}"
$nodeNameSegment = "${nodeNameVersionSegment}-${nodeArchitecture}"
# The URL for the Node 7z archive, which includes its shipped version of npm.
$nodeUrl = $nodeUrlBase, $nodeVersionSegment,
"${nodeNameSegment}.7z" -Join '/'
$archiveNode = Join-Path $dirTemp 'node.7z'
Write-Host "Downloading Node.js from ${nodeUrl}" -ForegroundColor Magenta
$webclient.DownloadFile($nodeUrl, $archiveNode)
Write-Host "Extracting Node 7z file..." -ForegroundColor Magenta
& "$system7zip" x $archiveNode -o"$dirTemp" | Out-Null
# This will be the location of the extracted Node tarball.
$dirTempNode = Join-Path $dirTemp $nodeNameSegment
# Delete the no longer necessary Node archive.
Remove-Item $archiveNode
$tempNodeExe = Join-Path $dirTempNode 'node.exe'
$tempNpmCmd = Join-Path $dirTempNode 'npm.cmd'
# Get additional values we'll need to fetch to complete this release.
$nodeProcessRelease = @{
headersUrl = & "$tempNodeExe" -p 'process.release.headersUrl'
libUrl = & "$tempNodeExe" -p 'process.release.libUrl'
}
if (!($nodeProcessRelease.headersUrl -And $nodeProcessRelease.libUrl)) {
throw "No 'headersUrl' or 'libUrl' in Node.js's 'process.release' output."
}
$nodeHeadersTarGz = Join-Path $dirTemp 'node-headers.tar.gz'
Write-Host "Downloading Node headers from $($nodeProcessRelease.headersUrl)" `
-ForegroundColor Magenta
$webclient.DownloadFile($nodeProcessRelease.headersUrl, $nodeHeadersTarGz)
$dirTempNodeHeaders = Join-Path $dirTemp 'node-headers'
if (!(Expand-TarGzToDirectory $nodeHeadersTarGz $dirTempNodeHeaders)) {
throw "Couldn't extract Node headers."
}
# Move the extracted include directory to the Node dir.
$dirTempNodeHeadersInclude = `
Join-Path $dirTempNodeHeaders $nodeNameVersionSegment |
Join-Path -ChildPath 'include'
Move-Item $dirTempNodeHeadersInclude $dirTempNode
$dirTempNodeHeadersInclude = Join-Path $dirTempNode 'include'
# The node.lib goes into a \Release directory.
$dirNodeRelease = Join-Path $dirTempNode 'Release'
New-Item -ItemType Directory -Force -Path $dirNodeRelease | Out-Null
Write-Host "Downloading node.lib from $($nodeProcessRelease.libUrl)" `
-ForegroundColor Magenta
$nodeLibTarget = Join-Path $dirNodeRelease 'node.lib'
$webclient.DownloadFile($nodeProcessRelease.libUrl, $nodeLibTarget)
#
# We should now have a fully functionaly local Node with headers to use.
#
# Let's install the npm version we really want.
Write-Host "Installing npm@${NPM_VERSION}..." -ForegroundColor Magenta
& "$tempNpmCmd" install --prefix="$dirLib" --no-bin-links --save `
--cache="$dirNpmCache" --nodedir="$dirTempNode" npm@${NPM_VERSION} |
Write-Debug
if ($LASTEXITCODE -ne 0) {
throw "Couldn't install npm@${NPM_VERSION}."
}
# After finishing up with our Node, let's put it in its final home
# and abandon this local npm directory.
# Move exe and cmd files to the \bin directory.
Move-Item $(Join-Path $dirTempNode '*.exe') $dirBin
# Move-Item $(Join-Path $dirTempNode '*.cmd') $dirBin
Move-Item $dirTempNodeHeadersInclude $DIR
Move-Item $dirNodeRelease $DIR
$finalNodeExe = Join-Path $dirBin 'node.exe'
$finalNpmCmd = Join-Path $dirBin 'npm.cmd'
# Uses process.execPath to infer dev_bundle\bin, npm location, &c.
& "$finalNodeExe" "${dirCheckout}\scripts\windows\link-npm-bin-commands.js"
# We use our own npm.cmd.
Copy-Item "${dirCheckout}\scripts\npm.cmd" $finalNpmCmd
Remove-DirectoryRecursively $dirTempNodeHeaders
Remove-DirectoryRecursively $dirTempNode
return New-Object -Type PSObject -Prop $(@{
node = $finalNodeExe
npm = $finalNpmCmd
})
}
Function Add-Mongo {
# Mongo >= 3.4 no longer supports 32-bit (x86) architectures, so we package
# the latest 3.2 version of Mongo for those builds and >= 3.4 for x64.
$mongo_filenames = @{
windows_x86 = "mongodb-win32-i386-${MONGO_VERSION_32BIT}"
windows_x64 = "mongodb-win32-x86_64-2008plus-ssl-${MONGO_VERSION_64BIT}"
}
$previousCwd = $PWD
cd "$DIR"
mkdir "$DIR\mongodb"
mkdir "$DIR\mongodb\bin"
$mongo_name = $mongo_filenames.Item($PLATFORM)
$mongo_link = "https://fastdl.mongodb.org/win32/${mongo_name}.zip"
$mongo_zip = "$DIR\mongodb\mongo.zip"
Write-Host "Downloading Mongo from ${mongo_link}..." -ForegroundColor Magenta
$webclient.DownloadFile($mongo_link, $mongo_zip)
Write-Host "Extracting Mongo ${mongo_zip}..." -ForegroundColor Magenta
$zip = $shell.NameSpace($mongo_zip)
foreach($item in $zip.items()) {
$shell.Namespace("$DIR\mongodb").copyhere($item, 0x14) # 0x10 - overwrite, 0x4 - no dialog
}
Write-Host "Putting MongoDB mongod.exe in \mongodb\bin\" -ForegroundColor Magenta
cp "$DIR\mongodb\$mongo_name\bin\mongod.exe" $DIR\mongodb\bin
Write-Host "Putting MongoDB mongo.exe in \mongodb\bin\" -ForegroundColor Magenta
cp "$DIR\mongodb\$mongo_name\bin\mongo.exe" $DIR\mongodb\bin
Write-Host "Removing the old Mongo zip..." -ForegroundColor Magenta
rm -Recurse -Force $mongo_zip
Write-Host "Removing the old Mongo directory..." -ForegroundColor Magenta
rm -Recurse -Force "$DIR\mongodb\$mongo_name"
cd "$previousCwd"
}
Function Add-NpmModulesFromJsBundleFile {
Param (
[Parameter(Mandatory=$True, Position=0)]
[string]$SourceJs,
[Parameter(Mandatory=$True, Position=1)]
[string]$Destination,
[Parameter(Mandatory=$True)]
$Commands,
[bool]$Shrinkwrap = $False
)
$previousCwd = $PWD
If (!(Test-Path $SourceJs)) {
throw "Couldn't find the source: $SourceJs"
}
New-Item -ItemType Directory -Force -Path $Destination | Out-Null
cd "$Destination"
Write-Host "Writing 'package.json' from ${SourceJs} to ${Destination}" `
-ForegroundColor Magenta
& "$($Commands.node)" $SourceJs |
Out-File -FilePath $(Join-Path $Destination 'package.json') -Encoding ascii
# No bin-links because historically, they weren't used anyway.
& "$($Commands.npm)" install
if ($LASTEXITCODE -ne 0) {
throw "Couldn't install npm packages."
}
# As of npm@5, this just renames `package-lock.json` to `npm-shrinkwrap.json`.
if ($Shrinkwrap -eq $True) {
& "$($Commands.npm)" shrinkwrap
if ($LASTEXITCODE -ne 0) {
throw "Couldn't make shrinkwrap."
}
}
# Since we install a patched version of pacote in $Destination\lib\node_modules,
# we need to remove npm's bundled version to make it use the new one.
cd node_modules
if (Test-Path "pacote") {
Remove-DirectoryRecursively "npm\node_modules\pacote"
}
cd "$previousCwd"
}
# Install the global 7zip application, if necessary.
if (!(Test-Path "$system7zip")) {
Write-Host "Installing 7-zip since not found at ${system7zip}" `
-ForegroundColor Magenta
Invoke-Install7ZipApplication
}
# Download and install 7zip command-line tool into \bin
Add-7ZipTool
# Download and install Mongo binaries into \bin
Add-Mongo
# Add Python to \bin, and use it for Node Gyp.
$env:PYTHON = Add-Python
# Set additional options for node-gyp
$env:GYP_MSVS_VERSION = "2015"
$env:npm_config_nodedir = "$DIR"
$env:npm_config_cache = "$dirNpmCache"
# Allow running $dirBin commands like node and npm.
$env:PATH = "$env:PATH;$dirBin"
# Install Node.js and npm and get their paths to use from here on.
$toolCmds = Add-NodeAndNpm
"Location of node.exe:"
& Get-Command node | Select-Object -ExpandProperty Definition
"Node process.versions:"
& node -p 'process.versions'
"Location of npm.cmd:"
& Get-Command npm | Select-Object -ExpandProperty Definition
"Npm 'version':"
& npm version
npm config set loglevel error
#
# Install the npms for the 'server'.
#
$npmServerArgs = @{
sourceJs = "${dirCheckout}\scripts\dev-bundle-server-package.js"
destination = $dirServerLib
commands = $toolCmds
shrinkwrap = $True
}
Add-NpmModulesFromJsBundleFile @npmServerArgs
# These are used by the Meteor tool bundler and written to the Meteor build.
# For information, see the 'ServerTarget' class in tools/isobuild/bundler.js,
# and look for 'serverPkgJson' and 'npm-shrinkwrap.json'
mkdir -Force "${DIR}\etc"
Move-Item $(Join-Path $dirServerLib 'package.json') "${DIR}\etc\"
Move-Item $(Join-Path $dirServerLib 'npm-shrinkwrap.json') "${DIR}\etc\"
#
# Install the npms for the 'tool'.
#
$npmToolArgs = @{
sourceJs = "${dirCheckout}\scripts\dev-bundle-tool-package.js"
destination = $dirLib
commands = $toolCmds
}
Add-NpmModulesFromJsBundleFile @npmToolArgs
# Leaving these probably doesn't hurt, but are removed for consistency w/ Unix.
Remove-Item $(Join-Path $dirLib 'package.json')
Remove-Item $(Join-Path $dirLib 'package-lock.json')
Write-Host "Done writing node_modules build(s)..." -ForegroundColor Magenta
Write-Host "Removing temp scratch $dirTemp" -ForegroundColor Magenta
Remove-DirectoryRecursively $dirTemp
# mark the version
Write-Host "Writing out the bundle version..." -ForegroundColor Magenta
echo "${BUNDLE_VERSION}" | Out-File $(Join-Path $DIR '.bundle_version.txt') -Encoding ascii
$devBundleName = "dev_bundle_${PLATFORM}_${BUNDLE_VERSION}"
$dirBundlePreArchive = Join-Path $dirCheckout $devBundleName
$devBundleTmpTar = Join-Path $dirCheckout "dev_bundle.tar"
$devBundleTarGz = Join-Path $dirCheckout "${devBundleName}.tar.gz"
# Cleanup from previous builds, if there are things in our way.
Remove-DirectoryRecursively $dirBundlePreArchive
If (Test-Path $devBundleTmpTar) {
Remove-Item -Force $devBundleTmpTar
}
If (Test-Path $devBundleTarGz) {
Remove-Item -Force $devBundleTarGz
}
# Get out of this directory, before we rename it.
cd "$DIR\.."
# rename the folder with the devbundle
Write-Host "Renaming to $dirBundlePreArchive" -ForegroundColor Magenta
Rename-Item "$DIR" $dirBundlePreArchive
Write-Host "Compressing $dirBundlePreArchive to $devBundleTmpTar"
& "$system7zip" a -ttar $devBundleTmpTar $dirBundlePreArchive
if ($LASTEXITCODE -ne 0) {
throw "Failure while building $devBundleTmpTar"
}
if ((Get-Item $devBundleTmpTar).length -lt 50mb) {
throw "Dev bundle .tar is <50mb. If this is correct, update this message!"
}
Write-Host "Compressing $devBundleTmpTar into $devBundleTarGz" `
-ForegroundColor Magenta
& "$system7zip" a -tgzip $devBundleTarGz $devBundleTmpTar
if ($LASTEXITCODE -ne 0) {
throw "Failure while building $devBundleTarGz"
}
if ((Get-Item $devBundleTarGz).length -lt 30mb) {
throw "Dev bundle .tar.gz is <30mb. If this is correct, update this message!"
}
Write-Host "Removing $devBundleTmpTar" -ForegroundColor Magenta
Remove-Item -Force $devBundleTmpTar
Write-Host "Removing the '$devBundleName' temp directory." `
-ForegroundColor Magenta
Remove-DirectoryRecursively $dirBundlePreArchive
Write-Host "Done building Dev Bundle!" -ForegroundColor Green
Exit 0