Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit afdfe7f

Browse files
lidelAlan Shaw
authored and
Alan Shaw
committed
fix: pin type filtering in pin.ls (#2228)
### Summary This PR fixes filtering, improves interop with go-ipfs and adds missing tests for `pin ls` ### Details Old version returned indirect pin when `pin ls -t direct <path>` was executed. This PR also tweaks error handling to match behavior from go-ipfs/js-ipfs-http-client and pass improved interop tests added in ipfs-inactive/interface-js-ipfs-core#375 I've added some inline comments, hope it helps in review. ### Related - Improved `pin ls` interop tests: ipfs-inactive/interface-js-ipfs-core#375 (this PR is not blocked by interop tests, old ones were less strict) - We need this fix for embedded js-ipfs in Brave 🦁 ipfs/ipfs-companion#716 License: MIT Signed-off-by: Marcin Rataj <[email protected]>
1 parent f5cf216 commit afdfe7f

File tree

5 files changed

+97
-15
lines changed

5 files changed

+97
-15
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189
"execa": "^2.0.3",
190190
"form-data": "^2.5.0",
191191
"hat": "0.0.3",
192-
"interface-ipfs-core": "^0.105.1",
192+
"interface-ipfs-core": "~0.107.3",
193193
"ipfsd-ctl": "^0.43.0",
194194
"libp2p-websocket-star": "~0.10.2",
195195
"ncp": "^2.0.0",

src/core/components/dag.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ module.exports = function dag (self) {
101101
if (split.length > 0) {
102102
path = split.join('/')
103103
} else {
104-
path = '/'
104+
path = path || '/'
105105
}
106106
} else if (Buffer.isBuffer(cid)) {
107107
try {
@@ -115,7 +115,7 @@ module.exports = function dag (self) {
115115
self._preload(cid)
116116
}
117117

118-
if (path === undefined || path === '/') {
118+
if (path == null || path === '/') {
119119
self._ipld.get(cid).then(
120120
(value) => {
121121
callback(null, {

src/core/components/pin.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ module.exports = (self) => {
327327
// check the pinned state of specific hashes
328328
waterfall([
329329
(cb) => resolvePath(self.object, paths, cb),
330-
(hashes, cb) => mapSeries(hashes, (hash, done) => pin._isPinnedWithType(hash, types.all, done), cb),
330+
(hashes, cb) => mapSeries(hashes, (hash, done) => pin._isPinnedWithType(hash, type, done), cb),
331331
(results, cb) => {
332332
results = results
333333
.filter(result => result.pinned)
@@ -348,12 +348,12 @@ module.exports = (self) => {
348348
})
349349

350350
if (!results.length) {
351-
return cb(new Error(`Path is not pinned`))
351+
return cb(new Error(`path '${paths}' is not pinned`))
352352
}
353353

354354
cb(null, results)
355355
}
356-
], callback)
356+
], (err, results) => err ? callback(err) : callback(null, results)) // we don't want results equal [undefined] when err is present
357357
} else {
358358
// show all pinned items of type
359359
let pins = []

src/http/api/resources/pin.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ exports.ls = {
5757
try {
5858
result = await ipfs.pin.ls(path, { type })
5959
} catch (err) {
60-
throw Boom.boomify(err, { message: 'Failed to list pins' })
60+
throw Boom.boomify(err)
6161
}
6262

6363
return h.response({

test/core/pin.js

+90-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ chai.use(dirtyChai)
99

1010
const fs = require('fs')
1111

12+
const CID = require('cids')
1213
const IPFS = require('../../src/core')
1314
const createTempRepo = require('../utils/create-repo-nodejs')
1415
const expectTimeout = require('../utils/expect-timeout')
@@ -44,14 +45,22 @@ describe('pin', function () {
4445
let pin
4546
let repo
4647

47-
function expectPinned (hash, type, pinned = true) {
48+
function expectPinned (hash, type = pinTypes.all, pinned = true) {
4849
if (typeof type === 'boolean') {
4950
pinned = type
50-
type = undefined
51+
type = pinTypes.all
5152
}
5253

53-
return pin._isPinnedWithType(hash, type || pinTypes.all)
54-
.then(result => expect(result.pinned).to.eql(pinned))
54+
return pin._isPinnedWithType(hash, type)
55+
.then(result => {
56+
expect(result.pinned).to.eql(pinned)
57+
if (type === pinTypes.indirect) {
58+
// indirect pins return a CID of recursively pinned root instead of 'indirect' string
59+
expect(CID.isCID(result.reason)).to.be.true()
60+
} else if (type !== pinTypes.all) {
61+
expect(result.reason).to.eql(type)
62+
}
63+
})
5564
}
5665

5766
async function clearPins () {
@@ -159,6 +168,7 @@ describe('pin', function () {
159168
it('recursive', function () {
160169
return pin.add(pins.root)
161170
.then(() => {
171+
expectPinned(pins.root, pinTypes.recursive)
162172
const pinChecks = Object.values(pins)
163173
.map(hash => expectPinned(hash))
164174

@@ -169,7 +179,7 @@ describe('pin', function () {
169179
it('direct', function () {
170180
return pin.add(pins.root, { recursive: false })
171181
.then(() => Promise.all([
172-
expectPinned(pins.root),
182+
expectPinned(pins.root, pinTypes.direct),
173183
expectPinned(pins.solarWiki, false)
174184
]))
175185
})
@@ -242,7 +252,7 @@ describe('pin', function () {
242252
)
243253
})
244254

245-
it('direct', function () {
255+
it('all direct', function () {
246256
return pin.ls({ type: 'direct' })
247257
.then(out =>
248258
expect(out).to.deep.include.members([
@@ -252,7 +262,7 @@ describe('pin', function () {
252262
)
253263
})
254264

255-
it('recursive', function () {
265+
it('all recursive', function () {
256266
return pin.ls({ type: 'recursive' })
257267
.then(out =>
258268
expect(out).to.deep.include.members([
@@ -262,7 +272,7 @@ describe('pin', function () {
262272
)
263273
})
264274

265-
it('indirect', function () {
275+
it('all indirect', function () {
266276
return pin.ls({ type: 'indirect' })
267277
.then(out =>
268278
expect(out).to.deep.include.members([
@@ -275,6 +285,78 @@ describe('pin', function () {
275285
])
276286
)
277287
})
288+
289+
it('direct for CID', function () {
290+
return pin.ls(pins.mercuryDir, { type: 'direct' })
291+
.then(out =>
292+
expect(out).to.have.deep.members([
293+
{ type: 'direct',
294+
hash: pins.mercuryDir }
295+
])
296+
)
297+
})
298+
299+
it('direct for path', function () {
300+
return pin.ls(`/ipfs/${pins.root}/mercury/`, { type: 'direct' })
301+
.then(out =>
302+
expect(out).to.have.deep.members([
303+
{ type: 'direct',
304+
hash: pins.mercuryDir }
305+
])
306+
)
307+
})
308+
309+
it('direct for path (no match)', function (done) {
310+
pin.ls(`/ipfs/${pins.root}/mercury/wiki.md`, { type: 'direct' }, (err, pinset) => {
311+
expect(err).to.exist()
312+
expect(pinset).to.not.exist()
313+
done()
314+
})
315+
})
316+
317+
it('direct for CID (no match)', function (done) {
318+
pin.ls(pins.root, { type: 'direct' }, (err, pinset) => {
319+
expect(err).to.exist()
320+
expect(pinset).to.not.exist()
321+
done()
322+
})
323+
})
324+
325+
it('recursive for CID', function () {
326+
return pin.ls(pins.root, { type: 'recursive' })
327+
.then(out =>
328+
expect(out).to.have.deep.members([
329+
{ type: 'recursive',
330+
hash: pins.root }
331+
])
332+
)
333+
})
334+
335+
it('recursive for CID (no match)', function (done) {
336+
return pin.ls(pins.mercuryDir, { type: 'recursive' }, (err, pinset) => {
337+
expect(err).to.exist()
338+
expect(pinset).to.not.exist()
339+
done()
340+
})
341+
})
342+
343+
it('indirect for CID', function () {
344+
return pin.ls(pins.solarWiki, { type: 'indirect' })
345+
.then(out =>
346+
expect(out).to.have.deep.members([
347+
{ type: `indirect through ${pins.root}`,
348+
hash: pins.solarWiki }
349+
])
350+
)
351+
})
352+
353+
it('indirect for CID (no match)', function (done) {
354+
pin.ls(pins.root, { type: 'indirect' }, (err, pinset) => {
355+
expect(err).to.exist()
356+
expect(pinset).to.not.exist()
357+
done()
358+
})
359+
})
278360
})
279361
})
280362

0 commit comments

Comments
 (0)