76 lines
2.0 KiB
JavaScript
76 lines
2.0 KiB
JavaScript
const
|
|
unZip = require('zlib').createGunzip,
|
|
unTar = require('tar').Extract,
|
|
request = require('request'),
|
|
{ Promise, promisify } = require('bluebird'),
|
|
statAsync = promisify(require('fs').stat),
|
|
rimrafAsync = promisify(require('rimraf'))
|
|
|
|
function progress (req, log, precision = 10) {
|
|
const logged = {}
|
|
let length = 0,
|
|
total = 1
|
|
|
|
return req.on('response', (res) => {
|
|
total = res.headers['content-length']
|
|
}).on('data', (chunk) => {
|
|
length += chunk.length
|
|
const percentComplete = +(length / total * 100).toFixed()
|
|
if (percentComplete % precision === 0 && !logged[percentComplete]) {
|
|
logged[percentComplete] = true
|
|
log(percentComplete)
|
|
}
|
|
})
|
|
}
|
|
|
|
function fetchNodeSource (path, url, log) {
|
|
log.info('Downloading Node: ' + url)
|
|
return new Promise((resolve, reject) => {
|
|
progress(request.get(url), (pc) => {
|
|
log.verbose(`Downloading Node: ${pc}%...`)
|
|
if (pc === 100) {
|
|
log.info('Extracting Node...')
|
|
}
|
|
}).on('error', reject)
|
|
.pipe(unZip().on('error', reject))
|
|
.pipe(unTar({ path, strip: 1 }))
|
|
.on('error', reject)
|
|
.on('end', () => resolve(log.info('Extracted to: ' + path)))
|
|
})
|
|
}
|
|
|
|
function cleanSrc (clean, src, log) {
|
|
if (clean === true) {
|
|
log.info('Removing source: ' + src)
|
|
return rimrafAsync(src).then(() => {
|
|
log.info('Source deleted.' + src)
|
|
})
|
|
}
|
|
return Promise.resolve()
|
|
}
|
|
|
|
/**
|
|
* Deletes (maybe) and downloads the node source to the configured temporary directory
|
|
* @param {*} compiler
|
|
* @param {*} next
|
|
*/
|
|
function download (compiler, next) {
|
|
const
|
|
{ src, log } = compiler,
|
|
{ version, sourceUrl, clean } = compiler.options,
|
|
url = sourceUrl ||
|
|
`https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`
|
|
|
|
return cleanSrc(clean, src, log).then(() => statAsync(src).then(
|
|
x => !x.isDirectory() && fetchNodeSource(src, url, log),
|
|
e => {
|
|
if (e.code !== 'ENOENT') {
|
|
throw e
|
|
}
|
|
return fetchNodeSource(src, url, log)
|
|
}
|
|
)).then(next)
|
|
}
|
|
|
|
module.exports.download = download
|