mirror of
https://github.com/pnpm/pnpm.git
synced 2026-02-05 12:41:44 -05:00
56 lines
1.6 KiB
JavaScript
56 lines
1.6 KiB
JavaScript
var debug = require('debug')('pnpm:fetch')
|
|
var got = require('./got')
|
|
var crypto = require('crypto')
|
|
var gunzip = require('gunzip-maybe')
|
|
var tar = require('tar-fs')
|
|
|
|
/*
|
|
* Fetches a tarball `tarball` and extracts it into `dir`
|
|
*/
|
|
|
|
module.exports = function fetch (dir, tarball, shasum, log) {
|
|
return got.getStream(tarball)
|
|
.then(stream => fetchStream(dir, tarball, shasum, log, stream))
|
|
}
|
|
|
|
function fetchStream (dir, tarball, shasum, log, stream) {
|
|
return new Promise((resolve, reject) => {
|
|
var actualShasum = crypto.createHash('sha1')
|
|
var size
|
|
var downloaded = 0
|
|
|
|
stream
|
|
.on('response', start)
|
|
.on('data', _ => { actualShasum.update(_) })
|
|
.on('error', reject)
|
|
.pipe(gunzip()).on('error', reject)
|
|
.pipe(tar.extract(dir, { strip: 1 })).on('error', reject)
|
|
.on('finish', finish)
|
|
|
|
function start (res) {
|
|
if (res.statusCode !== 200) {
|
|
return reject(new Error('' + tarball + ': invalid response ' + res.statusCode))
|
|
}
|
|
|
|
log('download-start')
|
|
if ('content-length' in res.headers) {
|
|
size = +res.headers['content-length']
|
|
res.on('data', chunk => {
|
|
downloaded += chunk.length
|
|
log('downloading', { done: downloaded, total: size })
|
|
})
|
|
}
|
|
}
|
|
|
|
function finish () {
|
|
var digest = actualShasum.digest('hex')
|
|
debug('finish %s %s', shasum, tarball)
|
|
if (shasum && digest !== shasum) {
|
|
return reject(new Error('' + tarball + ': incorrect shasum (expected ' + shasum + ', got ' + digest + ')'))
|
|
}
|
|
|
|
return resolve(dir)
|
|
}
|
|
})
|
|
}
|