123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- const path = require('path')
- const fs = require('fs')
- const get = require('simple-get')
- const pump = require('pump')
- const tfs = require('tar-fs')
- const zlib = require('zlib')
- const util = require('./util')
- const error = require('./error')
- const proxy = require('./proxy')
- const mkdirp = require('mkdirp-classic')
- function downloadPrebuild (downloadUrl, opts, cb) {
- let cachedPrebuild = util.cachedPrebuild(downloadUrl)
- const localPrebuild = util.localPrebuild(downloadUrl, opts)
- const tempFile = util.tempFile(cachedPrebuild)
- const log = opts.log || util.noopLogger
- if (opts.nolocal) return download()
- log.info('looking for local prebuild @', localPrebuild)
- fs.access(localPrebuild, fs.R_OK | fs.W_OK, function (err) {
- if (err && err.code === 'ENOENT') {
- return download()
- }
- log.info('found local prebuild')
- cachedPrebuild = localPrebuild
- unpack()
- })
- function download () {
- ensureNpmCacheDir(function (err) {
- if (err) return onerror(err)
- log.info('looking for cached prebuild @', cachedPrebuild)
- fs.access(cachedPrebuild, fs.R_OK | fs.W_OK, function (err) {
- if (!(err && err.code === 'ENOENT')) {
- log.info('found cached prebuild')
- return unpack()
- }
- log.http('request', 'GET ' + downloadUrl)
- const reqOpts = proxy({ url: downloadUrl }, opts)
- if (opts.token) {
- reqOpts.headers = {
- 'User-Agent': 'simple-get',
- Accept: 'application/octet-stream',
- Authorization: 'token ' + opts.token
- }
- }
- const req = get(reqOpts, function (err, res) {
- if (err) return onerror(err)
- log.http(res.statusCode, downloadUrl)
- if (res.statusCode !== 200) return onerror()
- mkdirp(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 () {
- let binaryName
- const updateName = opts.updateName || function (entry) {
- if (/\.node$/i.test(entry.name)) binaryName = entry.name
- }
- log.info('unpacking @', cachedPrebuild)
- const options = {
- readable: true,
- writable: true,
- hardlinkAsFilesFallback: true
- }
- const extract = tfs.extract(opts.path, options).on('entry', updateName)
- pump(fs.createReadStream(cachedPrebuild), zlib.createGunzip(), extract,
- function (err) {
- if (err) return cb(err)
- let resolved
- if (binaryName) {
- try {
- resolved = path.resolve(opts.path || '.', binaryName)
- } catch (err) {
- return cb(err)
- }
- log.info('unpack', 'resolved to ' + resolved)
- if (opts.runtime === 'node' && opts.platform === process.platform && opts.abi === process.versions.modules && opts.arch === process.arch) {
- try {
- require(resolved)
- } catch (err) {
- return cb(err)
- }
- log.info('unpack', 'required ' + resolved + ' successfully')
- }
- }
- cb(null, resolved)
- })
- }
- function ensureNpmCacheDir (cb) {
- const cacheFolder = util.npmCache()
- fs.access(cacheFolder, fs.R_OK | fs.W_OK, function (err) {
- if (err && err.code === 'ENOENT') {
- return makeNpmCacheDir()
- }
- cb(err)
- })
- function makeNpmCacheDir () {
- log.info('npm cache directory missing, creating it...')
- mkdirp(cacheFolder, cb)
- }
- }
- }
- module.exports = downloadPrebuild
|