Skip to content

Commit

Permalink
Make install-node windows compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
amio committed Apr 8, 2019
1 parent 88a5bd1 commit 3fdf7aa
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@types/yauzl-promise": "2.1.0",
"async-listen": "1.0.0",
"cache-or-tmp-directory": "1.0.0",
"cpy": "7.2.0",
"debug": "4.1.1",
"execa": "1.0.0",
"fs-extra": "7.0.1",
Expand Down
51 changes: 46 additions & 5 deletions src/install-node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { createWriteStream } from 'fs';
import { join } from 'path';
import { extract } from 'tar';
import fetch from 'node-fetch';
import createDebug from 'debug';
import { createGunzip } from 'zlib';
import { unzipToTemp } from './unzip';
import cpy from 'cpy';

const debug = createDebug('@zeit/fun:install-node');

Expand All @@ -13,7 +17,10 @@ export function generateNodeTarballUrl(
if (!version.startsWith('v')) {
version = `v${version}`;
}
return `https://nodejs.org/dist/${version}/node-${version}-${platform}-${arch}.tar.gz`;
const win = platform === 'win32' || platform === 'win64';
const _platform = win ? 'win' : platform;
const ext = win ? 'zip' : 'tar.gz';
return `https://nodejs.org/dist/${version}/node-${version}-${_platform}-${arch}.${ext}`;
}

export async function installNode(
Expand All @@ -22,18 +29,52 @@ export async function installNode(
platform: string = process.platform,
arch: string = process.arch
): Promise<void> {
const tarballUrl = generateNodeTarballUrl(version, platform, arch);
debug('Downloading Node.js %s tarball %o', version, tarballUrl);
const res = await fetch(tarballUrl);
const url = generateNodeTarballUrl(version, platform, arch);
debug('Downloading Node.js %s %o', version, url);

if (platform === 'win32' || platform === 'win64') {
return winExtractRemoteZip(url, dest, version);
}

return extractRemoteTarball(url, dest, version);
}

async function extractRemoteTarball(
url: string,
dest: string,
version: string
): Promise<void> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`HTTP request failed: ${res.status}`);
}
return new Promise((resolve, reject) => {
debug('Extracting Node.js %s tarball to %o', version, dest);
debug('Extracting Node.js %s binary to %o', version, dest);
res.body
.pipe(createGunzip())
.pipe(extract({ strip: 1, C: dest }))
.on('error', reject)
.on('end', resolve);
});
}

async function winExtractRemoteZip(
url: string,
dest: string,
version: string
): Promise<void> {
const zipFilePath = join(dest, 'node-bin.zip');
console.log(zipFilePath);
debug('Extracting Nodejs %s binary to %o', version, dest);
await fetch(url).then(res => {
const writer = res.body.pipe(createWriteStream(zipFilePath));
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
});

const tempDir = await unzipToTemp(zipFilePath);
const subDir = url.match(/([^/]+)\.zip$/)[1];
return cpy([path.join(tempDir, subDir, '*.*')], dest, dest);
}
4 changes: 4 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export function test_install_node_tarball_url() {
'https://nodejs.org/dist/v8.10.0/node-v8.10.0-darwin-x64.tar.gz',
generateNodeTarballUrl('8.10.0', 'darwin', 'x64')
);
assert.equal(
'https://nodejs.org/dist/v8.10.0/node-v8.10.0-win-x86.zip',
generateNodeTarballUrl('8.10.0', 'win32', 'x86')
);
}

export async function test_install_node() {
Expand Down
93 changes: 91 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==

"@types/glob@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"

"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==

"@types/node@*", "@types/[email protected]":
version "10.12.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
Expand Down Expand Up @@ -269,7 +283,7 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=

array-union@^1.0.1:
array-union@^1.0.1, array-union@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
Expand Down Expand Up @@ -671,6 +685,27 @@ [email protected]:
js-yaml "^3.9.0"
parse-json "^4.0.0"

cp-file@^6.1.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d"
integrity sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==
dependencies:
graceful-fs "^4.1.2"
make-dir "^2.0.0"
nested-error-stacks "^2.0.0"
pify "^4.0.1"
safe-buffer "^5.0.1"

[email protected]:
version "7.2.0"
resolved "https://registry.yarnpkg.com/cpy/-/cpy-7.2.0.tgz#6f0f39ec720712628b4702c32263816f4720a364"
integrity sha512-CUYi9WYd7vdtEcq1NKqiS/yY2WdaDCNOBA/AoTQHVJzlpJMqctB8py9JrHgGIft6TgO5m8ZidI4l1ZD+RMr/wA==
dependencies:
arrify "^1.0.1"
cp-file "^6.1.0"
globby "^9.2.0"
nested-error-stacks "^2.1.0"

cross-spawn@^4:
version "4.0.2"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
Expand Down Expand Up @@ -823,6 +858,13 @@ dir-glob@^2.0.0:
dependencies:
path-type "^3.0.0"

dir-glob@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4"
integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==
dependencies:
path-type "^3.0.0"

ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
Expand Down Expand Up @@ -984,7 +1026,7 @@ fast-deep-equal@^2.0.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=

fast-glob@^2.0.2:
fast-glob@^2.0.2, fast-glob@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295"
integrity sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==
Expand Down Expand Up @@ -1241,6 +1283,20 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"

globby@^9.2.0:
version "9.2.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d"
integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==
dependencies:
"@types/glob" "^7.1.1"
array-union "^1.0.2"
dir-glob "^2.2.2"
fast-glob "^2.2.6"
glob "^7.1.3"
ignore "^4.0.3"
pify "^4.0.1"
slash "^2.0.0"

graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.15"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
Expand Down Expand Up @@ -1369,6 +1425,11 @@ ignore@^3.3.5:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==

ignore@^4.0.3:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==

imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
Expand Down Expand Up @@ -1941,6 +2002,14 @@ make-dir@^1.0.0, make-dir@^1.3.0:
dependencies:
pify "^3.0.0"

make-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
dependencies:
pify "^4.0.1"
semver "^5.6.0"

map-age-cleaner@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
Expand Down Expand Up @@ -2122,6 +2191,11 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"

nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==

nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
Expand Down Expand Up @@ -2437,6 +2511,11 @@ pify@^3.0.0:
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=

pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==

pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
Expand Down Expand Up @@ -2771,6 +2850,11 @@ semver-compare@^1.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==

semver@^5.6.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==

set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
Expand Down Expand Up @@ -2830,6 +2914,11 @@ slash@^1.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=

slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==

[email protected]:
version "0.0.4"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
Expand Down

0 comments on commit 3fdf7aa

Please sign in to comment.