Skip to content

Commit d97a9de

Browse files
committed
feat: jsipfs pin improvements (ipfs#1249)
* initial sweep through to understand how pin works. Did make some changes but mostly minor. * refactor pb schema to it's own file * fix: don't pin files during files.add if opts.pin === false * feat: add some http qs parsing, http route/resources cleanup, cleanup core/utils.parseIpfsPath * feat: expand pin tests. \nFirst draft. still needs some further work. * feat: Add logging for entry/exit of pins: add/rm/flush/load. Clean some documentation. * feat: add --pin to files.add, fix: improper pin option parsing in core. * feat: Use ipfs.files.add to add init-docs instead of directly using the unix-fs importer. * feat(tests): Add tests for cli --pin option. I know this should be more of an integration test. Should be written in /core. Maybe talk with Victor about testing different layers * feat: use isIPFS to valiate a multihash.
1 parent e189b72 commit d97a9de

File tree

17 files changed

+1418
-36
lines changed

17 files changed

+1418
-36
lines changed

src/cli/commands/files/add.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ module.exports = {
178178
type: 'boolean',
179179
default: false,
180180
describe: 'Write no output'
181+
},
182+
pin: {
183+
type: 'boolean',
184+
default: true,
185+
describe: 'Pin this object when adding'
181186
}
182187
},
183188

@@ -192,6 +197,7 @@ module.exports = {
192197
cidVersion: argv.cidVersion,
193198
rawLeaves: argv.rawLeaves,
194199
onlyHash: argv.onlyHash
200+
pin: argv.pin
195201
}
196202

197203
// Temporary restriction on raw-leaves:

src/cli/commands/pin/add.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict'
2+
3+
const print = require('../../utils').print
4+
5+
module.exports = {
6+
command: 'add <ipfs-path>',
7+
8+
describe: 'Pins objects to local storage.',
9+
10+
builder: {
11+
recursive: {
12+
type: 'boolean',
13+
alias: 'r',
14+
default: true,
15+
describe: 'Recursively pin the object linked to by the specified object(s).'
16+
}
17+
},
18+
19+
handler (argv) {
20+
const paths = argv['ipfs-path'].split(' ')
21+
const recursive = argv.recursive
22+
const type = recursive ? 'recursive' : 'direct'
23+
argv.ipfs.pin.add(paths[0], { recursive: recursive }, (err, results) => {
24+
if (err) { throw err }
25+
results.forEach((res) => {
26+
print(`pinned ${res.hash} ${type}ly`)
27+
})
28+
})
29+
}
30+
}

src/cli/commands/pin/ls.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict'
2+
3+
const print = require('../../utils').print
4+
5+
module.exports = {
6+
// bracket syntax with '...' tells yargs to optionally accept a list
7+
command: 'ls [ipfs-path...]',
8+
9+
describe: 'List objects pinned to local storage.',
10+
11+
builder: {
12+
type: {
13+
type: 'string',
14+
alias: 't',
15+
default: 'all',
16+
choices: ['direct', 'indirect', 'recursive', 'all'],
17+
describe: 'The type of pinned keys to list.'
18+
},
19+
quiet: {
20+
type: 'boolean',
21+
alias: 'q',
22+
default: false,
23+
describe: 'Write just hashes of objects.'
24+
}
25+
},
26+
27+
handler: (argv) => {
28+
const paths = argv.ipfsPath || ''
29+
const type = argv.type
30+
const quiet = argv.quiet
31+
argv.ipfs.pin.ls(paths, { type: type }, (err, results) => {
32+
if (err) { throw err }
33+
results.forEach((res) => {
34+
let line = res.hash
35+
if (!quiet) {
36+
line += ` ${res.type}`
37+
}
38+
print(line)
39+
})
40+
})
41+
}
42+
}

