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/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, relativa al argumento `cache`.
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 [![npm version](https://img.shields.io/npm/v/cacache.svg)](https://npm.im/cacache) [![license](https://img.shields.io/npm/l/cacache.svg)](https://npm.im/cacache) [![Travis](https://img.shields.io/travis/zkat/cacache.svg)](https://travis-ci.org/zkat/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/zkat/cacache?svg=true)](https://ci.appveyor.com/project/zkat/cacache) [![Coverage Status](https://coveralls.io/repos/github/zkat/cacache/badge.svg?branch=latest)](https://coveralls.io/github/zkat/cacache?branch=latest)
1
+ # cacache [![npm version](https://img.shields.io/npm/v/cacache.svg)](https://npm.im/cacache) [![license](https://img.shields.io/npm/l/cacache.svg)](https://npm.im/cacache) [![Travis](https://img.shields.io/travis/npm/cacache.svg)](https://travis-ci.org/npm/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/npm/cacache?svg=true)](https://ci.appveyor.com/project/npm/cacache) [![Coverage Status](https://coveralls.io/repos/github/npm/cacache/badge.svg?branch=latest)](https://coveralls.io/github/npm/cacache?branch=latest)
2
2
 
3
- [`cacache`](https://github.com/zkat/cacache) is a Node.js library for managing
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
- It was originally written to be used as [npm](https://npm.im)'s local cache, but
9
- can just as easily be used on its own.
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 relative to `cache` argument where content is stored.
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 within
502
- are made according to the same `opts.gid`/`opts.uid` settings that would be
503
- passed in. If not, you can ask cacache to do it for you by calling
504
- [`tmp.fix()`](#tmp-fix), which will fix all tmp directory permissions.
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
 
@@ -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),
@@ -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]
@@ -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
- }, err => {
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), opts.uid, opts.gid
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
- destDir, opts.uid, opts.gid
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(destination, opts.uid, opts.gid)
144
+ return fixOwner.chownr(cache, destination)
145
145
  })
146
146
  }
147
147
 
@@ -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), opts.uid, opts.gid
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(bucket, opts.uid, opts.gid)
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), opts.uid, opts.gid)
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(bucket, opts.uid, opts.gid)
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 () {
@@ -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 (filepath, uid, gid) {
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
- if (typeof uid !== 'number' && typeof gid !== 'number') {
16
- // There's no permissions override. Nothing to do here.
17
- return BB.resolve()
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
- return BB.resolve()
23
- }
24
- return inflight(
25
- 'fixOwner: fixing ownership on ' + filepath,
26
- () => chownr(
27
- filepath,
28
- typeof uid === 'number' ? uid : process.getuid(),
29
- typeof gid === 'number' ? gid : process.getgid()
30
- ).catch({code: 'ENOENT'}, () => null)
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 (filepath, uid, gid) {
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
- if (typeof uid !== 'number' && typeof gid !== 'number') {
41
- // There's no permissions override. Nothing to do here.
42
- return
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 : process.getuid(),
53
- typeof gid === 'number' ? gid : process.getgid()
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 (p, uid, gid, cb) {
64
- return mkdirp(p).then(made => {
65
- if (made) {
66
- return fixOwner(made, uid, gid).then(() => made)
67
- }
68
- }).catch({code: 'EEXIST'}, () => {
69
- // There's a race in mkdirp!
70
- return fixOwner(p, uid, gid).then(() => null)
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 (p, uid, gid) {
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(made, uid, gid)
111
+ fixOwnerSync(cache, made)
80
112
  return made
81
113
  }
82
114
  } catch (err) {
83
115
  if (err.code === 'EEXIST') {
84
- fixOwnerSync(p, uid, gid)
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(tmpTarget, opts.uid, opts.gid).then(() => {
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, opts) {
38
- opts = TmpOpts(opts)
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, opts.uid, opts.gid).then(() => {
68
+ return fixOwner.mkdirfix(cache, cache).then(() => {
71
69
  // TODO - fix file permissions too
72
- return fixOwner.chownr(cache, opts.uid, opts.gid)
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
- return fs.writeFileAsync(verifile, '' + (+(new Date())))
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": "11.3.2",
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/zkat/cacache",
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.3",
61
+ "bluebird": "^3.5.5",
62
62
  "chownr": "^1.1.1",
63
63
  "figgy-pudding": "^3.5.1",
64
- "glob": "^7.1.3",
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.2",
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.3.2",
79
+ "chalk": "^2.4.2",
79
80
  "cross-env": "^5.1.4",
80
- "require-inject": "^1.4.2",
81
- "standard": "^11.0.1",
82
- "standard-version": "^4.4.0",
83
- "tacks": "^1.2.7",
84
- "tap": "^12.1.1",
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.8"
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
  }