diff --git a/package.json b/package.json index 58d8337540..18b607a5d5 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "ipfs-block-service": "~0.15.1", "ipfs-http-client": "^29.0.0", "ipfs-http-response": "~0.2.1", - "ipfs-mfs": "0.9.0", + "ipfs-mfs": "~0.9.1", "ipfs-multipart": "~0.1.0", "ipfs-repo": "~0.26.1", "ipfs-unixfs": "~0.1.16", @@ -168,7 +168,6 @@ "pull-stream": "^3.6.9", "pull-stream-to-stream": "^1.3.4", "pump": "^3.0.0", - "read-pkg-up": "^4.0.0", "readable-stream": "^3.1.1", "receptacle": "^1.3.2", "stream-to-pull-stream": "^1.7.2", diff --git a/src/cli/bin.js b/src/cli/bin.js index f602d1c7a2..597f6e958f 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -3,120 +3,91 @@ 'use strict' const YargsPromise = require('yargs-promise') -const yargs = require('yargs') +const yargs = require('yargs/yargs') const updateNotifier = require('update-notifier') -const readPkgUp = require('read-pkg-up') const utils = require('./utils') const print = utils.print const mfs = require('ipfs-mfs/cli') const debug = require('debug')('ipfs:cli') +const pkg = require('../../package.json') + +async function main (args) { + const oneWeek = 1000 * 60 * 60 * 24 * 7 + updateNotifier({ pkg, updateCheckInterval: oneWeek }).notify() + + const cli = yargs(args) + .option('silent', { + desc: 'Write no output', + type: 'boolean', + default: false, + coerce: silent => { + if (silent) utils.disablePrinting() + return silent + } + }) + .option('pass', { + desc: 'Pass phrase for the keys', + type: 'string', + default: '' + }) + .epilog(utils.ipfsPathHelp) + .demandCommand(1) + .fail((msg, err, yargs) => { + if (err) { + throw err // preserve stack + } -const pkg = readPkgUp.sync({ cwd: __dirname }).pkg -updateNotifier({ - pkg, - updateCheckInterval: 1000 * 60 * 60 * 24 * 7 // 1 week -}).notify() - -const args = process.argv.slice(2) - -const cli = yargs - .option('silent', { - desc: 'Write no output', - type: 'boolean', - default: false, - coerce: ('silent', silent => { - if (silent) { - utils.disablePrinting() + if (args.length > 0) { + print(msg) } - return silent + + yargs.showHelp() }) - }) - .option('pass', { - desc: 'Pass phrase for the keys', - type: 'string', - default: '' - }) - .epilog(utils.ipfsPathHelp) - .demandCommand(1) - .fail((msg, err, yargs) => { - if (err) { - throw err // preserve stack - } - if (args.length > 0) { - print(msg) - } + // Function to get hold of a singleton ipfs instance + const getIpfs = utils.singleton(cb => utils.getIPFS(yargs(args).argv, cb)) - yargs.showHelp() - }) + // add MFS (Files API) commands + mfs(cli) -// Need to skip to avoid locking as these commands -// don't require a daemon -if (args[0] === 'daemon' || args[0] === 'init') { cli + .commandDir('commands') .help() .strict() .completion() - .command(require('./commands/daemon')) - .command(require('./commands/init')) - - new YargsPromise(cli).parse(args) - .then(({ data }) => { - if (data) print(data) - }) -} else { - // here we have to make a separate yargs instance with - // only the `api` option because we need this before doing - // the final yargs parse where the command handler is invoked.. - yargs().option('api').parse(process.argv, (err, argv, output) => { - if (err) { - throw err - } - - utils.getIPFS(argv, (err, ipfs, cleanup) => { - if (err) { - throw err - } - - // add MFS (Files API) commands - mfs(cli) - cli - .commandDir('commands') - .help() - .strict() - .completion() + let exitCode = 0 - let exitCode = 0 + try { + const { data } = await new YargsPromise(cli, { getIpfs }).parse(args) + if (data) print(data) + } catch (err) { + debug(err) - const parser = new YargsPromise(cli, { ipfs }) - parser.parse(args) - .then(({ data, argv }) => { - if (data) { - print(data) - } - }) - .catch((arg) => { - debug(arg) + // the argument can have a different shape depending on where the error came from + if (err.message || (err.error && err.error.message)) { + print(err.message || err.error.message) + } else { + print('Unknown error, please re-run the command with DEBUG=ipfs:cli to see debug output') + } - // the argument can have a different shape depending on where the error came from - if (arg.message) { - print(arg.message) - } else if (arg.error && arg.error.message) { - print(arg.error.message) - } else { - print('Unknown error, please re-run the command with DEBUG=ipfs:cli to see debug output') - } + exitCode = 1 + } finally { + // If an IPFS instance was used in the handler then clean it up here + if (getIpfs.instance) { + try { + const cleanup = getIpfs.rest[0] + await cleanup() + } catch (err) { + debug(err) + exitCode = 1 + } + } + } - exitCode = 1 - }) - .then(() => cleanup()) - .catch(() => {}) - .then(() => { - if (exitCode !== 0) { - process.exit(exitCode) - } - }) - }) - }) + if (exitCode) { + process.exit(exitCode) + } } + +main(process.argv.slice(2)) diff --git a/src/cli/commands/add.js b/src/cli/commands/add.js index 3a80ed8535..11fc84c1ee 100644 --- a/src/cli/commands/add.js +++ b/src/cli/commands/add.js @@ -145,7 +145,7 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const { ipfs } = argv + const ipfs = await argv.getIpfs() const options = { strategy: argv.trickle ? 'trickle' : 'balanced', shardSplitThreshold: argv.enableShardingExperiment diff --git a/src/cli/commands/bitswap/stat.js b/src/cli/commands/bitswap/stat.js index 14d7969226..12ef6587c5 100644 --- a/src/cli/commands/bitswap/stat.js +++ b/src/cli/commands/bitswap/stat.js @@ -17,8 +17,9 @@ module.exports = { } }, - handler ({ ipfs, cidBase, resolve }) { + handler ({ getIpfs, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const stats = await ipfs.bitswap.stat() stats.wantlist = stats.wantlist.map(k => cidToString(k['/'], { base: cidBase, upgrade: false })) stats.peers = stats.peers || [] diff --git a/src/cli/commands/bitswap/unwant.js b/src/cli/commands/bitswap/unwant.js index 53241a2b02..fb4ebb31e8 100644 --- a/src/cli/commands/bitswap/unwant.js +++ b/src/cli/commands/bitswap/unwant.js @@ -21,8 +21,9 @@ module.exports = { choices: multibase.names } }, - handler ({ ipfs, key, cidBase, resolve }) { + handler ({ getIpfs, key, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() await ipfs.bitswap.unwant(key) print(`Key ${cidToString(key, { base: cidBase, upgrade: false })} removed from wantlist`) })()) diff --git a/src/cli/commands/bitswap/wantlist.js b/src/cli/commands/bitswap/wantlist.js index 6220a2e439..b14b8d453f 100644 --- a/src/cli/commands/bitswap/wantlist.js +++ b/src/cli/commands/bitswap/wantlist.js @@ -22,8 +22,9 @@ module.exports = { } }, - handler ({ ipfs, peer, cidBase, resolve }) { + handler ({ getIpfs, peer, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const list = await ipfs.bitswap.wantlist(peer) list.Keys.forEach(k => print(cidToString(k['/'], { base: cidBase, upgrade: false }))) })()) diff --git a/src/cli/commands/block/get.js b/src/cli/commands/block/get.js index 743965af97..9f9ca96222 100644 --- a/src/cli/commands/block/get.js +++ b/src/cli/commands/block/get.js @@ -9,8 +9,9 @@ module.exports = { builder: {}, - handler ({ ipfs, key, resolve }) { + handler ({ getIpfs, key, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const block = await ipfs.block.get(key) if (block) { print(block.data, false) diff --git a/src/cli/commands/block/put.js b/src/cli/commands/block/put.js index 3705a5befc..e2e9f6a3a8 100644 --- a/src/cli/commands/block/put.js +++ b/src/cli/commands/block/put.js @@ -52,7 +52,8 @@ module.exports = { }) } - const { cid } = await argv.ipfs.block.put(data, argv) + const ipfs = await argv.getIpfs() + const { cid } = await ipfs.block.put(data, argv) print(cidToString(cid, { base: argv.cidBase })) })()) } diff --git a/src/cli/commands/block/rm.js b/src/cli/commands/block/rm.js index e626622165..d2ab47983d 100644 --- a/src/cli/commands/block/rm.js +++ b/src/cli/commands/block/rm.js @@ -9,13 +9,14 @@ module.exports = { builder: {}, - handler ({ ipfs, key, resolve }) { + handler ({ getIpfs, key, resolve }) { resolve((async () => { if (isDaemonOn()) { // TODO implement this once `js-ipfs-http-client` supports it throw new Error('rm block with daemon running is not yet implemented') } + const ipfs = await getIpfs() await ipfs.block.rm(key) print('removed ' + key) })()) diff --git a/src/cli/commands/block/stat.js b/src/cli/commands/block/stat.js index 3752aba66a..94d435c80f 100644 --- a/src/cli/commands/block/stat.js +++ b/src/cli/commands/block/stat.js @@ -17,8 +17,9 @@ module.exports = { } }, - handler ({ ipfs, key, cidBase, resolve }) { + handler ({ getIpfs, key, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const stats = await ipfs.block.stat(key) print('Key: ' + cidToString(stats.key, { base: cidBase })) print('Size: ' + stats.size) diff --git a/src/cli/commands/bootstrap/add.js b/src/cli/commands/bootstrap/add.js index 16f2e0c86c..588ed4b982 100644 --- a/src/cli/commands/bootstrap/add.js +++ b/src/cli/commands/bootstrap/add.js @@ -17,7 +17,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const list = await argv.ipfs.bootstrap.add(argv.peer, { default: argv.default }) + const ipfs = await argv.getIpfs() + const list = await ipfs.bootstrap.add(argv.peer, { default: argv.default }) list.Peers.forEach((peer) => print(peer)) })()) } diff --git a/src/cli/commands/bootstrap/list.js b/src/cli/commands/bootstrap/list.js index e164f1b2ad..27c5a57b56 100644 --- a/src/cli/commands/bootstrap/list.js +++ b/src/cli/commands/bootstrap/list.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const list = await argv.ipfs.bootstrap.list() + const ipfs = await argv.getIpfs() + const list = await ipfs.bootstrap.list() list.Peers.forEach((node) => print(node)) })()) } diff --git a/src/cli/commands/bootstrap/rm.js b/src/cli/commands/bootstrap/rm.js index 4a71eb1afd..afff097445 100644 --- a/src/cli/commands/bootstrap/rm.js +++ b/src/cli/commands/bootstrap/rm.js @@ -20,7 +20,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const list = await argv.ipfs.bootstrap.rm(argv.peer, { all: argv.all }) + const ipfs = await argv.getIpfs() + const list = await ipfs.bootstrap.rm(argv.peer, { all: argv.all }) list.Peers.forEach((peer) => print(peer)) })()) } diff --git a/src/cli/commands/cat.js b/src/cli/commands/cat.js index ebe72c29f4..e34239dc56 100644 --- a/src/cli/commands/cat.js +++ b/src/cli/commands/cat.js @@ -18,14 +18,18 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, offset, length, resolve }) { - resolve(new Promise((resolve, reject) => { - const stream = ipfs.catReadableStream(ipfsPath, { offset, length }) + handler ({ getIpfs, ipfsPath, offset, length, resolve }) { + resolve((async () => { + const ipfs = await getIpfs() - stream.on('error', reject) - stream.on('end', resolve) + return new Promise((resolve, reject) => { + const stream = ipfs.catReadableStream(ipfsPath, { offset, length }) - stream.pipe(process.stdout) - })) + stream.on('error', reject) + stream.on('end', resolve) + + stream.pipe(process.stdout) + }) + })()) } } diff --git a/src/cli/commands/config.js b/src/cli/commands/config.js index 70baeb0df1..980f716002 100644 --- a/src/cli/commands/config.js +++ b/src/cli/commands/config.js @@ -30,12 +30,13 @@ module.exports = { } argv._handled = true - const { bool, json, key } = argv + const { bool, json, key, getIpfs } = argv + const ipfs = await getIpfs() let value = argv.value if (!value) { // Get the value of a given key - value = await argv.ipfs.config.get(key) + value = await ipfs.config.get(key) if (typeof value === 'object') { print(JSON.stringify(value, null, 2)) @@ -55,7 +56,7 @@ module.exports = { } } - await argv.ipfs.config.set(key, value) + await ipfs.config.set(key, value) } })()) } diff --git a/src/cli/commands/config/edit.js b/src/cli/commands/config/edit.js index ae56467ea1..1fdc90c4d4 100644 --- a/src/cli/commands/config/edit.js +++ b/src/cli/commands/config/edit.js @@ -24,9 +24,11 @@ module.exports = { throw new Error('ENV variable $EDITOR not set') } + const ipfs = await argv.getIpfs() + async function getConfig () { try { - await argv.ipfs.config.get() + await ipfs.config.get() } catch (err) { throw new Error('failed to get the config') } @@ -76,7 +78,7 @@ module.exports = { ? Buffer.from(JSON.stringify(config)) : config try { - await argv.ipfs.config.replace(config) + await ipfs.config.replace(config) } catch (err) { throw new Error('failed to save the config') } diff --git a/src/cli/commands/config/replace.js b/src/cli/commands/config/replace.js index 11c6087674..c7579b47f8 100644 --- a/src/cli/commands/config/replace.js +++ b/src/cli/commands/config/replace.js @@ -21,7 +21,8 @@ module.exports = { const config = utils.isDaemonOn() ? filePath : JSON.parse(fs.readFileSync(filePath, 'utf8')) - return argv.ipfs.config.replace(config) + const ipfs = await argv.getIpfs() + return ipfs.config.replace(config) })()) } } diff --git a/src/cli/commands/config/show.js b/src/cli/commands/config/show.js index 43db136343..f2a566de4b 100644 --- a/src/cli/commands/config/show.js +++ b/src/cli/commands/config/show.js @@ -17,7 +17,8 @@ module.exports = { if (argv._handled) return argv._handled = true - const config = await argv.ipfs.config.get() + const ipfs = await argv.getIpfs() + const config = await ipfs.config.get() print(JSON.stringify(config, null, 4)) })()) } diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index d14dc07bb8..8afcdbe3d6 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -67,7 +67,7 @@ module.exports = { print('Daemon is ready') const cleanup = async () => { - print(`Received interrupt signal, shutting down..`) + print(`Received interrupt signal, shutting down...`) await api.stop() process.exit(0) } diff --git a/src/cli/commands/dag/get.js b/src/cli/commands/dag/get.js index 3831563f08..0fb720ca5c 100644 --- a/src/cli/commands/dag/get.js +++ b/src/cli/commands/dag/get.js @@ -26,10 +26,11 @@ module.exports = { localResolve: argv.localResolve } + const ipfs = await argv.getIpfs() let result try { - result = await argv.ipfs.dag.get(cid, path, options) + result = await ipfs.dag.get(cid, path, options) } catch (err) { return print(`dag get failed: ${err.message}`) } diff --git a/src/cli/commands/dns.js b/src/cli/commands/dns.js index 2d80479ce7..020259ef3f 100644 --- a/src/cli/commands/dns.js +++ b/src/cli/commands/dns.js @@ -12,8 +12,9 @@ module.exports = { } }, - handler ({ ipfs, domain, resolve }) { + handler ({ getIpfs, domain, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const path = await ipfs.dns(domain) print(path) })()) diff --git a/src/cli/commands/file/ls.js b/src/cli/commands/file/ls.js index b4325e88ed..93d4209247 100644 --- a/src/cli/commands/file/ls.js +++ b/src/cli/commands/file/ls.js @@ -15,7 +15,8 @@ module.exports = { // `ipfs file ls` is deprecated. See https://ipfs.io/docs/commands/#ipfs-file-ls print(`This functionality is deprecated, and will be removed in future versions. If possible, please use 'ipfs ls' instead.`) - let links = await argv.ipfs.ls(path) + const ipfs = await argv.getIpfs() + let links = await ipfs.ls(path) // Single file? Then print its hash if (links.length === 0) { diff --git a/src/cli/commands/get.js b/src/cli/commands/get.js index 5756aeb66b..6fd2f385fe 100644 --- a/src/cli/commands/get.js +++ b/src/cli/commands/get.js @@ -58,20 +58,24 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, output, resolve }) { - resolve(new Promise((resolve, reject) => { - const dir = checkArgs(ipfsPath, output) - const stream = ipfs.getReadableStream(ipfsPath) + handler ({ getIpfs, ipfsPath, output, resolve }) { + resolve((async () => { + const ipfs = await getIpfs() - print(`Saving file(s) ${ipfsPath}`) - pull( - toPull.source(stream), - pull.asyncMap(fileHandler(dir)), - pull.onEnd((err) => { - if (err) return reject(err) - resolve() - }) - ) - })) + return new Promise((resolve, reject) => { + const dir = checkArgs(ipfsPath, output) + const stream = ipfs.getReadableStream(ipfsPath) + + print(`Saving file(s) ${ipfsPath}`) + pull( + toPull.source(stream), + pull.asyncMap(fileHandler(dir)), + pull.onEnd((err) => { + if (err) return reject(err) + resolve() + }) + ) + }) + })()) } } diff --git a/src/cli/commands/id.js b/src/cli/commands/id.js index 8778203093..7f4fafb6c6 100644 --- a/src/cli/commands/id.js +++ b/src/cli/commands/id.js @@ -15,7 +15,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const id = await argv.ipfs.id() + const ipfs = await argv.getIpfs() + const id = await ipfs.id() print(JSON.stringify(id, '', 2)) })()) } diff --git a/src/cli/commands/key/export.js b/src/cli/commands/key/export.js index b59250fce6..c2a910ae1b 100644 --- a/src/cli/commands/key/export.js +++ b/src/cli/commands/key/export.js @@ -24,7 +24,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const pem = await argv.ipfs.key.export(argv.name, argv.passout) + const ipfs = await argv.getIpfs() + const pem = await ipfs.key.export(argv.name, argv.passout) if (argv.output === 'stdout') { process.stdout.write(pem) } else { diff --git a/src/cli/commands/key/gen.js b/src/cli/commands/key/gen.js index 8b321df787..8fe7b96cb7 100644 --- a/src/cli/commands/key/gen.js +++ b/src/cli/commands/key/gen.js @@ -27,7 +27,8 @@ module.exports = { type: argv.type, size: argv.size } - const key = await argv.ipfs.key.gen(argv.name, opts) + const ipfs = await argv.getIpfs() + const key = await ipfs.key.gen(argv.name, opts) print(`generated ${key.id} ${key.name}`) })()) } diff --git a/src/cli/commands/key/import.js b/src/cli/commands/key/import.js index 1bc02bf6d9..cb4dad2fb9 100644 --- a/src/cli/commands/key/import.js +++ b/src/cli/commands/key/import.js @@ -25,7 +25,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const key = await argv.ipfs.key.import(argv.name, argv.input, argv.passin) + const ipfs = await argv.getIpfs() + const key = await ipfs.key.import(argv.name, argv.input, argv.passin) print(`imported ${key.id} ${key.name}`) })()) } diff --git a/src/cli/commands/key/list.js b/src/cli/commands/key/list.js index c2ef37d2d3..cf4f71d8e0 100644 --- a/src/cli/commands/key/list.js +++ b/src/cli/commands/key/list.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const keys = await argv.ipfs.key.list() + const ipfs = await argv.getIpfs() + const keys = await ipfs.key.list() keys.forEach((ki) => print(`${ki.id} ${ki.name}`)) })()) } diff --git a/src/cli/commands/key/rename.js b/src/cli/commands/key/rename.js index 9c9a86e8b8..d9ea745f31 100644 --- a/src/cli/commands/key/rename.js +++ b/src/cli/commands/key/rename.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const res = await argv.ipfs.key.rename(argv.name, argv.newName) + const ipfs = await argv.getIpfs() + const res = await ipfs.key.rename(argv.name, argv.newName) print(`renamed to ${res.id} ${res.now}`) })()) } diff --git a/src/cli/commands/key/rm.js b/src/cli/commands/key/rm.js index dccf65323b..9daa5af677 100644 --- a/src/cli/commands/key/rm.js +++ b/src/cli/commands/key/rm.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const key = await argv.ipfs.key.rm(argv.name) + const ipfs = await argv.getIpfs() + const key = await ipfs.key.rm(argv.name) print(`${key.id} ${key.name}`) })()) } diff --git a/src/cli/commands/ls.js b/src/cli/commands/ls.js index a4f6333401..1432d36d4c 100644 --- a/src/cli/commands/ls.js +++ b/src/cli/commands/ls.js @@ -34,8 +34,9 @@ module.exports = { } }, - handler ({ ipfs, key, recursive, headers, cidBase, resolve }) { + handler ({ getIpfs, key, recursive, headers, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() let links = await ipfs.ls(key, { recursive }) links = links.map(file => Object.assign(file, { hash: cidToString(file.hash, { base: cidBase }) })) diff --git a/src/cli/commands/name/publish.js b/src/cli/commands/name/publish.js index 2cd51e4c9a..bb67db22d0 100644 --- a/src/cli/commands/name/publish.js +++ b/src/cli/commands/name/publish.js @@ -46,7 +46,8 @@ module.exports = { ttl: argv.ttl } - const result = await argv.ipfs.name.publish(argv.ipfsPath, opts) + const ipfs = await argv.getIpfs() + const result = await ipfs.name.publish(argv.ipfsPath, opts) print(`Published to ${result.name}: ${result.value}`) })()) } diff --git a/src/cli/commands/name/pubsub/cancel.js b/src/cli/commands/name/pubsub/cancel.js index eeab1146e7..52e018555e 100644 --- a/src/cli/commands/name/pubsub/cancel.js +++ b/src/cli/commands/name/pubsub/cancel.js @@ -9,7 +9,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const result = await argv.ipfs.name.pubsub.cancel(argv.name) + const ipfs = await argv.getIpfs() + const result = await ipfs.name.pubsub.cancel(argv.name) print(result.canceled ? 'canceled' : 'no subscription') })()) } diff --git a/src/cli/commands/name/pubsub/state.js b/src/cli/commands/name/pubsub/state.js index c826789d13..8d987a2f4d 100644 --- a/src/cli/commands/name/pubsub/state.js +++ b/src/cli/commands/name/pubsub/state.js @@ -9,7 +9,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const result = await argv.ipfs.name.pubsub.state() + const ipfs = await argv.getIpfs() + const result = await ipfs.name.pubsub.state() print(result.enabled ? 'enabled' : 'disabled') })()) } diff --git a/src/cli/commands/name/pubsub/subs.js b/src/cli/commands/name/pubsub/subs.js index ef6b29aeae..a802ac5829 100644 --- a/src/cli/commands/name/pubsub/subs.js +++ b/src/cli/commands/name/pubsub/subs.js @@ -9,7 +9,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const result = await argv.ipfs.name.pubsub.subs() + const ipfs = await argv.getIpfs() + const result = await ipfs.name.pubsub.subs() result.forEach(s => print(s)) })()) } diff --git a/src/cli/commands/name/resolve.js b/src/cli/commands/name/resolve.js index c93fa7ba47..9c72a2bc0c 100644 --- a/src/cli/commands/name/resolve.js +++ b/src/cli/commands/name/resolve.js @@ -27,7 +27,8 @@ module.exports = { recursive: argv.recursive } - const result = await argv.ipfs.name.resolve(argv.name, opts) + const ipfs = await argv.getIpfs() + const result = await ipfs.name.resolve(argv.name, opts) if (result && result.path) { print(result.path) diff --git a/src/cli/commands/object/data.js b/src/cli/commands/object/data.js index e0ac085f24..157d14d37a 100644 --- a/src/cli/commands/object/data.js +++ b/src/cli/commands/object/data.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const data = await argv.ipfs.object.data(argv.key, { enc: 'base58' }) + const ipfs = await argv.getIpfs() + const data = await ipfs.object.data(argv.key, { enc: 'base58' }) print(data, false) })()) } diff --git a/src/cli/commands/object/get.js b/src/cli/commands/object/get.js index b0351ddd7b..6bbaa887e0 100644 --- a/src/cli/commands/object/get.js +++ b/src/cli/commands/object/get.js @@ -21,8 +21,9 @@ module.exports = { } }, - handler ({ ipfs, key, dataEncoding, cidBase, resolve }) { + handler ({ getIpfs, key, dataEncoding, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const node = await ipfs.object.get(key, { enc: 'base58' }) let data = node.data diff --git a/src/cli/commands/object/links.js b/src/cli/commands/object/links.js index c08ecac4c8..feb93596c7 100644 --- a/src/cli/commands/object/links.js +++ b/src/cli/commands/object/links.js @@ -17,8 +17,9 @@ module.exports = { } }, - handler ({ ipfs, key, cidBase, resolve }) { + handler ({ getIpfs, key, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const links = await ipfs.object.links(key, { enc: 'base58' }) links.forEach((link) => { diff --git a/src/cli/commands/object/new.js b/src/cli/commands/object/new.js index af3b99ed07..5146a29300 100644 --- a/src/cli/commands/object/new.js +++ b/src/cli/commands/object/new.js @@ -17,8 +17,9 @@ module.exports = { } }, - handler ({ ipfs, template, cidBase, resolve }) { + handler ({ getIpfs, template, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const cid = await ipfs.object.new(template) print(cidToString(cid, { base: cidBase, upgrade: false })) })()) diff --git a/src/cli/commands/object/patch/add-link.js b/src/cli/commands/object/patch/add-link.js index ad03de7d99..069060052e 100644 --- a/src/cli/commands/object/patch/add-link.js +++ b/src/cli/commands/object/patch/add-link.js @@ -20,8 +20,9 @@ module.exports = { } }, - handler ({ ipfs, root, name, ref, cidBase, resolve }) { + handler ({ getIpfs, root, name, ref, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const nodeA = await ipfs.object.get(ref, { enc: 'base58' }) const result = await promisify(dagPB.util.cid)(nodeA) const link = new DAGLink(name, nodeA.size, result) diff --git a/src/cli/commands/object/patch/append-data.js b/src/cli/commands/object/patch/append-data.js index 606c676fc9..3be1c76778 100644 --- a/src/cli/commands/object/patch/append-data.js +++ b/src/cli/commands/object/patch/append-data.js @@ -34,7 +34,8 @@ module.exports = { }) } - const cid = await argv.ipfs.object.patch.appendData(argv.root, data, { + const ipfs = await argv.getIpfs() + const cid = await ipfs.object.patch.appendData(argv.root, data, { enc: 'base58' }) diff --git a/src/cli/commands/object/patch/rm-link.js b/src/cli/commands/object/patch/rm-link.js index ea0376d8bb..64b70037b9 100644 --- a/src/cli/commands/object/patch/rm-link.js +++ b/src/cli/commands/object/patch/rm-link.js @@ -17,8 +17,9 @@ module.exports = { } }, - handler ({ ipfs, root, link, cidBase, resolve }) { + handler ({ getIpfs, root, link, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const cid = await ipfs.object.patch.rmLink(root, { name: link }, { enc: 'base58' }) diff --git a/src/cli/commands/object/patch/set-data.js b/src/cli/commands/object/patch/set-data.js index eec0598f57..69ded31e12 100644 --- a/src/cli/commands/object/patch/set-data.js +++ b/src/cli/commands/object/patch/set-data.js @@ -34,7 +34,8 @@ module.exports = { }) } - const cid = await argv.ipfs.object.patch.setData(argv.root, data, { + const ipfs = await argv.getIpfs() + const cid = await ipfs.object.patch.setData(argv.root, data, { enc: 'base58' }) diff --git a/src/cli/commands/object/put.js b/src/cli/commands/object/put.js index 8979a79379..ba246c31e0 100644 --- a/src/cli/commands/object/put.js +++ b/src/cli/commands/object/put.js @@ -38,7 +38,8 @@ module.exports = { }) } - const cid = await argv.ipfs.object.put(data, { enc: argv.inputEnc }) + const ipfs = await argv.getIpfs() + const cid = await ipfs.object.put(data, { enc: argv.inputEnc }) print(`added ${cidToString(cid, { base: argv.cidBase, upgrade: false })}`) })()) } diff --git a/src/cli/commands/object/stat.js b/src/cli/commands/object/stat.js index f9fd80474a..63388fed2b 100644 --- a/src/cli/commands/object/stat.js +++ b/src/cli/commands/object/stat.js @@ -9,8 +9,9 @@ module.exports = { builder: {}, - handler ({ ipfs, key, cidBase, resolve }) { + handler ({ getIpfs, key, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const stats = await ipfs.object.stat(key, { enc: 'base58' }) delete stats.Hash // only for js-ipfs-http-client output Object.keys(stats).forEach((key) => print(`${key}: ${stats[key]}`)) diff --git a/src/cli/commands/pin/add.js b/src/cli/commands/pin/add.js index a37f5b0550..4c3fd5c95a 100644 --- a/src/cli/commands/pin/add.js +++ b/src/cli/commands/pin/add.js @@ -23,9 +23,10 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, recursive, cidBase, resolve }) { + handler ({ getIpfs, ipfsPath, recursive, cidBase, resolve }) { resolve((async () => { const type = recursive ? 'recursive' : 'direct' + const ipfs = await getIpfs() const results = await ipfs.pin.add(ipfsPath, { recursive }) results.forEach((res) => { print(`pinned ${cidToString(res.hash, { base: cidBase })} ${type}ly`) diff --git a/src/cli/commands/pin/ls.js b/src/cli/commands/pin/ls.js index 9aafdb8239..8a8d1cb74b 100644 --- a/src/cli/commands/pin/ls.js +++ b/src/cli/commands/pin/ls.js @@ -31,9 +31,10 @@ module.exports = { } }, - handler: ({ ipfs, ipfsPath, type, quiet, cidBase, resolve }) => { + handler: ({ getIpfs, ipfsPath, type, quiet, cidBase, resolve }) => { resolve((async () => { const paths = ipfsPath + const ipfs = await getIpfs() const results = await ipfs.pin.ls(paths, { type }) results.forEach((res) => { let line = cidToString(res.hash, { base: cidBase }) diff --git a/src/cli/commands/pin/rm.js b/src/cli/commands/pin/rm.js index 00c2f4c362..9d58d4c26e 100644 --- a/src/cli/commands/pin/rm.js +++ b/src/cli/commands/pin/rm.js @@ -23,8 +23,9 @@ module.exports = { } }, - handler: ({ ipfs, ipfsPath, recursive, cidBase, resolve }) => { + handler: ({ getIpfs, ipfsPath, recursive, cidBase, resolve }) => { resolve((async () => { + const ipfs = await getIpfs() const results = await ipfs.pin.rm(ipfsPath, { recursive }) results.forEach((res) => { print(`unpinned ${cidToString(res.hash, { base: cidBase })}`) diff --git a/src/cli/commands/ping.js b/src/cli/commands/ping.js index a66767df59..c409aedddb 100644 --- a/src/cli/commands/ping.js +++ b/src/cli/commands/ping.js @@ -17,24 +17,28 @@ module.exports = { }, handler (argv) { - argv.resolve(new Promise((resolve, reject) => { - const peerId = argv.peerId - const count = argv.count || 10 - pull( - argv.ipfs.pingPullStream(peerId, { count }), - pull.drain(({ success, time, text }) => { - // Check if it's a pong - if (success && !text) { - print(`Pong received: time=${time} ms`) - // Status response - } else { - print(text) - } - }, err => { - if (err) return reject(err) - resolve() - }) - ) - })) + argv.resolve((async () => { + const ipfs = await argv.getIpfs() + + return new Promise((resolve, reject) => { + const peerId = argv.peerId + const count = argv.count || 10 + pull( + ipfs.pingPullStream(peerId, { count }), + pull.drain(({ success, time, text }) => { + // Check if it's a pong + if (success && !text) { + print(`Pong received: time=${time} ms`) + // Status response + } else { + print(text) + } + }, err => { + if (err) return reject(err) + resolve() + }) + ) + }) + })()) } } diff --git a/src/cli/commands/pubsub/ls.js b/src/cli/commands/pubsub/ls.js index 18a488ee88..12ed1a5b13 100644 --- a/src/cli/commands/pubsub/ls.js +++ b/src/cli/commands/pubsub/ls.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const subscriptions = await argv.ipfs.pubsub.ls() + const ipfs = await argv.getIpfs() + const subscriptions = await ipfs.pubsub.ls() subscriptions.forEach(sub => print(sub)) })()) } diff --git a/src/cli/commands/pubsub/peers.js b/src/cli/commands/pubsub/peers.js index 21eb57b01b..6e68d83bfb 100644 --- a/src/cli/commands/pubsub/peers.js +++ b/src/cli/commands/pubsub/peers.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const peers = await argv.ipfs.pubsub.peers(argv.topic) + const ipfs = await argv.getIpfs() + const peers = await ipfs.pubsub.peers(argv.topic) peers.forEach(peer => print(peer)) })()) } diff --git a/src/cli/commands/pubsub/pub.js b/src/cli/commands/pubsub/pub.js index 5cf96a3c57..59d0e7077d 100644 --- a/src/cli/commands/pubsub/pub.js +++ b/src/cli/commands/pubsub/pub.js @@ -10,7 +10,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { const data = Buffer.from(String(argv.data)) - await argv.ipfs.pubsub.publish(argv.topic, data) + const ipfs = await argv.getIpfs() + await ipfs.pubsub.publish(argv.topic, data) })()) } } diff --git a/src/cli/commands/pubsub/sub.js b/src/cli/commands/pubsub/sub.js index a35bbf2a44..4d2da8dc81 100644 --- a/src/cli/commands/pubsub/sub.js +++ b/src/cli/commands/pubsub/sub.js @@ -12,7 +12,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { const handler = msg => print(msg.data.toString()) - await argv.ipfs.pubsub.subscribe(argv.topic, handler) + const ipfs = await argv.getIpfs() + await ipfs.pubsub.subscribe(argv.topic, handler) })()) } } diff --git a/src/cli/commands/repo/gc.js b/src/cli/commands/repo/gc.js index 13d11dc630..ec3b547e93 100644 --- a/src/cli/commands/repo/gc.js +++ b/src/cli/commands/repo/gc.js @@ -9,7 +9,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - await argv.ipfs.repo.gc() + const ipfs = await argv.getIpfs() + await ipfs.repo.gc() })()) } } diff --git a/src/cli/commands/repo/stat.js b/src/cli/commands/repo/stat.js index 8a262eb027..660a7ff444 100644 --- a/src/cli/commands/repo/stat.js +++ b/src/cli/commands/repo/stat.js @@ -16,7 +16,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const stats = await argv.ipfs.repo.stat({ human: argv.human }) + const ipfs = await argv.getIpfs() + const stats = await ipfs.repo.stat({ human: argv.human }) print(`repo status number of objects: ${stats.numObjects} repo size: ${stats.repoSize} diff --git a/src/cli/commands/repo/version.js b/src/cli/commands/repo/version.js index 921cf0bb1e..3d52c684b3 100644 --- a/src/cli/commands/repo/version.js +++ b/src/cli/commands/repo/version.js @@ -11,7 +11,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const version = await argv.ipfs.repo.version() + const ipfs = await argv.getIpfs() + const version = await ipfs.repo.version() print(version) })()) } diff --git a/src/cli/commands/resolve.js b/src/cli/commands/resolve.js index 61668b5d28..086966c7ca 100644 --- a/src/cli/commands/resolve.js +++ b/src/cli/commands/resolve.js @@ -21,8 +21,9 @@ module.exports = { } }, - handler ({ ipfs, name, recursive, cidBase, resolve }) { + handler ({ getIpfs, name, recursive, cidBase, resolve }) { resolve((async () => { + const ipfs = await getIpfs() const res = await ipfs.resolve(name, { recursive, cidBase }) print(res) })()) diff --git a/src/cli/commands/shutdown.js b/src/cli/commands/shutdown.js index de6dc0c6d3..b9e741aefd 100644 --- a/src/cli/commands/shutdown.js +++ b/src/cli/commands/shutdown.js @@ -8,6 +8,9 @@ module.exports = { builder: {}, handler (argv) { - argv.resolve(argv.ipfs.shutdown()) + argv.resolve((async () => { + const ipfs = await argv.getIpfs() + return ipfs.shutdown() + })()) } } diff --git a/src/cli/commands/stats/bw.js b/src/cli/commands/stats/bw.js index 45e7fbcb86..a61e8fca85 100644 --- a/src/cli/commands/stats/bw.js +++ b/src/cli/commands/stats/bw.js @@ -27,24 +27,28 @@ module.exports = { } }, - handler ({ ipfs, peer, proto, poll, interval, resolve }) { - resolve(new Promise((resolve, reject) => { - const stream = ipfs.stats.bwPullStream({ peer, proto, poll, interval }) + handler ({ getIpfs, peer, proto, poll, interval, resolve }) { + resolve((async () => { + const ipfs = await getIpfs() - const onChunk = chunk => { - print(`bandwidth status + return new Promise((resolve, reject) => { + const stream = ipfs.stats.bwPullStream({ peer, proto, poll, interval }) + + const onChunk = chunk => { + print(`bandwidth status total in: ${chunk.totalIn}B total out: ${chunk.totalOut}B rate in: ${chunk.rateIn}B/s rate out: ${chunk.rateOut}B/s`) - } + } - const onEnd = err => { - if (err) return reject(err) - resolve() - } + const onEnd = err => { + if (err) return reject(err) + resolve() + } - pull(stream, pull.drain(onChunk, onEnd)) - })) + pull(stream, pull.drain(onChunk, onEnd)) + }) + })()) } } diff --git a/src/cli/commands/stats/repo.js b/src/cli/commands/stats/repo.js index 1c7a42c0ed..343b8d9617 100644 --- a/src/cli/commands/stats/repo.js +++ b/src/cli/commands/stats/repo.js @@ -16,7 +16,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const stats = await argv.ipfs.stats.repo({ human: argv.human }) + const ipfs = await argv.getIpfs() + const stats = await ipfs.stats.repo({ human: argv.human }) print(`repo status number of objects: ${stats.numObjects} repo size: ${stats.repoSize} diff --git a/src/cli/commands/swarm/addrs.js b/src/cli/commands/swarm/addrs.js index d5bbe9cf2a..aef6704416 100644 --- a/src/cli/commands/swarm/addrs.js +++ b/src/cli/commands/swarm/addrs.js @@ -14,7 +14,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const res = await argv.ipfs.swarm.addrs() + const ipfs = await argv.getIpfs() + const res = await ipfs.swarm.addrs() res.forEach((peer) => { const count = peer.multiaddrs.size print(`${peer.id.toB58String()} (${count})`) diff --git a/src/cli/commands/swarm/addrs/local.js b/src/cli/commands/swarm/addrs/local.js index b321fea6b8..d2a6e604fc 100644 --- a/src/cli/commands/swarm/addrs/local.js +++ b/src/cli/commands/swarm/addrs/local.js @@ -18,7 +18,8 @@ module.exports = { if (!utils.isDaemonOn()) { throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } - const res = await argv.ipfs.swarm.localAddrs() + const ipfs = await argv.getIpfs() + const res = await ipfs.swarm.localAddrs() res.forEach(addr => print(addr.toString())) })()) } diff --git a/src/cli/commands/swarm/connect.js b/src/cli/commands/swarm/connect.js index b1f26eeeee..0bf9dad939 100644 --- a/src/cli/commands/swarm/connect.js +++ b/src/cli/commands/swarm/connect.js @@ -15,7 +15,8 @@ module.exports = { if (!utils.isDaemonOn()) { throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } - const res = await argv.ipfs.swarm.connect(argv.address) + const ipfs = await argv.getIpfs() + const res = await ipfs.swarm.connect(argv.address) print(res.Strings[0]) })()) } diff --git a/src/cli/commands/swarm/disconnect.js b/src/cli/commands/swarm/disconnect.js index 36019177a3..d3c0775be4 100644 --- a/src/cli/commands/swarm/disconnect.js +++ b/src/cli/commands/swarm/disconnect.js @@ -15,7 +15,8 @@ module.exports = { if (!utils.isDaemonOn()) { throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } - const res = await argv.ipfs.swarm.disconnect(argv.address) + const ipfs = await argv.getIpfs() + const res = await ipfs.swarm.disconnect(argv.address) print(res.Strings[0]) })()) } diff --git a/src/cli/commands/swarm/peers.js b/src/cli/commands/swarm/peers.js index dc5ca9f3cd..db88d5ea9f 100644 --- a/src/cli/commands/swarm/peers.js +++ b/src/cli/commands/swarm/peers.js @@ -18,7 +18,8 @@ module.exports = { throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } - const result = await argv.ipfs.swarm.peers() + const ipfs = await argv.getIpfs() + const result = await ipfs.swarm.peers() result.forEach((item) => { let ma = multiaddr(item.addr.toString()) diff --git a/src/cli/commands/version.js b/src/cli/commands/version.js index e5078bc95f..04f74860e5 100644 --- a/src/cli/commands/version.js +++ b/src/cli/commands/version.js @@ -34,7 +34,8 @@ module.exports = { handler (argv) { argv.resolve((async () => { - const data = await argv.ipfs.version() + const ipfs = await argv.getIpfs() + const data = await ipfs.version() const withCommit = argv.all || argv.commit const parsedVersion = `${data.version}${withCommit ? `-${data.commit}` : ''}` diff --git a/src/cli/utils.js b/src/cli/utils.js index 46777125e5..81e71b9ab6 100644 --- a/src/cli/utils.js +++ b/src/cli/utils.js @@ -119,3 +119,18 @@ exports.rightpad = (val, n) => { exports.ipfsPathHelp = 'ipfs uses a repository in the local file system. By default, the repo is ' + 'located at ~/.jsipfs. To change the repo location, set the $IPFS_PATH environment variable:\n\n' + 'export IPFS_PATH=/path/to/ipfsrepo\n' + +exports.singleton = create => { + const requests = [] + const getter = promisify(cb => { + if (getter.instance) return cb(null, getter.instance, ...getter.rest) + requests.push(cb) + if (requests.length > 1) return + create((err, instance, ...rest) => { + getter.instance = instance + getter.rest = rest + while (requests.length) requests.pop()(err, instance, ...rest) + }) + }) + return getter +}