cacache 11.3.2 → 12.0.2
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 +216 -143
- package/README.es.md +1 -1
- package/README.md +35 -18
- package/lib/content/path.js +1 -1
- package/lib/content/read.js +6 -6
- package/lib/content/write.js +7 -7
- package/lib/entry-index.js +9 -11
- package/lib/util/fix-owner.js +69 -37
- package/lib/util/tmp.js +4 -7
- package/lib/verify.js +12 -12
- package/locales/en.json +3 -2
- package/package.json +13 -12
- package/put.js +3 -4
package/README.es.md
CHANGED
|
@@ -287,7 +287,7 @@ entrada si existe.
|
|
|
287
287
|
|
|
288
288
|
* `key` - Clave de la entrada. Igual al argumento `clave`.
|
|
289
289
|
* `integrity` - [hacheo de Subresource Integrity](#integrity) del contenido al que se refiere esta entrada.
|
|
290
|
-
* `path` - Dirección del fichero de datos almacenados,
|
|
290
|
+
* `path` - Dirección del fichero de datos almacenados, unida al argumento `cache`.
|
|
291
291
|
* `time` - Hora de creación de la entrada
|
|
292
292
|
* `metadata` - Metadatos asignados a esta entrada por el usuario
|
|
293
293
|
|
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
# cacache [](https://npm.im/cacache) [](https://npm.im/cacache) [](https://npm.im/cacache) [](https://npm.im/cacache) [](https://travis-ci.org/npm/cacache) [](https://ci.appveyor.com/project/npm/cacache) [](https://coveralls.io/github/npm/cacache?branch=latest)
|
|
2
2
|
|
|
3
|
-
[`cacache`](https://github.com/
|
|
3
|
+
[`cacache`](https://github.com/npm/cacache) is a Node.js library for managing
|
|
4
4
|
local key and content address caches. It's really fast, really good at
|
|
5
5
|
concurrency, and it will never give you corrupted data, even if cache files
|
|
6
6
|
get corrupted or manipulated.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
On systems that support user and group settings on files, cacache will
|
|
9
|
+
match the `uid` and `gid` values to the folder where the cache lives, even
|
|
10
|
+
when running as `root`.
|
|
11
|
+
|
|
12
|
+
It was written to be used as [npm](https://npm.im)'s local cache, but can
|
|
13
|
+
just as easily be used on its own.
|
|
10
14
|
|
|
11
15
|
_Translations: [español](README.es.md)_
|
|
12
16
|
|
|
@@ -290,7 +294,7 @@ one exists.
|
|
|
290
294
|
|
|
291
295
|
* `key` - Key the entry was looked up under. Matches the `key` argument.
|
|
292
296
|
* `integrity` - [Subresource Integrity hash](#integrity) for the content this entry refers to.
|
|
293
|
-
* `path` - Filesystem path
|
|
297
|
+
* `path` - Filesystem path where content is stored, joined with `cache` argument.
|
|
294
298
|
* `time` - Timestamp the entry was first added on.
|
|
295
299
|
* `metadata` - User-assigned metadata associated with the entry/content.
|
|
296
300
|
|
|
@@ -414,13 +418,6 @@ may also use any anagram of `'modnar'` to use this feature.
|
|
|
414
418
|
Currently only supports one algorithm at a time (i.e., an array length of
|
|
415
419
|
exactly `1`). Has no effect if `opts.integrity` is present.
|
|
416
420
|
|
|
417
|
-
##### `opts.uid`/`opts.gid`
|
|
418
|
-
|
|
419
|
-
If provided, cacache will do its best to make sure any new files added to the
|
|
420
|
-
cache use this particular `uid`/`gid` combination. This can be used,
|
|
421
|
-
for example, to drop permissions when someone uses `sudo`, but cacache makes
|
|
422
|
-
no assumptions about your needs here.
|
|
423
|
-
|
|
424
421
|
##### `opts.memoize`
|
|
425
422
|
|
|
426
423
|
Default: null
|
|
@@ -498,10 +495,11 @@ Completely resets the in-memory entry cache.
|
|
|
498
495
|
Returns a unique temporary directory inside the cache's `tmp` dir. This
|
|
499
496
|
directory will use the same safe user assignment that all the other stuff use.
|
|
500
497
|
|
|
501
|
-
Once the directory is made, it's the user's responsibility that all files
|
|
502
|
-
are
|
|
503
|
-
|
|
504
|
-
[`tmp.fix()`](#tmp-fix), which will fix all tmp directory
|
|
498
|
+
Once the directory is made, it's the user's responsibility that all files
|
|
499
|
+
within are given the appropriate `gid`/`uid` ownership settings to match
|
|
500
|
+
the rest of the cache. If not, you can ask cacache to do it for you by
|
|
501
|
+
calling [`tmp.fix()`](#tmp-fix), which will fix all tmp directory
|
|
502
|
+
permissions.
|
|
505
503
|
|
|
506
504
|
If you want automatic cleanup of this directory, use
|
|
507
505
|
[`tmp.withTmp()`](#with-tpm)
|
|
@@ -514,6 +512,27 @@ cacache.tmp.mkdir(cache).then(dir => {
|
|
|
514
512
|
})
|
|
515
513
|
```
|
|
516
514
|
|
|
515
|
+
#### <a name="tmp-fix"></a> `> tmp.fix(cache) -> Promise`
|
|
516
|
+
|
|
517
|
+
Sets the `uid` and `gid` properties on all files and folders within the tmp
|
|
518
|
+
folder to match the rest of the cache.
|
|
519
|
+
|
|
520
|
+
Use this after manually writing files into [`tmp.mkdir`](#tmp-mkdir) or
|
|
521
|
+
[`tmp.withTmp`](#with-tmp).
|
|
522
|
+
|
|
523
|
+
##### Example
|
|
524
|
+
|
|
525
|
+
```javascript
|
|
526
|
+
cacache.tmp.mkdir(cache).then(dir => {
|
|
527
|
+
writeFile(path.join(dir, 'file'), someData).then(() => {
|
|
528
|
+
// make sure we didn't just put a root-owned file in the cache
|
|
529
|
+
cacache.tmp.fix().then(() => {
|
|
530
|
+
// all uids and gids match now
|
|
531
|
+
})
|
|
532
|
+
})
|
|
533
|
+
})
|
|
534
|
+
```
|
|
535
|
+
|
|
517
536
|
#### <a name="with-tmp"></a> `> tmp.withTmp(cache, opts, cb) -> Promise`
|
|
518
537
|
|
|
519
538
|
Creates a temporary directory with [`tmp.mkdir()`](#tmp-mkdir) and calls `cb`
|
|
@@ -591,8 +610,6 @@ of entries removed, etc.
|
|
|
591
610
|
|
|
592
611
|
##### Options
|
|
593
612
|
|
|
594
|
-
* `opts.uid` - uid to assign to cache and its contents
|
|
595
|
-
* `opts.gid` - gid to assign to cache and its contents
|
|
596
613
|
* `opts.filter` - receives a formatted entry. Return false to remove it.
|
|
597
614
|
Note: might be called more than once on the same entry.
|
|
598
615
|
|
package/lib/content/path.js
CHANGED
|
@@ -12,7 +12,7 @@ const ssri = require('ssri')
|
|
|
12
12
|
//
|
|
13
13
|
module.exports = contentPath
|
|
14
14
|
function contentPath (cache, integrity) {
|
|
15
|
-
const sri = ssri.parse(integrity, {single: true})
|
|
15
|
+
const sri = ssri.parse(integrity, { single: true })
|
|
16
16
|
// contentPath is the *strongest* algo given
|
|
17
17
|
return path.join.apply(path, [
|
|
18
18
|
contentDir(cache),
|
package/lib/content/read.js
CHANGED
|
@@ -54,8 +54,8 @@ function readStream (cache, integrity, opts) {
|
|
|
54
54
|
opts = ReadOpts(opts)
|
|
55
55
|
const stream = new PassThrough()
|
|
56
56
|
withContentSri(cache, integrity, (cpath, sri) => {
|
|
57
|
-
return lstatAsync(cpath).then(stat => ({cpath, sri, stat}))
|
|
58
|
-
}).then(({cpath, sri, stat}) => {
|
|
57
|
+
return lstatAsync(cpath).then(stat => ({ cpath, sri, stat }))
|
|
58
|
+
}).then(({ cpath, sri, stat }) => {
|
|
59
59
|
return pipe(
|
|
60
60
|
fs.createReadStream(cpath),
|
|
61
61
|
ssri.integrityStream({
|
|
@@ -95,7 +95,7 @@ module.exports.hasContent = hasContent
|
|
|
95
95
|
function hasContent (cache, integrity) {
|
|
96
96
|
if (!integrity) { return BB.resolve(false) }
|
|
97
97
|
return withContentSri(cache, integrity, (cpath, sri) => {
|
|
98
|
-
return lstatAsync(cpath).then(stat => ({size: stat.size, sri, stat}))
|
|
98
|
+
return lstatAsync(cpath).then(stat => ({ size: stat.size, sri, stat }))
|
|
99
99
|
}).catch(err => {
|
|
100
100
|
if (err.code === 'ENOENT') { return false }
|
|
101
101
|
if (err.code === 'EPERM') {
|
|
@@ -114,7 +114,7 @@ function hasContentSync (cache, integrity) {
|
|
|
114
114
|
return withContentSriSync(cache, integrity, (cpath, sri) => {
|
|
115
115
|
try {
|
|
116
116
|
const stat = fs.lstatSync(cpath)
|
|
117
|
-
return {size: stat.size, sri, stat}
|
|
117
|
+
return { size: stat.size, sri, stat }
|
|
118
118
|
} catch (err) {
|
|
119
119
|
if (err.code === 'ENOENT') { return false }
|
|
120
120
|
if (err.code === 'EPERM') {
|
|
@@ -141,12 +141,12 @@ function withContentSri (cache, integrity, fn) {
|
|
|
141
141
|
} else {
|
|
142
142
|
return BB.any(sri[sri.pickAlgorithm()].map(meta => {
|
|
143
143
|
return withContentSri(cache, meta, fn)
|
|
144
|
-
}, {concurrency: 1}))
|
|
144
|
+
}, { concurrency: 1 }))
|
|
145
145
|
.catch(err => {
|
|
146
146
|
if ([].some.call(err, e => e.code === 'ENOENT')) {
|
|
147
147
|
throw Object.assign(
|
|
148
148
|
new Error('No matching content found for ' + sri.toString()),
|
|
149
|
-
{code: 'ENOENT'}
|
|
149
|
+
{ code: 'ENOENT' }
|
|
150
150
|
)
|
|
151
151
|
} else {
|
|
152
152
|
throw err[0]
|
package/lib/content/write.js
CHANGED
|
@@ -36,11 +36,11 @@ function write (cache, data, opts) {
|
|
|
36
36
|
}
|
|
37
37
|
return BB.using(makeTmp(cache, opts), tmp => (
|
|
38
38
|
writeFileAsync(
|
|
39
|
-
tmp.target, data, {flag: 'wx'}
|
|
39
|
+
tmp.target, data, { flag: 'wx' }
|
|
40
40
|
).then(() => (
|
|
41
41
|
moveToDestination(tmp, cache, sri, opts)
|
|
42
42
|
))
|
|
43
|
-
)).then(() => ({integrity: sri, size: data.length}))
|
|
43
|
+
)).then(() => ({ integrity: sri, size: data.length }))
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
module.exports.stream = writeStream
|
|
@@ -111,8 +111,8 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts, errCheck) {
|
|
|
111
111
|
})
|
|
112
112
|
errCheck()
|
|
113
113
|
return pipe(inputStream, hashStream, outStream).then(() => {
|
|
114
|
-
return {integrity, size}
|
|
115
|
-
}
|
|
114
|
+
return { integrity, size }
|
|
115
|
+
}).catch(err => {
|
|
116
116
|
return rimraf(tmpTarget).then(() => { throw err })
|
|
117
117
|
})
|
|
118
118
|
})
|
|
@@ -121,7 +121,7 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts, errCheck) {
|
|
|
121
121
|
function makeTmp (cache, opts) {
|
|
122
122
|
const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
|
|
123
123
|
return fixOwner.mkdirfix(
|
|
124
|
-
path.dirname(tmpTarget)
|
|
124
|
+
cache, path.dirname(tmpTarget)
|
|
125
125
|
).then(() => ({
|
|
126
126
|
target: tmpTarget,
|
|
127
127
|
moved: false
|
|
@@ -134,14 +134,14 @@ function moveToDestination (tmp, cache, sri, opts, errCheck) {
|
|
|
134
134
|
const destDir = path.dirname(destination)
|
|
135
135
|
|
|
136
136
|
return fixOwner.mkdirfix(
|
|
137
|
-
|
|
137
|
+
cache, destDir
|
|
138
138
|
).then(() => {
|
|
139
139
|
errCheck && errCheck()
|
|
140
140
|
return moveFile(tmp.target, destination)
|
|
141
141
|
}).then(() => {
|
|
142
142
|
errCheck && errCheck()
|
|
143
143
|
tmp.moved = true
|
|
144
|
-
return fixOwner.chownr(
|
|
144
|
+
return fixOwner.chownr(cache, destination)
|
|
145
145
|
})
|
|
146
146
|
}
|
|
147
147
|
|
package/lib/entry-index.js
CHANGED
|
@@ -32,9 +32,7 @@ module.exports.NotFoundError = class NotFoundError extends Error {
|
|
|
32
32
|
|
|
33
33
|
const IndexOpts = figgyPudding({
|
|
34
34
|
metadata: {},
|
|
35
|
-
size: {}
|
|
36
|
-
uid: {},
|
|
37
|
-
gid: {}
|
|
35
|
+
size: {}
|
|
38
36
|
})
|
|
39
37
|
|
|
40
38
|
module.exports.insert = insert
|
|
@@ -49,7 +47,7 @@ function insert (cache, key, integrity, opts) {
|
|
|
49
47
|
metadata: opts.metadata
|
|
50
48
|
}
|
|
51
49
|
return fixOwner.mkdirfix(
|
|
52
|
-
path.dirname(bucket)
|
|
50
|
+
cache, path.dirname(bucket)
|
|
53
51
|
).then(() => {
|
|
54
52
|
const stringified = JSON.stringify(entry)
|
|
55
53
|
// NOTE - Cleverness ahoy!
|
|
@@ -63,8 +61,8 @@ function insert (cache, key, integrity, opts) {
|
|
|
63
61
|
bucket, `\n${hashEntry(stringified)}\t${stringified}`
|
|
64
62
|
)
|
|
65
63
|
}).then(
|
|
66
|
-
() => fixOwner.chownr(
|
|
67
|
-
).catch({code: 'ENOENT'}, () => {
|
|
64
|
+
() => fixOwner.chownr(cache, bucket)
|
|
65
|
+
).catch({ code: 'ENOENT' }, () => {
|
|
68
66
|
// There's a class of race conditions that happen when things get deleted
|
|
69
67
|
// during fixOwner, or between the two mkdirfix/chownr calls.
|
|
70
68
|
//
|
|
@@ -86,13 +84,13 @@ function insertSync (cache, key, integrity, opts) {
|
|
|
86
84
|
size: opts.size,
|
|
87
85
|
metadata: opts.metadata
|
|
88
86
|
}
|
|
89
|
-
fixOwner.mkdirfix.sync(path.dirname(bucket)
|
|
87
|
+
fixOwner.mkdirfix.sync(cache, path.dirname(bucket))
|
|
90
88
|
const stringified = JSON.stringify(entry)
|
|
91
89
|
fs.appendFileSync(
|
|
92
90
|
bucket, `\n${hashEntry(stringified)}\t${stringified}`
|
|
93
91
|
)
|
|
94
92
|
try {
|
|
95
|
-
fixOwner.chownr.sync(
|
|
93
|
+
fixOwner.chownr.sync(cache, bucket)
|
|
96
94
|
} catch (err) {
|
|
97
95
|
if (err.code !== 'ENOENT') {
|
|
98
96
|
throw err
|
|
@@ -178,7 +176,7 @@ function lsStream (cache) {
|
|
|
178
176
|
const formatted = formatEntry(cache, entry)
|
|
179
177
|
formatted && stream.push(formatted)
|
|
180
178
|
}
|
|
181
|
-
}).catch({code: 'ENOENT'}, nop)
|
|
179
|
+
}).catch({ code: 'ENOENT' }, nop)
|
|
182
180
|
})
|
|
183
181
|
})
|
|
184
182
|
}).then(() => {
|
|
@@ -282,8 +280,8 @@ function formatEntry (cache, entry) {
|
|
|
282
280
|
|
|
283
281
|
function readdirOrEmpty (dir) {
|
|
284
282
|
return readdirAsync(dir)
|
|
285
|
-
.catch({code: 'ENOENT'}, () => [])
|
|
286
|
-
.catch({code: 'ENOTDIR'}, () => [])
|
|
283
|
+
.catch({ code: 'ENOENT' }, () => [])
|
|
284
|
+
.catch({ code: 'ENOTDIR' }, () => [])
|
|
287
285
|
}
|
|
288
286
|
|
|
289
287
|
function nop () {
|
package/lib/util/fix-owner.js
CHANGED
|
@@ -5,83 +5,115 @@ const BB = require('bluebird')
|
|
|
5
5
|
const chownr = BB.promisify(require('chownr'))
|
|
6
6
|
const mkdirp = BB.promisify(require('mkdirp'))
|
|
7
7
|
const inflight = require('promise-inflight')
|
|
8
|
+
const inferOwner = require('infer-owner')
|
|
9
|
+
|
|
10
|
+
// Memoize getuid()/getgid() calls.
|
|
11
|
+
// patch process.setuid/setgid to invalidate cached value on change
|
|
12
|
+
const self = { uid: null, gid: null }
|
|
13
|
+
const getSelf = () => {
|
|
14
|
+
if (typeof self.uid !== 'number') {
|
|
15
|
+
self.uid = process.getuid()
|
|
16
|
+
const setuid = process.setuid
|
|
17
|
+
process.setuid = (uid) => {
|
|
18
|
+
self.uid = null
|
|
19
|
+
process.setuid = setuid
|
|
20
|
+
return process.setuid(uid)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (typeof self.gid !== 'number') {
|
|
24
|
+
self.gid = process.getgid()
|
|
25
|
+
const setgid = process.setgid
|
|
26
|
+
process.setgid = (gid) => {
|
|
27
|
+
self.gid = null
|
|
28
|
+
process.setgid = setgid
|
|
29
|
+
return process.setgid(gid)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
8
33
|
|
|
9
34
|
module.exports.chownr = fixOwner
|
|
10
|
-
function fixOwner (
|
|
35
|
+
function fixOwner (cache, filepath) {
|
|
11
36
|
if (!process.getuid) {
|
|
12
37
|
// This platform doesn't need ownership fixing
|
|
13
38
|
return BB.resolve()
|
|
14
39
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if ((typeof uid === 'number' && process.getuid() === uid) &&
|
|
20
|
-
(typeof gid === 'number' && process.getgid() === gid)) {
|
|
40
|
+
return BB.resolve(inferOwner(cache)).then(owner => {
|
|
41
|
+
const { uid, gid } = owner
|
|
42
|
+
getSelf()
|
|
43
|
+
|
|
21
44
|
// No need to override if it's already what we used.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
filepath,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
45
|
+
if (self.uid === uid && self.gid === gid) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return inflight(
|
|
50
|
+
'fixOwner: fixing ownership on ' + filepath,
|
|
51
|
+
() => chownr(
|
|
52
|
+
filepath,
|
|
53
|
+
typeof uid === 'number' ? uid : self.uid,
|
|
54
|
+
typeof gid === 'number' ? gid : self.gid
|
|
55
|
+
).catch({ code: 'ENOENT' }, () => null)
|
|
56
|
+
)
|
|
57
|
+
})
|
|
32
58
|
}
|
|
33
59
|
|
|
34
60
|
module.exports.chownr.sync = fixOwnerSync
|
|
35
|
-
function fixOwnerSync (
|
|
61
|
+
function fixOwnerSync (cache, filepath) {
|
|
36
62
|
if (!process.getuid) {
|
|
37
63
|
// This platform doesn't need ownership fixing
|
|
38
64
|
return
|
|
39
65
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
if ((typeof uid === 'number' && process.getuid() === uid) &&
|
|
45
|
-
(typeof gid === 'number' && process.getgid() === gid)) {
|
|
66
|
+
const { uid, gid } = inferOwner.sync(cache)
|
|
67
|
+
getSelf()
|
|
68
|
+
if (self.uid === uid && self.gid === gid) {
|
|
46
69
|
// No need to override if it's already what we used.
|
|
47
70
|
return
|
|
48
71
|
}
|
|
49
72
|
try {
|
|
50
73
|
chownr.sync(
|
|
51
74
|
filepath,
|
|
52
|
-
typeof uid === 'number' ? uid :
|
|
53
|
-
typeof gid === 'number' ? gid :
|
|
75
|
+
typeof uid === 'number' ? uid : self.uid,
|
|
76
|
+
typeof gid === 'number' ? gid : self.gid
|
|
54
77
|
)
|
|
55
78
|
} catch (err) {
|
|
79
|
+
// only catch ENOENT, any other error is a problem.
|
|
56
80
|
if (err.code === 'ENOENT') {
|
|
57
81
|
return null
|
|
58
82
|
}
|
|
83
|
+
throw err
|
|
59
84
|
}
|
|
60
85
|
}
|
|
61
86
|
|
|
62
87
|
module.exports.mkdirfix = mkdirfix
|
|
63
|
-
function mkdirfix (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
function mkdirfix (cache, p, cb) {
|
|
89
|
+
// we have to infer the owner _before_ making the directory, even though
|
|
90
|
+
// we aren't going to use the results, since the cache itself might not
|
|
91
|
+
// exist yet. If we mkdirp it, then our current uid/gid will be assumed
|
|
92
|
+
// to be correct if it creates the cache folder in the process.
|
|
93
|
+
return BB.resolve(inferOwner(cache)).then(() => {
|
|
94
|
+
return mkdirp(p).then(made => {
|
|
95
|
+
if (made) {
|
|
96
|
+
return fixOwner(cache, made).then(() => made)
|
|
97
|
+
}
|
|
98
|
+
}).catch({ code: 'EEXIST' }, () => {
|
|
99
|
+
// There's a race in mkdirp!
|
|
100
|
+
return fixOwner(cache, p).then(() => null)
|
|
101
|
+
})
|
|
71
102
|
})
|
|
72
103
|
}
|
|
73
104
|
|
|
74
105
|
module.exports.mkdirfix.sync = mkdirfixSync
|
|
75
|
-
function mkdirfixSync (
|
|
106
|
+
function mkdirfixSync (cache, p) {
|
|
76
107
|
try {
|
|
108
|
+
inferOwner.sync(cache)
|
|
77
109
|
const made = mkdirp.sync(p)
|
|
78
110
|
if (made) {
|
|
79
|
-
fixOwnerSync(
|
|
111
|
+
fixOwnerSync(cache, made)
|
|
80
112
|
return made
|
|
81
113
|
}
|
|
82
114
|
} catch (err) {
|
|
83
115
|
if (err.code === 'EEXIST') {
|
|
84
|
-
fixOwnerSync(
|
|
116
|
+
fixOwnerSync(cache, p)
|
|
85
117
|
return null
|
|
86
118
|
} else {
|
|
87
119
|
throw err
|
package/lib/util/tmp.js
CHANGED
|
@@ -9,16 +9,14 @@ const rimraf = BB.promisify(require('rimraf'))
|
|
|
9
9
|
const uniqueFilename = require('unique-filename')
|
|
10
10
|
|
|
11
11
|
const TmpOpts = figgyPudding({
|
|
12
|
-
tmpPrefix: {}
|
|
13
|
-
uid: {},
|
|
14
|
-
gid: {}
|
|
12
|
+
tmpPrefix: {}
|
|
15
13
|
})
|
|
16
14
|
|
|
17
15
|
module.exports.mkdir = mktmpdir
|
|
18
16
|
function mktmpdir (cache, opts) {
|
|
19
17
|
opts = TmpOpts(opts)
|
|
20
18
|
const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
|
|
21
|
-
return fixOwner.mkdirfix(
|
|
19
|
+
return fixOwner.mkdirfix(cache, tmpTarget).then(() => {
|
|
22
20
|
return tmpTarget
|
|
23
21
|
})
|
|
24
22
|
}
|
|
@@ -34,7 +32,6 @@ function withTmp (cache, opts, cb) {
|
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
module.exports.fix = fixtmpdir
|
|
37
|
-
function fixtmpdir (cache
|
|
38
|
-
|
|
39
|
-
return fixOwner(path.join(cache, 'tmp'), opts.uid, opts.gid)
|
|
35
|
+
function fixtmpdir (cache) {
|
|
36
|
+
return fixOwner(cache, path.join(cache, 'tmp'))
|
|
40
37
|
}
|
package/lib/verify.js
CHANGED
|
@@ -22,9 +22,7 @@ const VerifyOpts = figgyPudding({
|
|
|
22
22
|
filter: {},
|
|
23
23
|
log: {
|
|
24
24
|
default: { silly () {} }
|
|
25
|
-
}
|
|
26
|
-
uid: {},
|
|
27
|
-
gid: {}
|
|
25
|
+
}
|
|
28
26
|
})
|
|
29
27
|
|
|
30
28
|
module.exports = verify
|
|
@@ -67,9 +65,9 @@ function markEndTime (cache, opts) {
|
|
|
67
65
|
|
|
68
66
|
function fixPerms (cache, opts) {
|
|
69
67
|
opts.log.silly('verify', 'fixing cache permissions')
|
|
70
|
-
return fixOwner.mkdirfix(cache,
|
|
68
|
+
return fixOwner.mkdirfix(cache, cache).then(() => {
|
|
71
69
|
// TODO - fix file permissions too
|
|
72
|
-
return fixOwner.chownr(cache,
|
|
70
|
+
return fixOwner.chownr(cache, cache)
|
|
73
71
|
}).then(() => null)
|
|
74
72
|
}
|
|
75
73
|
|
|
@@ -130,7 +128,7 @@ function garbageCollect (cache, opts) {
|
|
|
130
128
|
})
|
|
131
129
|
})
|
|
132
130
|
}
|
|
133
|
-
}, {concurrency: opts.concurrency}))
|
|
131
|
+
}, { concurrency: opts.concurrency }))
|
|
134
132
|
})
|
|
135
133
|
})
|
|
136
134
|
}
|
|
@@ -150,7 +148,7 @@ function verifyContent (filepath, sri) {
|
|
|
150
148
|
contentInfo.valid = false
|
|
151
149
|
})
|
|
152
150
|
}).then(() => contentInfo)
|
|
153
|
-
}).catch({code: 'ENOENT'}, () => ({size: 0, valid: false}))
|
|
151
|
+
}).catch({ code: 'ENOENT' }, () => ({ size: 0, valid: false }))
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
function rebuildIndex (cache, opts) {
|
|
@@ -183,7 +181,7 @@ function rebuildIndex (cache, opts) {
|
|
|
183
181
|
}
|
|
184
182
|
return BB.map(Object.keys(buckets), key => {
|
|
185
183
|
return rebuildBucket(cache, buckets[key], stats, opts)
|
|
186
|
-
}, {concurrency: opts.concurrency}).then(() => stats)
|
|
184
|
+
}, { concurrency: opts.concurrency }).then(() => stats)
|
|
187
185
|
})
|
|
188
186
|
}
|
|
189
187
|
|
|
@@ -195,12 +193,10 @@ function rebuildBucket (cache, bucket, stats, opts) {
|
|
|
195
193
|
const content = contentPath(cache, entry.integrity)
|
|
196
194
|
return fs.statAsync(content).then(() => {
|
|
197
195
|
return index.insert(cache, entry.key, entry.integrity, {
|
|
198
|
-
uid: opts.uid,
|
|
199
|
-
gid: opts.gid,
|
|
200
196
|
metadata: entry.metadata,
|
|
201
197
|
size: entry.size
|
|
202
198
|
}).then(() => { stats.totalEntries++ })
|
|
203
|
-
}).catch({code: 'ENOENT'}, () => {
|
|
199
|
+
}).catch({ code: 'ENOENT' }, () => {
|
|
204
200
|
stats.rejectedEntries++
|
|
205
201
|
stats.missingContent++
|
|
206
202
|
})
|
|
@@ -216,7 +212,11 @@ function cleanTmp (cache, opts) {
|
|
|
216
212
|
function writeVerifile (cache, opts) {
|
|
217
213
|
const verifile = path.join(cache, '_lastverified')
|
|
218
214
|
opts.log.silly('verify', 'writing verifile to ' + verifile)
|
|
219
|
-
|
|
215
|
+
try {
|
|
216
|
+
return fs.writeFileAsync(verifile, '' + (+(new Date())))
|
|
217
|
+
} finally {
|
|
218
|
+
fixOwner.chownr.sync(cache, verifile)
|
|
219
|
+
}
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
module.exports.lastRun = lastRun
|
package/locales/en.json
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
"No cache entry for `%s` found in `%s`": "No cache entry for %s found in %s",
|
|
3
3
|
"Integrity verification failed for %s (%s)": "Integrity verification failed for %s (%s)",
|
|
4
4
|
"Bad data size: expected inserted data to be %s bytes, but got %s instead": "Bad data size: expected inserted data to be %s bytes, but got %s instead",
|
|
5
|
-
"Cache input stream was empty": "Cache input stream was empty"
|
|
6
|
-
|
|
5
|
+
"Cache input stream was empty": "Cache input stream was empty",
|
|
6
|
+
"Integrity check failed:\n Wanted: %s\n Found: %s": "Integrity check failed:\n Wanted: %s\n Found: %s"
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cacache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.2",
|
|
4
4
|
"cache-version": {
|
|
5
5
|
"content": "2",
|
|
6
6
|
"index": "5"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
|
|
24
24
|
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'"
|
|
25
25
|
},
|
|
26
|
-
"repository": "https://github.com/
|
|
26
|
+
"repository": "https://github.com/npm/cacache",
|
|
27
27
|
"keywords": [
|
|
28
28
|
"cache",
|
|
29
29
|
"caching",
|
|
@@ -58,32 +58,33 @@
|
|
|
58
58
|
],
|
|
59
59
|
"license": "ISC",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"bluebird": "^3.5.
|
|
61
|
+
"bluebird": "^3.5.5",
|
|
62
62
|
"chownr": "^1.1.1",
|
|
63
63
|
"figgy-pudding": "^3.5.1",
|
|
64
|
-
"glob": "^7.1.
|
|
64
|
+
"glob": "^7.1.4",
|
|
65
65
|
"graceful-fs": "^4.1.15",
|
|
66
|
+
"infer-owner": "^1.0.3",
|
|
66
67
|
"lru-cache": "^5.1.1",
|
|
67
68
|
"mississippi": "^3.0.0",
|
|
68
69
|
"mkdirp": "^0.5.1",
|
|
69
70
|
"move-concurrently": "^1.0.1",
|
|
70
71
|
"promise-inflight": "^1.0.1",
|
|
71
|
-
"rimraf": "^2.6.
|
|
72
|
+
"rimraf": "^2.6.3",
|
|
72
73
|
"ssri": "^6.0.1",
|
|
73
74
|
"unique-filename": "^1.1.1",
|
|
74
75
|
"y18n": "^4.0.0"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
77
78
|
"benchmark": "^2.1.4",
|
|
78
|
-
"chalk": "^2.
|
|
79
|
+
"chalk": "^2.4.2",
|
|
79
80
|
"cross-env": "^5.1.4",
|
|
80
|
-
"require-inject": "^1.4.
|
|
81
|
-
"standard": "^
|
|
82
|
-
"standard-version": "^
|
|
83
|
-
"tacks": "^1.
|
|
84
|
-
"tap": "^12.
|
|
81
|
+
"require-inject": "^1.4.4",
|
|
82
|
+
"standard": "^12.0.1",
|
|
83
|
+
"standard-version": "^6.0.1",
|
|
84
|
+
"tacks": "^1.3.0",
|
|
85
|
+
"tap": "^12.7.0",
|
|
85
86
|
"weallbehave": "^1.2.0",
|
|
86
|
-
"weallcontribute": "^1.0.
|
|
87
|
+
"weallcontribute": "^1.0.9"
|
|
87
88
|
},
|
|
88
89
|
"config": {
|
|
89
90
|
"nyc": {
|
package/put.js
CHANGED
|
@@ -16,10 +16,9 @@ const PutOpts = figgyPudding({
|
|
|
16
16
|
pickAlgorithm: {},
|
|
17
17
|
size: {},
|
|
18
18
|
tmpPrefix: {},
|
|
19
|
-
uid: {},
|
|
20
|
-
gid: {},
|
|
21
19
|
single: {},
|
|
22
20
|
sep: {},
|
|
21
|
+
error: {},
|
|
23
22
|
strict: {}
|
|
24
23
|
})
|
|
25
24
|
|
|
@@ -28,7 +27,7 @@ function putData (cache, key, data, opts) {
|
|
|
28
27
|
opts = PutOpts(opts)
|
|
29
28
|
return write(cache, data, opts).then(res => {
|
|
30
29
|
return index.insert(
|
|
31
|
-
cache, key, res.integrity, opts.concat({size: res.size})
|
|
30
|
+
cache, key, res.integrity, opts.concat({ size: res.size })
|
|
32
31
|
).then(entry => {
|
|
33
32
|
if (opts.memoize) {
|
|
34
33
|
memo.put(cache, entry, data, opts)
|
|
@@ -63,7 +62,7 @@ function putStream (cache, key, opts) {
|
|
|
63
62
|
})
|
|
64
63
|
}, cb => {
|
|
65
64
|
contentStream.end(() => {
|
|
66
|
-
index.insert(cache, key, integrity, opts.concat({size})).then(entry => {
|
|
65
|
+
index.insert(cache, key, integrity, opts.concat({ size })).then(entry => {
|
|
67
66
|
if (opts.memoize) {
|
|
68
67
|
memo.put(cache, entry, Buffer.concat(memoData, memoTotal), opts)
|
|
69
68
|
}
|