pacote 7.5.1 → 7.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/extract.js +36 -36
- package/lib/fetchers/file.js +7 -7
- package/lib/fetchers/git.js +10 -10
- package/lib/fetchers/registry/fetch.js +6 -6
- package/lib/fetchers/registry/manifest.js +2 -2
- package/lib/fetchers/registry/tarball.js +11 -11
- package/lib/finalize-manifest.js +6 -6
- package/lib/util/git.js +99 -55
- package/lib/util/opt-check.js +2 -2
- package/lib/util/pack-dir.js +2 -2
- package/lib/with-tarball-stream.js +85 -86
- package/package.json +6 -6
- package/tarball.js +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
<a name="7.6.1"></a>
|
|
6
|
+
## [7.6.1](https://github.com/zkat/pacote/compare/v7.6.0...v7.6.1) (2018-03-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **standard:** update to new standard rules ([bb52d02](https://github.com/zkat/pacote/commit/bb52d02))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
<a name="7.6.0"></a>
|
|
16
|
+
# [7.6.0](https://github.com/zkat/pacote/compare/v7.5.3...v7.6.0) (2018-03-08)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* **git:** added retry logic for all git operations. ([#136](https://github.com/zkat/pacote/issues/136)) ([425c58d](https://github.com/zkat/pacote/commit/425c58d))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
<a name="7.5.3"></a>
|
|
26
|
+
## [7.5.3](https://github.com/zkat/pacote/compare/v7.5.2...v7.5.3) (2018-03-02)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* **tarball:** stop dropping stream errors on the floor ([3db03c2](https://github.com/zkat/pacote/commit/3db03c2))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
<a name="7.5.2"></a>
|
|
36
|
+
## [7.5.2](https://github.com/zkat/pacote/compare/v7.5.1...v7.5.2) (2018-03-02)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
|
|
41
|
+
* **console:** remove spurious debugging console.log :< ([5b8b509](https://github.com/zkat/pacote/commit/5b8b509))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
5
45
|
<a name="7.5.1"></a>
|
|
6
46
|
## [7.5.1](https://github.com/zkat/pacote/compare/v7.5.0...v7.5.1) (2018-03-01)
|
|
7
47
|
|
package/extract.js
CHANGED
|
@@ -24,27 +24,27 @@ function extract (spec, dest, opts) {
|
|
|
24
24
|
return withTarballStream(spec, opts, stream => {
|
|
25
25
|
return tryExtract(spec, stream, dest, opts)
|
|
26
26
|
})
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
.then(() => {
|
|
28
|
+
if (!opts.resolved) {
|
|
29
|
+
const pjson = path.join(dest, 'package.json')
|
|
30
|
+
return readFileAsync(pjson, 'utf8')
|
|
31
|
+
.then(str => truncateAsync(pjson)
|
|
32
|
+
.then(() => appendFileAsync(pjson, str.replace(
|
|
33
|
+
/}\s*$/,
|
|
34
|
+
`\n,"_resolved": ${
|
|
35
|
+
JSON.stringify(opts.resolved || '')
|
|
36
|
+
}\n,"_integrity": ${
|
|
37
|
+
JSON.stringify(opts.integrity || '')
|
|
38
|
+
}\n,"_from": ${
|
|
39
|
+
JSON.stringify(spec.toString())
|
|
40
|
+
}\n}`
|
|
41
|
+
))))
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
.then(() => opts.log.silly(
|
|
45
|
+
'extract',
|
|
46
|
+
`${spec} extracted to ${dest} (${Date.now() - startTime}ms)`
|
|
47
|
+
))
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function tryExtract (spec, tarStream, dest, opts) {
|
|
@@ -52,19 +52,19 @@ function tryExtract (spec, tarStream, dest, opts) {
|
|
|
52
52
|
tarStream.on('error', reject)
|
|
53
53
|
setImmediate(resolve)
|
|
54
54
|
})
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
.then(() => rimraf(dest))
|
|
56
|
+
.then(() => mkdirp(dest))
|
|
57
|
+
.then(() => new BB((resolve, reject) => {
|
|
58
|
+
const xtractor = extractStream(spec, dest, opts)
|
|
59
|
+
tarStream.on('error', reject)
|
|
60
|
+
xtractor.on('error', reject)
|
|
61
|
+
xtractor.on('close', resolve)
|
|
62
|
+
tarStream.pipe(xtractor)
|
|
63
|
+
}))
|
|
64
|
+
.catch(err => {
|
|
65
|
+
if (err.code === 'EINTEGRITY') {
|
|
66
|
+
err.message = `Verification failed while extracting ${spec}:\n${err.message}`
|
|
67
|
+
}
|
|
68
|
+
throw err
|
|
69
|
+
})
|
|
70
70
|
}
|
package/lib/fetchers/file.js
CHANGED
|
@@ -52,13 +52,13 @@ Fetcher.impl(fetchFile, {
|
|
|
52
52
|
} else {
|
|
53
53
|
let integrity
|
|
54
54
|
const cacheWriter = !opts.cache
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
? BB.resolve(null)
|
|
56
|
+
: (pipe(
|
|
57
|
+
fs.createReadStream(src),
|
|
58
|
+
cacache.put.stream(opts.cache, `pacote:tarball:${src}`, {
|
|
59
|
+
integrity: opts.integrity
|
|
60
|
+
}).on('integrity', d => { integrity = d })
|
|
61
|
+
))
|
|
62
62
|
return cacheWriter.then(() => {
|
|
63
63
|
if (integrity) { stream.emit('integrity', integrity) }
|
|
64
64
|
return pipe(fs.createReadStream(src), stream)
|
package/lib/fetchers/git.js
CHANGED
|
@@ -135,16 +135,16 @@ function resolve (url, spec, name, opts) {
|
|
|
135
135
|
const isSemver = !!spec.gitRange
|
|
136
136
|
return git.revs(url, opts).then(remoteRefs => {
|
|
137
137
|
return isSemver
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
? pickManifest({
|
|
139
|
+
versions: remoteRefs.versions,
|
|
140
|
+
'dist-tags': remoteRefs['dist-tags'],
|
|
141
|
+
name: name
|
|
142
|
+
}, spec.gitRange, opts)
|
|
143
|
+
: remoteRefs
|
|
144
|
+
? BB.resolve(
|
|
145
|
+
remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]]
|
|
146
|
+
)
|
|
147
|
+
: null
|
|
148
148
|
})
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -68,12 +68,12 @@ function logRequest (uri, res, startTime, opts) {
|
|
|
68
68
|
|
|
69
69
|
function getCacheMode (opts) {
|
|
70
70
|
return opts.offline
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
? 'only-if-cached'
|
|
72
|
+
: opts.preferOffline
|
|
73
|
+
? 'force-cache'
|
|
74
|
+
: opts.preferOnline
|
|
75
|
+
? 'no-cache'
|
|
76
|
+
: 'default'
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function getHeaders (uri, registry, opts) {
|
|
@@ -60,20 +60,20 @@ function fromManifest (manifest, spec, opts) {
|
|
|
60
60
|
integrity: manifest._integrity,
|
|
61
61
|
algorithms: [
|
|
62
62
|
manifest._integrity
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
? ssri.parse(manifest._integrity).pickAlgorithm()
|
|
64
|
+
: 'sha1'
|
|
65
65
|
],
|
|
66
66
|
spec
|
|
67
67
|
}, opts))
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
.then(res => {
|
|
69
|
+
const hash = res.headers.get('x-local-cache-hash')
|
|
70
|
+
if (hash) {
|
|
71
|
+
stream.emit('integrity', decodeURIComponent(hash))
|
|
72
|
+
}
|
|
73
|
+
res.body.on('error', err => stream.emit('error', err))
|
|
74
|
+
res.body.pipe(stream)
|
|
75
|
+
})
|
|
76
|
+
.catch(err => stream.emit('error', err))
|
|
77
77
|
return stream
|
|
78
78
|
}
|
|
79
79
|
|
package/lib/finalize-manifest.js
CHANGED
|
@@ -38,8 +38,8 @@ function finalizeManifest (pkg, spec, opts) {
|
|
|
38
38
|
opts = optCheck(opts)
|
|
39
39
|
|
|
40
40
|
const cachedManifest = (opts.cache && key && !opts.preferOnline && !opts.fullMetadata)
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
? cacache.get.info(opts.cache, key, opts)
|
|
42
|
+
: BB.resolve(null)
|
|
43
43
|
|
|
44
44
|
return cachedManifest.then(cached => {
|
|
45
45
|
if (cached && cached.metadata.manifest) {
|
|
@@ -47,8 +47,8 @@ function finalizeManifest (pkg, spec, opts) {
|
|
|
47
47
|
} else {
|
|
48
48
|
return tarballedProps(pkg, spec, opts).then(props => {
|
|
49
49
|
return pkg && pkg.name
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
? new Manifest(pkg, props, opts.fullMetadata)
|
|
51
|
+
: new Manifest(props, null, opts.fullMetadata)
|
|
52
52
|
}).then(manifest => {
|
|
53
53
|
const cacheKey = key || finalKey(manifest, spec)
|
|
54
54
|
if (!opts.cache || !cacheKey) {
|
|
@@ -169,8 +169,8 @@ function tarballedProps (pkg, spec, opts) {
|
|
|
169
169
|
// to add to bin
|
|
170
170
|
if (paths && paths.length) {
|
|
171
171
|
const dirBin = mani
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
? (mani && mani.directories && mani.directories.bin)
|
|
173
|
+
: (pkg && pkg.directories && pkg.directories.bin)
|
|
174
174
|
if (dirBin) {
|
|
175
175
|
extraProps.bin = {}
|
|
176
176
|
paths.forEach(filePath => {
|
package/lib/util/git.js
CHANGED
|
@@ -12,6 +12,7 @@ const optCheck = require('./opt-check')
|
|
|
12
12
|
const osenv = require('osenv')
|
|
13
13
|
const path = require('path')
|
|
14
14
|
const pinflight = require('promise-inflight')
|
|
15
|
+
const promiseRetry = require('promise-retry')
|
|
15
16
|
const uniqueFilename = require('unique-filename')
|
|
16
17
|
const which = BB.promisify(require('which'))
|
|
17
18
|
const semver = require('semver')
|
|
@@ -26,6 +27,23 @@ const GOOD_ENV_VARS = new Set([
|
|
|
26
27
|
'GIT_SSL_NO_VERIFY'
|
|
27
28
|
])
|
|
28
29
|
|
|
30
|
+
const GIT_TRANSIENT_ERRORS = [
|
|
31
|
+
'remote error: Internal Server Error',
|
|
32
|
+
'The remote end hung up unexpectedly',
|
|
33
|
+
'Connection timed out',
|
|
34
|
+
'Operation timed out',
|
|
35
|
+
'Failed to connect to .* Timed out',
|
|
36
|
+
'Connection reset by peer',
|
|
37
|
+
'SSL_ERROR_SYSCALL',
|
|
38
|
+
'The requested URL returned error: 503'
|
|
39
|
+
].join('|')
|
|
40
|
+
|
|
41
|
+
const GIT_TRANSIENT_ERROR_RE = new RegExp(GIT_TRANSIENT_ERRORS)
|
|
42
|
+
|
|
43
|
+
function shouldRetry (error) {
|
|
44
|
+
return GIT_TRANSIENT_ERROR_RE.test(error)
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
const GIT_ = 'GIT_'
|
|
30
48
|
let GITENV
|
|
31
49
|
function gitEnv () {
|
|
@@ -114,57 +132,51 @@ function revs (repo, opts) {
|
|
|
114
132
|
return pinflight(`ls-remote:${repo}`, () => {
|
|
115
133
|
return spawnGit(['ls-remote', '-h', '-t', repo], {
|
|
116
134
|
env: gitEnv()
|
|
117
|
-
}, opts).then(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const split = line.split(/\s+/, 2)
|
|
128
|
-
if (split.length < 2) { return revs }
|
|
129
|
-
const sha = split[0].trim()
|
|
130
|
-
const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1]
|
|
131
|
-
if (!ref) { return revs } // ???
|
|
132
|
-
if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap
|
|
133
|
-
const type = refType(line)
|
|
134
|
-
const doc = {sha, ref, type}
|
|
135
|
-
|
|
136
|
-
revs.refs[ref] = doc
|
|
137
|
-
// We can check out shallow clones on specific SHAs if we have a ref
|
|
138
|
-
if (revs.shas[sha]) {
|
|
139
|
-
revs.shas[sha].push(ref)
|
|
140
|
-
} else {
|
|
141
|
-
revs.shas[sha] = [ref]
|
|
142
|
-
}
|
|
135
|
+
}, opts).then((stdout) => {
|
|
136
|
+
return stdout.split('\n').reduce((revs, line) => {
|
|
137
|
+
const split = line.split(/\s+/, 2)
|
|
138
|
+
if (split.length < 2) { return revs }
|
|
139
|
+
const sha = split[0].trim()
|
|
140
|
+
const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1]
|
|
141
|
+
if (!ref) { return revs } // ???
|
|
142
|
+
if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap
|
|
143
|
+
const type = refType(line)
|
|
144
|
+
const doc = {sha, ref, type}
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
revs.refs[ref] = doc
|
|
147
|
+
// We can check out shallow clones on specific SHAs if we have a ref
|
|
148
|
+
if (revs.shas[sha]) {
|
|
149
|
+
revs.shas[sha].push(ref)
|
|
150
|
+
} else {
|
|
151
|
+
revs.shas[sha] = [ref]
|
|
152
|
+
}
|
|
150
153
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Object.keys(revs.versions).forEach(v => {
|
|
157
|
-
if (v.sha === HEAD.sha) {
|
|
158
|
-
revs['dist-tags'].HEAD = v
|
|
159
|
-
if (!revs.refs.latest) {
|
|
160
|
-
revs['dist-tags'].latest = revs.refs.HEAD
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
})
|
|
154
|
+
if (type === 'tag') {
|
|
155
|
+
const match = ref.match(/v?(\d+\.\d+\.\d+(?:[-+].+)?)$/)
|
|
156
|
+
if (match && semver.valid(match[1], true)) {
|
|
157
|
+
revs.versions[semver.clean(match[1], true)] = doc
|
|
158
|
+
}
|
|
164
159
|
}
|
|
165
|
-
|
|
160
|
+
|
|
166
161
|
return revs
|
|
167
|
-
})
|
|
162
|
+
}, {versions: {}, 'dist-tags': {}, refs: {}, shas: {}})
|
|
163
|
+
}, err => {
|
|
164
|
+
err.message = `Error while executing:\n${GITPATH} ls-remote -h -t ${repo}\n\n${err.stderr}\n${err.message}`
|
|
165
|
+
throw err
|
|
166
|
+
}).then(revs => {
|
|
167
|
+
if (revs.refs.HEAD) {
|
|
168
|
+
const HEAD = revs.refs.HEAD
|
|
169
|
+
Object.keys(revs.versions).forEach(v => {
|
|
170
|
+
if (v.sha === HEAD.sha) {
|
|
171
|
+
revs['dist-tags'].HEAD = v
|
|
172
|
+
if (!revs.refs.latest) {
|
|
173
|
+
revs['dist-tags'].latest = revs.refs.HEAD
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
REVS.set(repo, revs)
|
|
179
|
+
return revs
|
|
168
180
|
})
|
|
169
181
|
})
|
|
170
182
|
}
|
|
@@ -173,7 +185,18 @@ module.exports._exec = execGit
|
|
|
173
185
|
function execGit (gitArgs, gitOpts, opts) {
|
|
174
186
|
opts = optCheck(opts)
|
|
175
187
|
return checkGit().then(gitPath => {
|
|
176
|
-
return
|
|
188
|
+
return promiseRetry((retry, number) => {
|
|
189
|
+
if (number !== 1) {
|
|
190
|
+
opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number)
|
|
191
|
+
}
|
|
192
|
+
return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts)).catch((err) => {
|
|
193
|
+
if (shouldRetry(err)) {
|
|
194
|
+
retry(err)
|
|
195
|
+
} else {
|
|
196
|
+
throw err
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
}, opts.retry)
|
|
177
200
|
})
|
|
178
201
|
}
|
|
179
202
|
|
|
@@ -181,7 +204,28 @@ module.exports._spawn = spawnGit
|
|
|
181
204
|
function spawnGit (gitArgs, gitOpts, opts) {
|
|
182
205
|
opts = optCheck(opts)
|
|
183
206
|
return checkGit().then(gitPath => {
|
|
184
|
-
return
|
|
207
|
+
return promiseRetry((retry, number) => {
|
|
208
|
+
if (number !== 1) {
|
|
209
|
+
opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number)
|
|
210
|
+
}
|
|
211
|
+
const child = cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts))
|
|
212
|
+
|
|
213
|
+
let stdout = ''
|
|
214
|
+
let stderr = ''
|
|
215
|
+
child.stdout.on('data', d => { stdout += d })
|
|
216
|
+
child.stderr.on('data', d => { stderr += d })
|
|
217
|
+
|
|
218
|
+
return finished(child).catch(err => {
|
|
219
|
+
if (shouldRetry(stderr)) {
|
|
220
|
+
retry(err)
|
|
221
|
+
} else {
|
|
222
|
+
err.stderr = stderr
|
|
223
|
+
throw err
|
|
224
|
+
}
|
|
225
|
+
}).then(() => {
|
|
226
|
+
return stdout
|
|
227
|
+
})
|
|
228
|
+
}, opts.retry)
|
|
185
229
|
})
|
|
186
230
|
}
|
|
187
231
|
|
|
@@ -214,10 +258,10 @@ const REFS_HEADS = 'refs/heads/'
|
|
|
214
258
|
const HEAD = 'HEAD'
|
|
215
259
|
function refType (ref) {
|
|
216
260
|
return ref.indexOf(REFS_TAGS) !== -1
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
261
|
+
? 'tag'
|
|
262
|
+
: ref.indexOf(REFS_HEADS) !== -1
|
|
263
|
+
? 'branch'
|
|
264
|
+
: ref.endsWith(HEAD)
|
|
265
|
+
? 'head'
|
|
266
|
+
: 'other'
|
|
223
267
|
}
|
package/lib/util/opt-check.js
CHANGED
|
@@ -45,8 +45,8 @@ function PacoteOptions (opts) {
|
|
|
45
45
|
this.fullMetadata = opts.fullMetadata
|
|
46
46
|
this.alwaysAuth = opts.alwaysAuth
|
|
47
47
|
this.includeDeprecated = opts.includeDeprecated == null
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
? true
|
|
49
|
+
: opts.includeDeprecated
|
|
50
50
|
|
|
51
51
|
this.dirPacker = opts.dirPacker || null
|
|
52
52
|
|
package/lib/util/pack-dir.js
CHANGED
|
@@ -14,8 +14,8 @@ function packDir (manifest, label, dir, target, opts) {
|
|
|
14
14
|
opts = optCheck(opts)
|
|
15
15
|
|
|
16
16
|
const packer = opts.dirPacker
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
? BB.resolve(opts.dirPacker(manifest, dir))
|
|
18
|
+
: mkPacker(dir)
|
|
19
19
|
|
|
20
20
|
if (!opts.cache) {
|
|
21
21
|
return packer.then(packer => pipe(packer, target))
|
|
@@ -27,108 +27,107 @@ function withTarballStream (spec, opts, streamHandler) {
|
|
|
27
27
|
opts.resolved &&
|
|
28
28
|
opts.resolved.startsWith('file:')
|
|
29
29
|
)
|
|
30
|
-
|
|
30
|
+
? BB.try(() => {
|
|
31
31
|
// NOTE - this is a special shortcut! Packages installed as files do not
|
|
32
32
|
// have a `resolved` field -- this specific case only occurs when you have,
|
|
33
33
|
// say, a git dependency or a registry dependency that you've packaged into
|
|
34
34
|
// a local file, and put that file: spec in the `resolved` field.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
35
|
+
opts.log.silly('pacote', `trying ${spec} by local file: ${opts.resolved}`)
|
|
36
|
+
const file = path.resolve(opts.where || '.', opts.resolved.substr(5))
|
|
37
|
+
return statAsync(file)
|
|
38
|
+
.then(() => {
|
|
39
|
+
const verifier = ssri.integrityStream({integrity: opts.integrity})
|
|
40
|
+
const stream = fs.createReadStream(file)
|
|
41
|
+
.on('error', err => verifier.emit('error', err))
|
|
42
|
+
.pipe(verifier)
|
|
43
|
+
return streamHandler(stream)
|
|
44
|
+
})
|
|
45
|
+
.catch(err => {
|
|
46
|
+
if (err.code === 'EINTEGRITY') {
|
|
47
|
+
opts.log.warn('pacote', `EINTEGRITY while extracting ${spec} from ${file}.You will have to recreate the file.`)
|
|
48
|
+
opts.log.verbose('pacote', `EINTEGRITY for ${spec}: ${err.message}`)
|
|
49
|
+
}
|
|
50
|
+
throw err
|
|
51
|
+
})
|
|
51
52
|
})
|
|
52
|
-
|
|
53
|
-
: BB.reject(Object.assign(new Error('no file!'), {code: 'ENOENT'}))
|
|
53
|
+
: BB.reject(Object.assign(new Error('no file!'), {code: 'ENOENT'}))
|
|
54
54
|
|
|
55
55
|
const tryDigest = tryFile
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
.catch(err => {
|
|
57
|
+
if (
|
|
58
|
+
opts.preferOnline ||
|
|
59
59
|
!opts.cache ||
|
|
60
60
|
!opts.integrity ||
|
|
61
61
|
!RETRIABLE_ERRORS.has(err.code)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
62
|
+
) {
|
|
63
|
+
throw err
|
|
64
|
+
} else {
|
|
65
|
+
opts.log.silly('tarball', `trying ${spec} by hash: ${opts.integrity}`)
|
|
66
|
+
const stream = cacache.get.stream.byDigest(
|
|
67
|
+
opts.cache, opts.integrity, opts
|
|
68
|
+
)
|
|
69
|
+
stream.once('error', err => stream.on('newListener', (ev, l) => {
|
|
70
|
+
if (ev === 'error') { l(err) }
|
|
71
|
+
}))
|
|
72
|
+
return streamHandler(stream)
|
|
73
|
+
.catch(err => {
|
|
74
|
+
if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') {
|
|
75
|
+
opts.log.warn('tarball', `cached data for ${spec} (${opts.integrity}) seems to be corrupted. Refreshing cache.`)
|
|
76
|
+
return cleanUpCached(opts.cache, opts.integrity, opts)
|
|
77
|
+
.then(() => { throw err })
|
|
78
|
+
} else {
|
|
79
|
+
throw err
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
84
|
|
|
85
85
|
const trySpec = tryDigest
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
.catch(err => {
|
|
87
|
+
if (!RETRIABLE_ERRORS.has(err.code)) {
|
|
88
88
|
// If it's not one of our retriable errors, bail out and give up.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
tardata.on('error', err => console.error('ERROR:', err))
|
|
106
|
-
return BB.try(() => streamHandler(tardata))
|
|
107
|
-
.catch(err => {
|
|
108
|
-
// Retry once if we have a cache, to clear up any weird conditions.
|
|
109
|
-
// Don't retry network errors, though -- make-fetch-happen has already
|
|
110
|
-
// taken care of making sure we're all set on that front.
|
|
111
|
-
if (opts.cache && err.code && !err.code.match(/^E\d{3}$/)) {
|
|
112
|
-
if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') {
|
|
113
|
-
opts.log.warn('tarball', `tarball data for ${spec} (${opts.integrity}) seems to be corrupted. Trying one more time.`)
|
|
114
|
-
}
|
|
115
|
-
return cleanUpCached(opts.cache, err.sri, opts)
|
|
116
|
-
.then(() => tryAgain(err))
|
|
117
|
-
} else {
|
|
118
|
-
throw err
|
|
89
|
+
throw err
|
|
90
|
+
} else {
|
|
91
|
+
opts.log.silly(
|
|
92
|
+
'tarball',
|
|
93
|
+
`no local data for ${spec}. Extracting by manifest.`
|
|
94
|
+
)
|
|
95
|
+
return BB.resolve(retry((tryAgain, attemptNum) => {
|
|
96
|
+
const tardata = fetch.tarball(spec, opts)
|
|
97
|
+
if (!opts.resolved) {
|
|
98
|
+
tardata.on('manifest', m => {
|
|
99
|
+
opts.resolved = m._resolved
|
|
100
|
+
})
|
|
101
|
+
tardata.on('integrity', i => {
|
|
102
|
+
opts.integrity = i
|
|
103
|
+
})
|
|
119
104
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
return BB.try(() => streamHandler(tardata))
|
|
106
|
+
.catch(err => {
|
|
107
|
+
// Retry once if we have a cache, to clear up any weird conditions.
|
|
108
|
+
// Don't retry network errors, though -- make-fetch-happen has already
|
|
109
|
+
// taken care of making sure we're all set on that front.
|
|
110
|
+
if (opts.cache && err.code && !err.code.match(/^E\d{3}$/)) {
|
|
111
|
+
if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') {
|
|
112
|
+
opts.log.warn('tarball', `tarball data for ${spec} (${opts.integrity}) seems to be corrupted. Trying one more time.`)
|
|
113
|
+
}
|
|
114
|
+
return cleanUpCached(opts.cache, err.sri, opts)
|
|
115
|
+
.then(() => tryAgain(err))
|
|
116
|
+
} else {
|
|
117
|
+
throw err
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
}, {retries: 1}))
|
|
121
|
+
}
|
|
122
|
+
})
|
|
124
123
|
|
|
125
124
|
return trySpec
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
.catch(err => {
|
|
126
|
+
if (err.code === 'EINTEGRITY') {
|
|
127
|
+
err.message = `Verification failed while extracting ${spec}:\n${err.message}`
|
|
128
|
+
}
|
|
129
|
+
throw err
|
|
130
|
+
})
|
|
132
131
|
}
|
|
133
132
|
|
|
134
133
|
function cleanUpCached (cachePath, integrity, opts) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pacote",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.1",
|
|
4
4
|
"description": "JavaScript package downloader",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"lru-cache": "^4.1.1",
|
|
49
49
|
"make-fetch-happen": "^2.6.0",
|
|
50
50
|
"minimatch": "^3.0.4",
|
|
51
|
-
"mississippi": "^
|
|
51
|
+
"mississippi": "^3.0.0",
|
|
52
52
|
"mkdirp": "^0.5.1",
|
|
53
53
|
"normalize-package-data": "^2.4.0",
|
|
54
54
|
"npm-package-arg": "^6.0.0",
|
|
@@ -62,19 +62,19 @@
|
|
|
62
62
|
"safe-buffer": "^5.1.1",
|
|
63
63
|
"semver": "^5.5.0",
|
|
64
64
|
"ssri": "^5.2.4",
|
|
65
|
-
"tar": "^4.
|
|
65
|
+
"tar": "^4.4.0",
|
|
66
66
|
"unique-filename": "^1.1.0",
|
|
67
67
|
"which": "^1.3.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"nock": "^9.
|
|
70
|
+
"nock": "^9.2.3",
|
|
71
71
|
"npmlog": "^4.1.2",
|
|
72
72
|
"nyc": "^11.4.1",
|
|
73
73
|
"require-inject": "^1.4.2",
|
|
74
|
-
"standard": "^
|
|
74
|
+
"standard": "^11.0.0",
|
|
75
75
|
"standard-version": "^4.3.0",
|
|
76
76
|
"tacks": "^1.2.6",
|
|
77
|
-
"tap": "^11.1.
|
|
77
|
+
"tap": "^11.1.2",
|
|
78
78
|
"tar-stream": "^1.5.5",
|
|
79
79
|
"weallbehave": "^1.2.0",
|
|
80
80
|
"weallcontribute": "^1.0.7"
|
package/tarball.js
CHANGED
|
@@ -45,6 +45,7 @@ function tarballStream (spec, opts) {
|
|
|
45
45
|
})
|
|
46
46
|
}
|
|
47
47
|
})
|
|
48
|
+
.catch(err => output.emit('error', err))
|
|
48
49
|
return output
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -53,14 +54,14 @@ function tarballToFile (spec, dest, opts) {
|
|
|
53
54
|
opts = optCheck(opts)
|
|
54
55
|
spec = npa(spec, opts.where)
|
|
55
56
|
return mkdirp(path.dirname(dest))
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
.then(() => withTarballStream(spec, opts, stream => {
|
|
58
|
+
return rimraf(dest)
|
|
59
|
+
.then(() => new BB((resolve, reject) => {
|
|
60
|
+
const writer = fs.createWriteStream(dest)
|
|
61
|
+
stream.on('error', reject)
|
|
62
|
+
writer.on('error', reject)
|
|
63
|
+
writer.on('close', resolve)
|
|
64
|
+
stream.pipe(writer)
|
|
65
|
+
}))
|
|
64
66
|
}))
|
|
65
|
-
}))
|
|
66
67
|
}
|