Comparing version 6.0.1 to 6.0.2
@@ -5,2 +5,12 @@ # Change Log | ||
<a name="6.0.2"></a> | ||
## [6.0.2](https://github.com/zkat/cacache/compare/v6.0.1...v6.0.2) (2017-03-11) | ||
### Bug Fixes | ||
* **index:** segment cache items with another subbucket (#64) ([c3644e5](https://github.com/zkat/cacache/commit/c3644e5)) | ||
<a name="6.0.1"></a> | ||
@@ -7,0 +17,0 @@ ## [6.0.1](https://github.com/zkat/cacache/compare/v6.0.0...v6.0.1) (2017-03-05) |
@@ -38,3 +38,3 @@ 'use strict' | ||
if (!entry && !byDigest) { | ||
throw index.notFoundError(cache, key) | ||
throw new index.NotFoundError(cache, key) | ||
} | ||
@@ -77,3 +77,3 @@ return read(cache, byDigest ? key : entry.digest, { | ||
return stream.emit( | ||
'error', index.notFoundError(cache, key) | ||
'error', new index.NotFoundError(cache, key) | ||
) | ||
@@ -80,0 +80,0 @@ } |
'use strict' | ||
var contentVer = require('../../package.json')['cache-version'].content | ||
var hashToSegments = require('../util/hash-to-segments') | ||
var path = require('path') | ||
@@ -14,9 +15,7 @@ | ||
hashAlgorithm = hashAlgorithm ? hashAlgorithm.toLowerCase() : 'sha512' | ||
return path.join( | ||
return path.join.apply(path, [ | ||
cache, | ||
`content-v${contentVer}`, | ||
hashAlgorithm, | ||
address.slice(0, 2), | ||
address.slice(2) | ||
) | ||
].concat(hashToSegments(address))) | ||
} |
'use strict' | ||
const asyncMap = require('slide/lib/async-map') | ||
const contentPath = require('./content/path') | ||
@@ -10,3 +9,4 @@ const crypto = require('crypto') | ||
const Promise = require('bluebird') | ||
const through = require('mississippi').through | ||
const ms = require('mississippi') | ||
const hashToSegments = require('./util/hash-to-segments') | ||
@@ -17,3 +17,15 @@ const indexV = require('../package.json')['cache-version'].index | ||
const readFileAsync = Promise.promisify(fs.readFile) | ||
const readdirAsync = Promise.promisify(fs.readdir) | ||
const concat = ms.concat | ||
const from = ms.from | ||
module.exports.NotFoundError = class NotFoundError extends Error { | ||
constructor (cache, key) { | ||
super('content not found') | ||
this.code = 'ENOENT' | ||
this.cache = cache | ||
this.key = key | ||
} | ||
} | ||
module.exports.insert = insert | ||
@@ -79,43 +91,35 @@ function insert (cache, key, digest, opts) { | ||
const indexDir = bucketDir(cache) | ||
const stream = through.obj() | ||
fs.readdir(indexDir, function (err, buckets) { | ||
if (err && err.code === 'ENOENT') { | ||
return stream.end() | ||
} else if (err) { | ||
return stream.emit('error', err) | ||
} else { | ||
asyncMap(buckets, (bucket, cb) => { | ||
fs.readdir(path.join(indexDir, bucket), (err, files) => { | ||
if (err && err.code === 'ENOENT') { | ||
return cb() | ||
} else if (err) { | ||
return cb(err) | ||
} else { | ||
asyncMap(files, function (f, cb) { | ||
const bpath = path.join(indexDir, bucket, f) | ||
bucketEntries(cache, bpath).then(_entries => { | ||
const entries = _entries.reduce((acc, entry) => { | ||
acc[entry.key] = entry | ||
return acc | ||
}, {}) | ||
Object.keys(entries).forEach(function (k) { | ||
stream.write(formatEntry(cache, entries[k])) | ||
}) | ||
cb() | ||
}, err => { | ||
if (err.code === 'ENOENT') { | ||
cb() | ||
} else { | ||
cb(err) | ||
} | ||
}) | ||
}, cb) | ||
} | ||
}) | ||
}, function (err) { | ||
if (err) { stream.emit('error') } | ||
stream.end() | ||
const stream = from.obj() | ||
// "/cachename/*" | ||
readdirOrEmpty(indexDir).map(bucket => { | ||
const bucketPath = path.join(indexDir, bucket) | ||
// "/cachename/<bucket 0xFF>/*" | ||
return readdirOrEmpty(bucketPath).map(subbucket => { | ||
const subbucketPath = path.join(bucketPath, subbucket) | ||
// "/cachename/<bucket 0xFF>/<bucket 0xFF>/*" | ||
return readdirOrEmpty(subbucketPath).map(entry => { | ||
const getKeyToEntry = bucketEntries( | ||
cache, | ||
path.join(subbucketPath, entry) | ||
).reduce((acc, entry) => { | ||
acc.set(entry.key, entry) | ||
return acc | ||
}, new Map()) | ||
return getKeyToEntry.then(reduced => { | ||
return Array.from(reduced.values()).map( | ||
entry => stream.push(formatEntry(cache, entry)) | ||
) | ||
}).catch({code: 'ENOENT'}, nop) | ||
}) | ||
} | ||
}) | ||
}).then(() => { | ||
stream.push(null) | ||
}, err => { | ||
stream.emit('error', err) | ||
}) | ||
return stream | ||
@@ -126,21 +130,12 @@ } | ||
function ls (cache) { | ||
const entries = {} | ||
return Promise.fromNode(cb => { | ||
lsStream(cache).on('finish', function () { | ||
cb(null, entries) | ||
}).on('data', function (d) { | ||
entries[d.key] = d | ||
}).on('error', cb) | ||
lsStream(cache).on('error', cb).pipe(concat(entries => { | ||
cb(null, entries.reduce((acc, xs) => { | ||
acc[xs.key] = xs | ||
return acc | ||
}, {})) | ||
})) | ||
}) | ||
} | ||
module.exports.notFoundError = notFoundError | ||
function notFoundError (cache, key) { | ||
const err = new Error('content not found') | ||
err.code = 'ENOENT' | ||
err.cache = cache | ||
err.key = key | ||
return err | ||
} | ||
function bucketEntries (cache, bucket, filter) { | ||
@@ -179,3 +174,5 @@ return readFileAsync( | ||
const hashed = hashKey(key) | ||
return path.join(bucketDir(cache), hashed.slice(0, 2), hashed.slice(2)) | ||
return path.join.apply(path, [bucketDir(cache)].concat( | ||
hashToSegments(hashed) | ||
)) | ||
} | ||
@@ -201,1 +198,8 @@ | ||
} | ||
function readdirOrEmpty (dir) { | ||
return readdirAsync(dir).catch({code: 'ENOENT'}, () => []) | ||
} | ||
function nop () { | ||
} |
{ | ||
"name": "cacache", | ||
"version": "6.0.1", | ||
"version": "6.0.2", | ||
"cache-version": { | ||
"content": "1", | ||
"index": "1" | ||
"content": "2", | ||
"index": "2" | ||
}, | ||
@@ -20,3 +20,3 @@ "description": "General content-addressable cache system that maintains a filesystem registry of file data.", | ||
"release": "standard-version -s", | ||
"test": "nyc -- tap -J test/*.js", | ||
"test": "nyc --all -- tap -J test/*.js", | ||
"test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test", | ||
@@ -62,3 +62,2 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", | ||
"rimraf": "^2.6.1", | ||
"slide": "^1.1.6", | ||
"unique-filename": "^1.1.0" | ||
@@ -65,0 +64,0 @@ }, |
@@ -21,15 +21,19 @@ # 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) | ||
* [API](#api) | ||
* [`ls`](#ls) | ||
* [`get`](#get-data) | ||
* [`get.stream`](#get-stream) | ||
* [`get.info`](#get-info) | ||
* [`put`](#put-data) | ||
* [`put.stream`](#put-stream) | ||
* [`put*` opts](#put-options) | ||
* [`rm.all`](#rm-all) | ||
* [`rm.entry`](#rm-entry) | ||
* [`rm.content`](#rm-content) | ||
* [`clearMemoized`](#clear-memoized) | ||
* [`verify`](#verify) | ||
* [`verify.lastRun`](#verify-last-run) | ||
* Reading | ||
* [`ls`](#ls) | ||
* [`ls.stream`](#ls-stream) | ||
* [`get`](#get-data) | ||
* [`get.stream`](#get-stream) | ||
* [`get.info`](#get-info) | ||
* Writing | ||
* [`put`](#put-data) | ||
* [`put.stream`](#put-stream) | ||
* [`put*` opts](#put-options) | ||
* [`rm.all`](#rm-all) | ||
* [`rm.entry`](#rm-entry) | ||
* [`rm.content`](#rm-content) | ||
* Utilities | ||
* [`clearMemoized`](#clear-memoized) | ||
* [`verify`](#verify) | ||
* [`verify.lastRun`](#verify-last-run) | ||
@@ -45,3 +49,2 @@ ### Example | ||
const key = 'my-unique-key-1234' | ||
let tarballDigest = null | ||
@@ -125,2 +128,40 @@ // Cache it! Use `cachePath` as the root of the content cache | ||
#### <a name="ls-stream"></a> `> cacache.ls.stream(cache) -> Readable` | ||
Lists info for all entries currently in the cache as a single large object. | ||
This works just like [`ls`](#ls), except [`get.info`](#get-info) entries are | ||
returned as `'data'` events on the returned stream. | ||
##### Example | ||
```javascript | ||
cacache.ls.stream(cachePath).on('data', console.log) | ||
// Output | ||
{ | ||
key: 'my-thing', | ||
digest: 'deadbeef', | ||
hashAlgorithm: 'sha512', | ||
path: '.testcache/content/deadbeef', // joined with `cachePath` | ||
time: 12345698490, | ||
metadata: { | ||
name: 'blah', | ||
version: '1.2.3', | ||
description: 'this was once a package but now it is my-thing' | ||
} | ||
} | ||
{ | ||
key: 'other-thing', | ||
digest: 'bada55', | ||
hashAlgorithm: 'whirlpool', | ||
path: '.testcache/content/bada55', | ||
time: 11992309289 | ||
} | ||
{ | ||
... | ||
} | ||
``` | ||
#### <a name="get-data"></a> `> cacache.get(cache, key, [opts]) -> Promise({data, metadata, digest, hashAlgorithm})` | ||
@@ -216,4 +257,3 @@ | ||
Looks up `key` in the cache index, returning information about the entry if | ||
one exists. If an entry does not exist, the second argument to `cb` will be | ||
falsy. | ||
one exists. | ||
@@ -220,0 +260,0 @@ ##### Fields |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51592
13
20
946
470
- Removedslide@^1.1.6
- Removedslide@1.1.6(transitive)