diff options
Diffstat (limited to 'deps/npm/node_modules/pacote/lib')
12 files changed, 147 insertions, 344 deletions
diff --git a/deps/npm/node_modules/pacote/lib/extract-stream.js b/deps/npm/node_modules/pacote/lib/extract-stream.js index b7694876ba..b3c720b07f 100644 --- a/deps/npm/node_modules/pacote/lib/extract-stream.js +++ b/deps/npm/node_modules/pacote/lib/extract-stream.js @@ -1,6 +1,5 @@ 'use strict' -const PassThrough = require('stream').PassThrough const path = require('path') const tar = require('tar') @@ -11,29 +10,7 @@ function computeMode (fileMode, optMode, umask) { return (fileMode | optMode) & ~(umask || 0) } -function pkgJsonTransform (spec, opts) { - return entry => { - if (entry.path === 'package.json') { - const transformed = new PassThrough() - let str = '' - entry.on('end', () => transformed.end(str.replace( - /}\s*$/, - `\n,"_resolved": ${ - JSON.stringify(opts.resolved || '') - }\n,"_integrity": ${ - JSON.stringify(opts.integrity || '') - }\n,"_from": ${ - JSON.stringify(spec.toString()) - }\n}` - ))) - entry.on('error', e => transformed.emit('error')) - entry.on('data', d => { str += d }) - return transformed - } - } -} - -function extractStream (spec, dest, opts) { +function extractStream (dest, opts) { opts = opts || {} const sawIgnores = new Set() return tar.x({ @@ -43,7 +20,6 @@ function extractStream (spec, dest, opts) { onwarn: msg => opts.log && opts.log.warn('tar', msg), uid: opts.uid, gid: opts.gid, - transform: opts.resolved && pkgJsonTransform(spec, opts), onentry (entry) { if (entry.type.toLowerCase() === 'file') { entry.mode = computeMode(entry.mode, opts.fmode, opts.umask) diff --git a/deps/npm/node_modules/pacote/lib/fetchers/file.js b/deps/npm/node_modules/pacote/lib/fetchers/file.js index 5688cd1bdd..48bec0c2d8 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/file.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/file.js @@ -52,13 +52,13 @@ Fetcher.impl(fetchFile, { } else { let integrity const cacheWriter = !opts.cache - ? BB.resolve(null) - : (pipe( - fs.createReadStream(src), - cacache.put.stream(opts.cache, `pacote:tarball:${src}`, { - integrity: opts.integrity - }).on('integrity', d => { integrity = d }) - )) + ? BB.resolve(null) + : (pipe( + fs.createReadStream(src), + cacache.put.stream(opts.cache, `pacote:tarball:${src}`, { + integrity: opts.integrity + }).on('integrity', d => { integrity = d }) + )) return cacheWriter.then(() => { if (integrity) { stream.emit('integrity', integrity) } return pipe(fs.createReadStream(src), stream) diff --git a/deps/npm/node_modules/pacote/lib/fetchers/git.js b/deps/npm/node_modules/pacote/lib/fetchers/git.js index 6ce966ae5d..11b5695255 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/git.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/git.js @@ -135,16 +135,16 @@ function resolve (url, spec, name, opts) { const isSemver = !!spec.gitRange return git.revs(url, opts).then(remoteRefs => { return isSemver - ? pickManifest({ - versions: remoteRefs.versions, - 'dist-tags': remoteRefs['dist-tags'], - name: name - }, spec.gitRange, opts) - : remoteRefs - ? BB.resolve( - remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]] - ) - : null + ? pickManifest({ + versions: remoteRefs.versions, + 'dist-tags': remoteRefs['dist-tags'], + name: name + }, spec.gitRange, opts) + : remoteRefs + ? BB.resolve( + remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]] + ) + : null }) } diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js index 3a2a4a5a77..a947ccea55 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js @@ -68,12 +68,12 @@ function logRequest (uri, res, startTime, opts) { function getCacheMode (opts) { return opts.offline - ? 'only-if-cached' - : opts.preferOffline - ? 'force-cache' - : opts.preferOnline - ? 'no-cache' - : 'default' + ? 'only-if-cached' + : opts.preferOffline + ? 'force-cache' + : opts.preferOnline + ? 'no-cache' + : 'default' } function getHeaders (uri, registry, opts) { diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js index 4e5a8010e2..4488ddb4c7 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js @@ -28,8 +28,8 @@ function manifest (spec, opts) { function metadataUrl (registry, name) { const normalized = registry.slice(-1) !== '/' - ? registry + '/' - : registry + ? registry + '/' + : registry return url.resolve(normalized, name) } diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js index 89158d3929..2c63872e7f 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js @@ -7,40 +7,22 @@ const manifest = require('./manifest') const optCheck = require('../../util/opt-check') const PassThrough = require('stream').PassThrough const pickRegistry = require('./pick-registry') +const pipe = BB.promisify(require('mississippi').pipe) const ssri = require('ssri') const url = require('url') module.exports = tarball function tarball (spec, opts) { opts = optCheck(opts) - const registry = pickRegistry(spec, opts) const stream = new PassThrough() - let mani - if ( - opts.resolved && - // spec.type === 'version' && - opts.resolved.indexOf(registry) === 0 - ) { - // fakeChild is a shortcut to avoid looking up a manifest! - mani = BB.resolve({ - name: spec.name, - version: spec.fetchSpec, - _integrity: opts.integrity, - _resolved: opts.resolved, - _fakeChild: true - }) - } else { - // We can't trust opts.resolved if it's going to a separate host. - mani = manifest(spec, opts) - } - - mani.then(mani => { - !mani._fakeChild && stream.emit('manifest', mani) - const fetchStream = fromManifest(mani, spec, opts).on( - 'integrity', i => stream.emit('integrity', i) + manifest(spec, opts).then(manifest => { + stream.emit('manifest', manifest) + return pipe( + fromManifest(manifest, spec, opts).on( + 'integrity', i => stream.emit('integrity', i) + ), + stream ) - fetchStream.on('error', err => stream.emit('error', err)) - fetchStream.pipe(stream) }).catch(err => stream.emit('error', err)) return stream } @@ -51,43 +33,45 @@ function fromManifest (manifest, spec, opts) { opts.scope = spec.scope || opts.scope const stream = new PassThrough() const registry = pickRegistry(spec, opts) - const uri = getTarballUrl(spec, registry, manifest, opts) + const uri = getTarballUrl(registry, manifest) fetch(uri, registry, Object.assign({ headers: { 'pacote-req-type': 'tarball', - 'pacote-pkg-id': `registry:${manifest.name}@${uri}` + 'pacote-pkg-id': `registry:${ + spec.type === 'remote' + ? spec + : `${manifest.name}@${manifest.version}` + }` }, integrity: manifest._integrity, algorithms: [ manifest._integrity - ? ssri.parse(manifest._integrity).pickAlgorithm() - : 'sha1' + ? ssri.parse(manifest._integrity).pickAlgorithm() + : 'sha1' ], spec - }, opts)) - .then(res => { - const hash = res.headers.get('x-local-cache-hash') - if (hash) { - stream.emit('integrity', decodeURIComponent(hash)) - } - res.body.on('error', err => stream.emit('error', err)) - res.body.pipe(stream) - }) - .catch(err => stream.emit('error', err)) + }, opts)).then(res => { + const hash = res.headers.get('x-local-cache-hash') + if (hash) { + stream.emit('integrity', decodeURIComponent(hash)) + } + res.body.on('error', err => stream.emit('error', err)) + res.body.pipe(stream) + }).catch(err => stream.emit('error', err)) return stream } -function getTarballUrl (spec, registry, mani, opts) { - const reg = url.parse(registry) - const tarball = url.parse(mani._resolved) +function getTarballUrl (registry, manifest) { // https://github.com/npm/npm/pull/9471 // - // TL;DR: Some alternative registries host tarballs on http and packuments - // on https, and vice-versa. There's also a case where people who can't use - // SSL to access the npm registry, for example, might use - // `--registry=http://registry.npmjs.org/`. In this case, we need to - // rewrite `tarball` to match the protocol. + // TL;DR: Some alternative registries host tarballs on http and packuments on + // https, and vice-versa. There's also a case where people who can't use SSL + // to access the npm registry, for example, might use + // `--registry=http://registry.npmjs.org/`. In this case, we need to rewrite + // `tarball` to match the protocol. // + const reg = url.parse(registry) + const tarball = url.parse(manifest._resolved) if (reg.hostname === tarball.hostname && reg.protocol !== tarball.protocol) { tarball.protocol = reg.protocol // Ports might be same host different protocol! diff --git a/deps/npm/node_modules/pacote/lib/finalize-manifest.js b/deps/npm/node_modules/pacote/lib/finalize-manifest.js index a5ec7a7348..86b273b215 100644 --- a/deps/npm/node_modules/pacote/lib/finalize-manifest.js +++ b/deps/npm/node_modules/pacote/lib/finalize-manifest.js @@ -38,8 +38,8 @@ function finalizeManifest (pkg, spec, opts) { opts = optCheck(opts) const cachedManifest = (opts.cache && key && !opts.preferOnline && !opts.fullMetadata) - ? cacache.get.info(opts.cache, key, opts) - : BB.resolve(null) + ? cacache.get.info(opts.cache, key, opts) + : BB.resolve(null) return cachedManifest.then(cached => { if (cached && cached.metadata.manifest) { @@ -47,8 +47,8 @@ function finalizeManifest (pkg, spec, opts) { } else { return tarballedProps(pkg, spec, opts).then(props => { return pkg && pkg.name - ? new Manifest(pkg, props, opts.fullMetadata) - : new Manifest(props, null, opts.fullMetadata) + ? new Manifest(pkg, props, opts.fullMetadata) + : new Manifest(props, null, opts.fullMetadata) }).then(manifest => { const cacheKey = key || finalKey(manifest, spec) if (!opts.cache || !cacheKey) { @@ -169,8 +169,8 @@ function tarballedProps (pkg, spec, opts) { // to add to bin if (paths && paths.length) { const dirBin = mani - ? (mani && mani.directories && mani.directories.bin) - : (pkg && pkg.directories && pkg.directories.bin) + ? (mani && mani.directories && mani.directories.bin) + : (pkg && pkg.directories && pkg.directories.bin) if (dirBin) { extraProps.bin = {} paths.forEach(filePath => { diff --git a/deps/npm/node_modules/pacote/lib/util/git.js b/deps/npm/node_modules/pacote/lib/util/git.js index b854208ef9..a6162ceeba 100644 --- a/deps/npm/node_modules/pacote/lib/util/git.js +++ b/deps/npm/node_modules/pacote/lib/util/git.js @@ -12,10 +12,8 @@ const optCheck = require('./opt-check') const osenv = require('osenv') const path = require('path') const pinflight = require('promise-inflight') -const promiseRetry = require('promise-retry') const uniqueFilename = require('unique-filename') const which = BB.promisify(require('which')) -const semver = require('semver') const GOOD_ENV_VARS = new Set([ 'GIT_ASKPASS', @@ -27,23 +25,6 @@ const GOOD_ENV_VARS = new Set([ 'GIT_SSL_NO_VERIFY' ]) -const GIT_TRANSIENT_ERRORS = [ - 'remote error: Internal Server Error', - 'The remote end hung up unexpectedly', - 'Connection timed out', - 'Operation timed out', - 'Failed to connect to .* Timed out', - 'Connection reset by peer', - 'SSL_ERROR_SYSCALL', - 'The requested URL returned error: 503' -].join('|') - -const GIT_TRANSIENT_ERROR_RE = new RegExp(GIT_TRANSIENT_ERRORS) - -function shouldRetry (error) { - return GIT_TRANSIENT_ERROR_RE.test(error) -} - const GIT_ = 'GIT_' let GITENV function gitEnv () { @@ -132,51 +113,57 @@ function revs (repo, opts) { return pinflight(`ls-remote:${repo}`, () => { return spawnGit(['ls-remote', '-h', '-t', repo], { env: gitEnv() - }, opts).then((stdout) => { - return stdout.split('\n').reduce((revs, line) => { - const split = line.split(/\s+/, 2) - if (split.length < 2) { return revs } - const sha = split[0].trim() - const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1] - if (!ref) { return revs } // ??? - if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap - const type = refType(line) - const doc = {sha, ref, type} - - revs.refs[ref] = doc - // We can check out shallow clones on specific SHAs if we have a ref - if (revs.shas[sha]) { - revs.shas[sha].push(ref) - } else { - revs.shas[sha] = [ref] - } - - if (type === 'tag') { - const match = ref.match(/v?(\d+\.\d+\.\d+(?:[-+].+)?)$/) - if (match && semver.valid(match[1], true)) { - revs.versions[semver.clean(match[1], true)] = doc + }, opts).then(child => { + let stdout = '' + let stderr = '' + child.stdout.on('data', d => { stdout += d }) + child.stderr.on('data', d => { stderr += d }) + return finished(child).catch(err => { + err.message = `Error while executing:\n${GITPATH} ls-remote -h -t ${repo}\n\n${stderr}\n${err.message}` + throw err + }).then(() => { + return stdout.split('\n').reduce((revs, line) => { + const split = line.split(/\s+/, 2) + if (split.length < 2) { return revs } + const sha = split[0].trim() + const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1] + if (!ref) { return revs } // ??? + if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap + const type = refType(line) + const doc = {sha, ref, type} + + revs.refs[ref] = doc + // We can check out shallow clones on specific SHAs if we have a ref + if (revs.shas[sha]) { + revs.shas[sha].push(ref) + } else { + revs.shas[sha] = [ref] } - } - return revs - }, {versions: {}, 'dist-tags': {}, refs: {}, shas: {}}) - }, err => { - err.message = `Error while executing:\n${GITPATH} ls-remote -h -t ${repo}\n\n${err.stderr}\n${err.message}` - throw err - }).then(revs => { - if (revs.refs.HEAD) { - const HEAD = revs.refs.HEAD - Object.keys(revs.versions).forEach(v => { - if (v.sha === HEAD.sha) { - revs['dist-tags'].HEAD = v - if (!revs.refs.latest) { - revs['dist-tags'].latest = revs.refs.HEAD + if (type === 'tag') { + const match = ref.match(/v?(\d+\.\d+\.\d+)$/) + if (match) { + revs.versions[match[1]] = doc } } - }) - } - REVS.set(repo, revs) - return revs + + return revs + }, {versions: {}, 'dist-tags': {}, refs: {}, shas: {}}) + }).then(revs => { + if (revs.refs.HEAD) { + const HEAD = revs.refs.HEAD + Object.keys(revs.versions).forEach(v => { + if (v.sha === HEAD.sha) { + revs['dist-tags'].HEAD = v + if (!revs.refs.latest) { + revs['dist-tags'].latest = revs.refs.HEAD + } + } + }) + } + REVS.set(repo, revs) + return revs + }) }) }) } @@ -185,18 +172,7 @@ module.exports._exec = execGit function execGit (gitArgs, gitOpts, opts) { opts = optCheck(opts) return checkGit().then(gitPath => { - return promiseRetry((retry, number) => { - if (number !== 1) { - opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number) - } - return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts)).catch((err) => { - if (shouldRetry(err)) { - retry(err) - } else { - throw err - } - }) - }, opts.retry) + return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts)) }) } @@ -204,28 +180,7 @@ module.exports._spawn = spawnGit function spawnGit (gitArgs, gitOpts, opts) { opts = optCheck(opts) return checkGit().then(gitPath => { - return promiseRetry((retry, number) => { - if (number !== 1) { - opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number) - } - const child = cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts)) - - let stdout = '' - let stderr = '' - child.stdout.on('data', d => { stdout += d }) - child.stderr.on('data', d => { stderr += d }) - - return finished(child).catch(err => { - if (shouldRetry(stderr)) { - retry(err) - } else { - err.stderr = stderr - throw err - } - }).then(() => { - return stdout - }) - }, opts.retry) + return cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts)) }) } @@ -258,10 +213,10 @@ const REFS_HEADS = 'refs/heads/' const HEAD = 'HEAD' function refType (ref) { return ref.indexOf(REFS_TAGS) !== -1 - ? 'tag' - : ref.indexOf(REFS_HEADS) !== -1 - ? 'branch' - : ref.endsWith(HEAD) - ? 'head' - : 'other' + ? 'tag' + : ref.indexOf(REFS_HEADS) !== -1 + ? 'branch' + : ref.endsWith(HEAD) + ? 'head' + : 'other' } diff --git a/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js b/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js new file mode 100644 index 0000000000..055de2921a --- /dev/null +++ b/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js @@ -0,0 +1,24 @@ +'use strict' + +const duplex = require('mississippi').duplex +const through = require('mississippi').through +const zlib = require('zlib') + +function hasGzipHeader (c) { + return c[0] === 0x1F && c[1] === 0x8B && c[2] === 0x08 +} + +module.exports = gunzip +function gunzip () { + const stream = duplex() + const peeker = through((chunk, enc, cb) => { + const newStream = hasGzipHeader(chunk) + ? zlib.createGunzip() + : through() + stream.setReadable(newStream) + stream.setWritable(newStream) + stream.write(chunk) + }) + stream.setWritable(peeker) + return stream +} diff --git a/deps/npm/node_modules/pacote/lib/util/opt-check.js b/deps/npm/node_modules/pacote/lib/util/opt-check.js index d13a69e4dc..711f46c91a 100644 --- a/deps/npm/node_modules/pacote/lib/util/opt-check.js +++ b/deps/npm/node_modules/pacote/lib/util/opt-check.js @@ -25,7 +25,6 @@ function PacoteOptions (opts) { this.proxy = opts.proxy this.noProxy = opts.noProxy this.registry = opts.registry || 'https://registry.npmjs.org' - this.resolved = opts.resolved this.retry = opts.retry // for npm-registry-client this.scope = opts.scope this.userAgent = opts.userAgent || `${pkg.name}@${pkg.version}/node@${process.version}+${process.arch} (${process.platform})` @@ -45,8 +44,8 @@ function PacoteOptions (opts) { this.fullMetadata = opts.fullMetadata this.alwaysAuth = opts.alwaysAuth this.includeDeprecated = opts.includeDeprecated == null - ? true - : opts.includeDeprecated + ? true + : opts.includeDeprecated this.dirPacker = opts.dirPacker || null diff --git a/deps/npm/node_modules/pacote/lib/util/pack-dir.js b/deps/npm/node_modules/pacote/lib/util/pack-dir.js index 62776692e1..7625f4faf8 100644 --- a/deps/npm/node_modules/pacote/lib/util/pack-dir.js +++ b/deps/npm/node_modules/pacote/lib/util/pack-dir.js @@ -14,8 +14,8 @@ function packDir (manifest, label, dir, target, opts) { opts = optCheck(opts) const packer = opts.dirPacker - ? BB.resolve(opts.dirPacker(manifest, dir)) - : mkPacker(dir) + ? BB.resolve(opts.dirPacker(manifest, dir)) + : mkPacker(dir) if (!opts.cache) { return packer.then(packer => pipe(packer, target)) diff --git a/deps/npm/node_modules/pacote/lib/with-tarball-stream.js b/deps/npm/node_modules/pacote/lib/with-tarball-stream.js deleted file mode 100644 index 653a4a688a..0000000000 --- a/deps/npm/node_modules/pacote/lib/with-tarball-stream.js +++ /dev/null @@ -1,135 +0,0 @@ -'use strict' - -const BB = require('bluebird') - -const cacache = require('cacache') -const fetch = require('./fetch.js') -const fs = require('fs') -const npa = require('npm-package-arg') -const optCheck = require('./util/opt-check.js') -const path = require('path') -const ssri = require('ssri') -const retry = require('promise-retry') - -const statAsync = BB.promisify(fs.stat) - -const RETRIABLE_ERRORS = new Set(['ENOENT', 'EINTEGRITY', 'Z_DATA_ERROR']) - -module.exports = withTarballStream -function withTarballStream (spec, opts, streamHandler) { - opts = optCheck(opts) - spec = npa(spec, opts.where) - - // First, we check for a file: resolved shortcut - const tryFile = ( - !opts.preferOnline && - opts.integrity && - opts.resolved && - opts.resolved.startsWith('file:') - ) - ? BB.try(() => { - // NOTE - this is a special shortcut! Packages installed as files do not - // have a `resolved` field -- this specific case only occurs when you have, - // say, a git dependency or a registry dependency that you've packaged into - // a local file, and put that file: spec in the `resolved` field. - opts.log.silly('pacote', `trying ${spec} by local file: ${opts.resolved}`) - const file = path.resolve(opts.where || '.', opts.resolved.substr(5)) - return statAsync(file) - .then(() => { - const verifier = ssri.integrityStream({integrity: opts.integrity}) - const stream = fs.createReadStream(file) - .on('error', err => verifier.emit('error', err)) - .pipe(verifier) - return streamHandler(stream) - }) - .catch(err => { - if (err.code === 'EINTEGRITY') { - opts.log.warn('pacote', `EINTEGRITY while extracting ${spec} from ${file}.You will have to recreate the file.`) - opts.log.verbose('pacote', `EINTEGRITY for ${spec}: ${err.message}`) - } - throw err - }) - }) - : BB.reject(Object.assign(new Error('no file!'), {code: 'ENOENT'})) - - const tryDigest = tryFile - .catch(err => { - if ( - opts.preferOnline || - !opts.cache || - !opts.integrity || - !RETRIABLE_ERRORS.has(err.code) - ) { - throw err - } else { - opts.log.silly('tarball', `trying ${spec} by hash: ${opts.integrity}`) - const stream = cacache.get.stream.byDigest( - opts.cache, opts.integrity, opts - ) - stream.once('error', err => stream.on('newListener', (ev, l) => { - if (ev === 'error') { l(err) } - })) - return streamHandler(stream) - .catch(err => { - if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') { - opts.log.warn('tarball', `cached data for ${spec} (${opts.integrity}) seems to be corrupted. Refreshing cache.`) - return cleanUpCached(opts.cache, opts.integrity, opts) - .then(() => { throw err }) - } else { - throw err - } - }) - } - }) - - const trySpec = tryDigest - .catch(err => { - if (!RETRIABLE_ERRORS.has(err.code)) { - // If it's not one of our retriable errors, bail out and give up. - throw err - } else { - opts.log.silly( - 'tarball', - `no local data for ${spec}. Extracting by manifest.` - ) - return BB.resolve(retry((tryAgain, attemptNum) => { - const tardata = fetch.tarball(spec, opts) - if (!opts.resolved) { - tardata.on('manifest', m => { - opts.resolved = m._resolved - }) - tardata.on('integrity', i => { - opts.integrity = i - }) - } - return BB.try(() => streamHandler(tardata)) - .catch(err => { - // Retry once if we have a cache, to clear up any weird conditions. - // Don't retry network errors, though -- make-fetch-happen has already - // taken care of making sure we're all set on that front. - if (opts.cache && err.code && !err.code.match(/^E\d{3}$/)) { - if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') { - opts.log.warn('tarball', `tarball data for ${spec} (${opts.integrity}) seems to be corrupted. Trying one more time.`) - } - return cleanUpCached(opts.cache, err.sri, opts) - .then(() => tryAgain(err)) - } else { - throw err - } - }) - }, {retries: 1})) - } - }) - - return trySpec - .catch(err => { - if (err.code === 'EINTEGRITY') { - err.message = `Verification failed while extracting ${spec}:\n${err.message}` - } - throw err - }) -} - -function cleanUpCached (cachePath, integrity, opts) { - return cacache.rm.content(cachePath, integrity, opts) -} |