src/cli/commands/pin/rm.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict'
2+
3+
const print = require('../../utils').print
4+
5+
module.exports = {
6+
command: 'rm <ipfs-path>',
7+
8+
describe: 'Removes the pinned object from local storage.',
9+
10+
builder: {
11+
recursive: {
12+
type: 'boolean',
13+
alias: 'r',
14+
default: true,
15+
describe: 'Recursively unpin the objects linked to by the specified object(s).'
16+
}
17+
},
18+
19+
handler: (argv) => {
20+
const paths = argv['ipfs-path'].split(' ')
21+
const recursive = argv.recursive
22+
argv.ipfs.pin.rm(paths, { recursive: recursive }, (err, results) => {
23+
if (err) { throw err }
24+
results.forEach((res) => {
25+
print(`unpinned ${res.hash}`)
26+
})
27+
})
28+
}
29+
}

src/core/components/files.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const CID = require('cids')
1818
const toB58String = require('multihashes').toB58String
1919

2020
function noop () {}
21+
function identity (x) { return x }
2122

2223
function prepareFile (self, opts, file, callback) {
2324
opts = opts || {}
@@ -111,7 +112,8 @@ module.exports = function files (self) {
111112
}, options)
112113

113114
let total = 0
114-
let prog = opts.progress || (() => {})
115+
const shouldPin = 'pin' in opts ? opts.pin : true
116+
const prog = opts.progress || noop
115117
const progress = (bytes) => {
116118
total += bytes
117119
prog(total)
@@ -122,7 +124,8 @@ module.exports = function files (self) {
122124
pull.map(normalizeContent),
123125
pull.flatten(),
124126
importer(self._ipld, opts),
125-
pull.asyncMap(prepareFile.bind(null, self, opts))
127+
pull.asyncMap(prepareFile.bind(null, self, opts)),
128+
shouldPin ? pull.asyncMap(pinFile.bind(null, self)) : identity
126129
)
127130
}
128131

src/core/components/init-assets.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,20 @@ module.exports = function addDefaultAssets (self, log, callback) {
1515

1616
pull(
1717
pull.values([initDocsPath]),
18-
pull.asyncMap((val, cb) => glob(path.join(val, '/**/*'), cb)),
18+
pull.asyncMap((val, cb) =>
19+
glob(path.join(val, '/**/*'), { nodir: true }, cb)
20+
),
1921
pull.flatten(),
20-
pull.map((element) => {
22+
pull.map(element => {
2123
const addPath = element.substring(index + 1)
22-
23-
if (fs.statSync(element).isDirectory()) { return }
24-
2524
return { path: addPath, content: file(element) }
2625
}),
27-
// Filter out directories, which are undefined from above
28-
pull.filter(Boolean),
29-
importer(self._ipld),
30-
pull.through((el) => {
31-
if (el.path === 'init-docs') {
32-
const cid = new CID(el.multihash)
26+
self.files.addPullStream(),
27+
pull.through(file => {
28+
if (file.path === 'init-docs') {
29+
const cid = new CID(file.hash)
3330
log('to get started, enter:\n')
34-
log(`\t jsipfs files cat /ipfs/${cid.toBaseEncodedString()}/readme\n`)
31+
log(`\tjsipfs files cat /ipfs/${cid.toBaseEncodedString()}/readme\n`)
3532
}
3633
}),
3734
pull.collect((err) => {

src/core/components/init.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,11 @@ module.exports = function init (self) {
8585
}
8686

8787
self.log('adding assets')
88-
const tasks = [
88+
parallel([
8989
// add empty unixfs dir object (go-ipfs assumes this exists)
90-
(cb) => self.object.new('unixfs-dir', cb)
91-
]
92-
93-
if (typeof addDefaultAssets === 'function') {
94-
tasks.push((cb) => addDefaultAssets(self, opts.log, cb))
95-
}
96-
97-
parallel(tasks, (err) => {
90+
(cb) => self.object.new('unixfs-dir', cb),
91+
(cb) => addDefaultAssets(self, opts.log, cb)
92+
], (err) => {
9893
if (err) {
9994
cb(err)
10095
} else {

0 commit comments

Comments
 (0)