Skip to content

Commit fe2f05f

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 95e74cc commit fe2f05f

File tree

17 files changed

+1416
-36
lines changed

17 files changed

+1416
-36
lines changed

src/cli/commands/files/add.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ module.exports = {
173173
type: 'boolean',
174174
default: false,
175175
describe: 'Write no output'
176+
},
177+
pin: {
178+
type: 'boolean',
179+
default: true,
180+
describe: 'Pin this object when adding'
176181
}
177182
},
178183

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
@@ -21,6 +21,7 @@ const toB58String = require('multihashes').toB58String
2121
const WRAPPER = 'wrapper/'
2222

2323
function noop () {}
24+
function identity (x) { return x }
2425

2526
function prepareFile (self, opts, file, callback) {
2627
opts = opts || {}
@@ -130,7 +131,8 @@ module.exports = function files (self) {
130131
}
131132

132133
let total = 0
133-
let prog = opts.progress || (() => {})
134+
const shouldPin = 'pin' in opts ? opts.pin : true
135+
const prog = opts.progress || noop
134136
const progress = (bytes) => {
135137
total += bytes
136138
prog(total)
@@ -141,7 +143,8 @@ module.exports = function files (self) {
141143
pull.map(normalizeContent.bind(null, opts)),
142144
pull.flatten(),
143145
importer(self._ipld, opts),
144-
pull.asyncMap(prepareFile.bind(null, self, opts))
146+
pull.asyncMap(prepareFile.bind(null, self, opts)),
147+
shouldPin ? pull.asyncMap(pinFile.bind(null, self)) : identity
145148
)
146149
}
147150

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
@@ -86,16 +86,11 @@ module.exports = function init (self) {
8686
}
8787

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

0 commit comments

Comments
 (0)