You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.5 KiB
129 lines
3.5 KiB
var path = require('path') |
|
var fs = require('fs') |
|
var get = require('simple-get') |
|
var pump = require('pump') |
|
var tfs = require('tar-fs') |
|
var noop = require('noop-logger') |
|
var zlib = require('zlib') |
|
var util = require('./util') |
|
var error = require('./error') |
|
|
|
function downloadPrebuild (opts, cb) { |
|
var downloadUrl = util.getDownloadUrl(opts) |
|
var cachedPrebuild = util.cachedPrebuild(downloadUrl) |
|
var localPrebuild = util.localPrebuild(downloadUrl) |
|
var tempFile = util.tempFile(cachedPrebuild) |
|
|
|
var log = opts.log || noop |
|
|
|
if (opts.nolocal) return download() |
|
|
|
log.info('looking for local prebuild @', localPrebuild) |
|
fs.exists(localPrebuild, function (exists) { |
|
if (exists) { |
|
log.info('found local prebuild') |
|
cachedPrebuild = localPrebuild |
|
return unpack() |
|
} |
|
|
|
download() |
|
}) |
|
|
|
function download () { |
|
ensureNpmCacheDir(function (err) { |
|
if (err) return onerror(err) |
|
|
|
log.info('looking for cached prebuild @', cachedPrebuild) |
|
fs.exists(cachedPrebuild, function (exists) { |
|
if (exists) { |
|
log.info('found cached prebuild') |
|
return unpack() |
|
} |
|
|
|
log.http('request', 'GET ' + downloadUrl) |
|
var req = get(downloadUrl, function (err, res) { |
|
if (err) return onerror(err) |
|
log.http(res.statusCode, downloadUrl) |
|
if (res.statusCode !== 200) return onerror() |
|
fs.mkdir(util.prebuildCache(), function () { |
|
log.info('downloading to @', tempFile) |
|
pump(res, fs.createWriteStream(tempFile), function (err) { |
|
if (err) return onerror(err) |
|
fs.rename(tempFile, cachedPrebuild, function (err) { |
|
if (err) return cb(err) |
|
log.info('renaming to @', cachedPrebuild) |
|
unpack() |
|
}) |
|
}) |
|
}) |
|
}) |
|
|
|
req.setTimeout(30 * 1000, function () { |
|
req.abort() |
|
}) |
|
}) |
|
|
|
function onerror (err) { |
|
fs.unlink(tempFile, function () { |
|
cb(err || error.noPrebuilts(opts)) |
|
}) |
|
} |
|
}) |
|
} |
|
|
|
function unpack () { |
|
var binaryName |
|
|
|
var updateName = opts.updateName || function (entry) { |
|
if (/\.node$/i.test(entry.name)) binaryName = entry.name |
|
} |
|
|
|
log.info('unpacking @', cachedPrebuild) |
|
pump(fs.createReadStream(cachedPrebuild), zlib.createGunzip(), tfs.extract(opts.path, {readable: true, writable: true}).on('entry', updateName), function (err) { |
|
if (err) return cb(err) |
|
if (!binaryName) return cb(error.invalidArchive()) |
|
|
|
var resolved |
|
try { |
|
resolved = path.resolve(opts.path || '.', binaryName) |
|
} catch (err) { |
|
return cb(err) |
|
} |
|
log.info('unpack', 'resolved to ' + resolved) |
|
|
|
if (opts.abi === process.versions.modules) { |
|
try { |
|
require(resolved) |
|
} catch (err) { |
|
return cb(err) |
|
} |
|
log.info('unpack', 'required ' + resolved + ' successfully') |
|
} |
|
cb(null, resolved) |
|
}) |
|
} |
|
|
|
function ensureNpmCacheDir (cb) { |
|
var cacheFolder = util.npmCache() |
|
if (fs.access) { |
|
fs.access(cacheFolder, fs.R_OK | fs.W_OK, function (err) { |
|
if (err && err.code === 'ENOENT') { |
|
return makeNpmCacheDir() |
|
} |
|
cb(err) |
|
}) |
|
} else { |
|
fs.exists(cacheFolder, function (exists) { |
|
if (!exists) return makeNpmCacheDir() |
|
cb() |
|
}) |
|
} |
|
|
|
function makeNpmCacheDir () { |
|
log.info('npm cache directory missing, creating it...') |
|
fs.mkdir(cacheFolder, cb) |
|
} |
|
} |
|
} |
|
|
|
module.exports = downloadPrebuild
|
|
|