From 6066c97d08cdacb9f7f7034f8565c687f2610810 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 21 Jan 2019 14:24:13 +0000 Subject: [PATCH] fix: race condition causing Database is not open error (#1834) [`cleanup`](https://github.com/ipfs/js-ipfs/blob/7d9b006d0b0542651cbaa540d5f22a0112ae09bd/src/cli/bin.js#L109) closes the DB but `yargs-promise` does not wait for async stuff in the command handler to finish, and executes that promise chain immediately after the handler is executed. So it's a race condition. In windows, _sometimes_, the database is closed before the async stuff from the handler completes. This PR changes the CLI command handlers to always pass a promise to `resolve` function that `yargs-promise` adds to the context (`argv`). This makes `yargs-promise` wait for it to be resolved before continuing the promise chain and closing the DB. Since I had to edit all of the commands to make them use the `resolve` function and introduce promises, I decided to take the opportunity to refactor the CLI commands to use async/await. It should help towards https://github.com/ipfs/js-ipfs/issues/1670. License: MIT Signed-off-by: Alan Shaw --- src/cli/bin.js | 6 +- src/cli/commands/add.js | 129 ++++++++++--------- src/cli/commands/bitswap/stat.js | 11 +- src/cli/commands/bitswap/unwant.js | 10 +- src/cli/commands/bitswap/wantlist.js | 10 +- src/cli/commands/block/get.js | 11 +- src/cli/commands/block/put.js | 37 +++--- src/cli/commands/block/rm.js | 17 +-- src/cli/commands/block/stat.js | 11 +- src/cli/commands/bootstrap/add.js | 11 +- src/cli/commands/bootstrap/list.js | 9 +- src/cli/commands/bootstrap/rm.js | 11 +- src/cli/commands/cat.js | 13 +- src/cli/commands/config.js | 56 ++++---- src/cli/commands/config/edit.js | 123 ++++++++---------- src/cli/commands/config/replace.js | 18 ++- src/cli/commands/config/show.js | 13 +- src/cli/commands/daemon.js | 50 +++---- src/cli/commands/dag/get.js | 24 ++-- src/cli/commands/dns.js | 11 +- src/cli/commands/file/ls.js | 15 +-- src/cli/commands/get.js | 28 ++-- src/cli/commands/id.js | 10 +- src/cli/commands/init.js | 42 +++--- src/cli/commands/key/export.js | 8 +- src/cli/commands/key/gen.js | 14 +- src/cli/commands/key/import.js | 8 +- src/cli/commands/key/list.js | 8 +- src/cli/commands/key/rename.js | 8 +- src/cli/commands/key/rm.js | 8 +- src/cli/commands/ls.js | 10 +- src/cli/commands/name/publish.js | 31 ++--- src/cli/commands/name/pubsub/cancel.js | 11 +- src/cli/commands/name/pubsub/state.js | 11 +- src/cli/commands/name/pubsub/subs.js | 13 +- src/cli/commands/name/resolve.js | 16 +-- src/cli/commands/object/data.js | 11 +- src/cli/commands/object/get.js | 11 +- src/cli/commands/object/links.js | 13 +- src/cli/commands/object/new.js | 11 +- src/cli/commands/object/patch/add-link.js | 33 ++--- src/cli/commands/object/patch/append-data.js | 40 +++--- src/cli/commands/object/patch/rm-link.js | 14 +- src/cli/commands/object/patch/set-data.js | 40 +++--- src/cli/commands/object/put.js | 36 +++--- src/cli/commands/object/stat.js | 16 +-- src/cli/commands/pin/add.js | 11 +- src/cli/commands/pin/ls.js | 11 +- src/cli/commands/pin/rm.js | 8 +- src/cli/commands/ping.js | 33 +++-- src/cli/commands/pubsub/ls.js | 13 +- src/cli/commands/pubsub/peers.js | 11 +- src/cli/commands/pubsub/pub.js | 11 +- src/cli/commands/pubsub/sub.js | 13 +- src/cli/commands/repo/gc.js | 8 +- src/cli/commands/repo/stat.js | 9 +- src/cli/commands/repo/version.js | 9 +- src/cli/commands/resolve.js | 9 +- src/cli/commands/shutdown.js | 6 +- src/cli/commands/stats/bw.js | 20 ++- src/cli/commands/stats/repo.js | 9 +- src/cli/commands/swarm/addrs.js | 9 +- src/cli/commands/swarm/addrs/local.js | 18 +-- src/cli/commands/swarm/connect.js | 14 +- src/cli/commands/swarm/disconnect.js | 14 +- src/cli/commands/swarm/peers.js | 14 +- src/cli/commands/version.js | 8 +- 67 files changed, 563 insertions(+), 742 deletions(-) diff --git a/src/cli/bin.js b/src/cli/bin.js index 7878a05978..f602d1c7a2 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -59,7 +59,11 @@ if (args[0] === 'daemon' || args[0] === 'init') { .completion() .command(require('./commands/daemon')) .command(require('./commands/init')) - .parse(args) + + 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 diff --git a/src/cli/commands/add.js b/src/cli/commands/add.js index 1ad89f618e..3a80ed8535 100644 --- a/src/cli/commands/add.js +++ b/src/cli/commands/add.js @@ -2,9 +2,9 @@ const sortBy = require('lodash/sortBy') const pull = require('pull-stream') -const getFolderSize = require('get-folder-size') +const promisify = require('promisify-es6') +const getFolderSize = promisify(require('get-folder-size')) const byteman = require('byteman') -const reduce = require('async/reduce') const mh = require('multihashes') const multibase = require('multibase') const toPull = require('stream-to-pull-stream') @@ -12,42 +12,46 @@ const { print, isDaemonOn, createProgressBar } = require('../utils') const { cidToString } = require('../../utils/cid') const globSource = require('../../utils/files/glob-source') -function getTotalBytes (paths, cb) { - reduce(paths, 0, (total, path, cb) => { - getFolderSize(path, (err, size) => { - if (err) return cb(err) - cb(null, total + size) - }) - }, cb) +async function getTotalBytes (paths, cb) { + const sizes = await Promise.all(paths.map(p => getFolderSize(p))) + return sizes.reduce((total, size) => total + size, 0) } function addPipeline (source, addStream, options) { - pull( - source, - addStream, - pull.collect((err, added) => { - if (err) { - // Tweak the error message and add more relevant infor for the CLI - if (err.code === 'ERR_DIR_NON_RECURSIVE') { - err.message = `'${err.path}' is a directory, use the '-r' flag to specify directories` + return new Promise((resolve, reject) => { + pull( + source, + addStream, + pull.collect((err, added) => { + if (err) { + // Tweak the error message and add more relevant infor for the CLI + if (err.code === 'ERR_DIR_NON_RECURSIVE') { + err.message = `'${err.path}' is a directory, use the '-r' flag to specify directories` + } + return reject(err) + } + + if (options.silent) return resolve() + + if (options.quieter) { + print(added.pop().hash) + return resolve() } - throw err - } - if (options.silent) return - if (options.quieter) return print(added.pop().hash) - - sortBy(added, 'path') - .reverse() - .map((file) => { - const log = options.quiet ? [] : ['added'] - log.push(cidToString(file.hash, { base: options.cidBase })) - if (!options.quiet && file.path.length > 0) log.push(file.path) - return log.join(' ') - }) - .forEach((msg) => print(msg)) - }) - ) + sortBy(added, 'path') + .reverse() + .map((file) => { + const log = options.quiet ? [] : ['added'] + log.push(cidToString(file.hash, { base: options.cidBase })) + if (!options.quiet && file.path.length > 0) log.push(file.path) + return log.join(' ') + }) + .forEach((msg) => print(msg)) + + resolve() + }) + ) + }) } module.exports = { @@ -140,46 +144,45 @@ module.exports = { }, handler (argv) { - const { ipfs } = argv - const options = { - strategy: argv.trickle ? 'trickle' : 'balanced', - shardSplitThreshold: argv.enableShardingExperiment - ? argv.shardSplitThreshold - : Infinity, - cidVersion: argv.cidVersion, - rawLeaves: argv.rawLeaves, - onlyHash: argv.onlyHash, - hashAlg: argv.hash, - wrapWithDirectory: argv.wrapWithDirectory, - pin: argv.pin, - chunker: argv.chunker - } - - if (options.enableShardingExperiment && isDaemonOn()) { - throw new Error('Error: Enabling the sharding experiment should be done on the daemon') - } + argv.resolve((async () => { + const { ipfs } = argv + const options = { + strategy: argv.trickle ? 'trickle' : 'balanced', + shardSplitThreshold: argv.enableShardingExperiment + ? argv.shardSplitThreshold + : Infinity, + cidVersion: argv.cidVersion, + rawLeaves: argv.rawLeaves, + onlyHash: argv.onlyHash, + hashAlg: argv.hash, + wrapWithDirectory: argv.wrapWithDirectory, + pin: argv.pin, + chunker: argv.chunker + } - const source = argv.file - ? globSource(...argv.file, { recursive: argv.recursive }) - : toPull.source(process.stdin) // Pipe directly to ipfs.add + if (options.enableShardingExperiment && isDaemonOn()) { + throw new Error('Error: Enabling the sharding experiment should be done on the daemon') + } - const adder = ipfs.addPullStream(options) + const source = argv.file + ? globSource(...argv.file, { recursive: argv.recursive }) + : toPull.source(process.stdin) // Pipe directly to ipfs.add - // No progress or piping directly to ipfs.add: no need to getTotalBytes - if (!argv.progress || !argv.file) { - return addPipeline(source, adder, argv) - } + const adder = ipfs.addPullStream(options) - getTotalBytes(argv.file, (err, totalBytes) => { - if (err) throw err + // No progress or piping directly to ipfs.add: no need to getTotalBytes + if (!argv.progress || !argv.file) { + return addPipeline(source, adder, argv) + } + const totalBytes = await getTotalBytes(argv.file) const bar = createProgressBar(totalBytes) options.progress = byteLength => { bar.update(byteLength / totalBytes, { progress: byteman(byteLength, 2, 'MB') }) } - addPipeline(source, adder, argv) - }) + return addPipeline(source, adder, argv) + })()) } } diff --git a/src/cli/commands/bitswap/stat.js b/src/cli/commands/bitswap/stat.js index 94060701eb..14d7969226 100644 --- a/src/cli/commands/bitswap/stat.js +++ b/src/cli/commands/bitswap/stat.js @@ -17,12 +17,9 @@ module.exports = { } }, - handler ({ ipfs, cidBase }) { - ipfs.bitswap.stat((err, stats) => { - if (err) { - throw err - } - + handler ({ ipfs, cidBase, resolve }) { + resolve((async () => { + const stats = await ipfs.bitswap.stat() stats.wantlist = stats.wantlist.map(k => cidToString(k['/'], { base: cidBase, upgrade: false })) stats.peers = stats.peers || [] @@ -34,6 +31,6 @@ module.exports = { ${stats.wantlist.join('\n ')} partners [${stats.peers.length}] ${stats.peers.join('\n ')}`) - }) + })()) } } diff --git a/src/cli/commands/bitswap/unwant.js b/src/cli/commands/bitswap/unwant.js index af0c77296b..53241a2b02 100644 --- a/src/cli/commands/bitswap/unwant.js +++ b/src/cli/commands/bitswap/unwant.js @@ -21,12 +21,10 @@ module.exports = { choices: multibase.names } }, - handler ({ ipfs, key, cidBase }) { - ipfs.bitswap.unwant(key, (err) => { - if (err) { - throw err - } + handler ({ ipfs, key, cidBase, resolve }) { + resolve((async () => { + 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 7c8e15d1a2..6220a2e439 100644 --- a/src/cli/commands/bitswap/wantlist.js +++ b/src/cli/commands/bitswap/wantlist.js @@ -22,12 +22,10 @@ module.exports = { } }, - handler ({ ipfs, peer, cidBase }) { - ipfs.bitswap.wantlist(peer, (err, list) => { - if (err) { - throw err - } + handler ({ ipfs, peer, cidBase, resolve }) { + resolve((async () => { + 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 f5c32fe0e1..743965af97 100644 --- a/src/cli/commands/block/get.js +++ b/src/cli/commands/block/get.js @@ -9,17 +9,14 @@ module.exports = { builder: {}, - handler ({ ipfs, key }) { - ipfs.block.get(key, (err, block) => { - if (err) { - throw err - } - + handler ({ ipfs, key, resolve }) { + resolve((async () => { + const block = await ipfs.block.get(key) if (block) { print(block.data, false) } else { print('Block was unwanted before it could be remotely retrieved') } - }) + })()) } } diff --git a/src/cli/commands/block/put.js b/src/cli/commands/block/put.js index a87204b46e..3705a5befc 100644 --- a/src/cli/commands/block/put.js +++ b/src/cli/commands/block/put.js @@ -3,20 +3,10 @@ const bl = require('bl') const fs = require('fs') const multibase = require('multibase') +const promisify = require('promisify-es6') const { print } = require('../../utils') const { cidToString } = require('../../../utils/cid') -function addBlock (data, opts) { - const ipfs = opts.ipfs - - ipfs.block.put(data, opts, (err, block) => { - if (err) { - throw err - } - print(cidToString(block.cid, { base: opts.cidBase })) - }) -} - module.exports = { command: 'put [block]', @@ -48,17 +38,22 @@ module.exports = { }, handler (argv) { - if (argv.block) { - const buf = fs.readFileSync(argv.block) - return addBlock(buf, argv) - } - - process.stdin.pipe(bl((err, input) => { - if (err) { - throw err + argv.resolve((async () => { + let data + + if (argv.block) { + data = await promisify(fs.readFile)(argv.block) + } else { + data = await new Promise((resolve, reject) => { + process.stdin.pipe(bl((err, input) => { + if (err) return reject(err) + resolve(input) + })) + }) } - addBlock(input, argv) - })) + const { cid } = await argv.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 7b8a27db60..e626622165 100644 --- a/src/cli/commands/block/rm.js +++ b/src/cli/commands/block/rm.js @@ -9,18 +9,15 @@ module.exports = { builder: {}, - handler ({ ipfs, key }) { - if (isDaemonOn()) { - // TODO implement this once `js-ipfs-http-client` supports it - throw new Error('rm block with daemon running is not yet implemented') - } - - ipfs.block.rm(key, (err) => { - if (err) { - throw err + handler ({ ipfs, 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') } + 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 9c9bdb5e21..3752aba66a 100644 --- a/src/cli/commands/block/stat.js +++ b/src/cli/commands/block/stat.js @@ -17,14 +17,11 @@ module.exports = { } }, - handler ({ ipfs, key, cidBase }) { - ipfs.block.stat(key, (err, stats) => { - if (err) { - throw err - } - + handler ({ ipfs, key, cidBase, resolve }) { + resolve((async () => { + 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 ebab4736c9..16f2e0c86c 100644 --- a/src/cli/commands/bootstrap/add.js +++ b/src/cli/commands/bootstrap/add.js @@ -16,14 +16,9 @@ module.exports = { }, handler (argv) { - argv.ipfs.bootstrap.add(argv.peer, { - default: argv.default - }, (err, list) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const list = await argv.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 4a9a76baee..e164f1b2ad 100644 --- a/src/cli/commands/bootstrap/list.js +++ b/src/cli/commands/bootstrap/list.js @@ -10,12 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.bootstrap.list((err, list) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const list = await argv.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 cb8e398cc3..4a71eb1afd 100644 --- a/src/cli/commands/bootstrap/rm.js +++ b/src/cli/commands/bootstrap/rm.js @@ -19,14 +19,9 @@ module.exports = { }, handler (argv) { - argv.ipfs.bootstrap.rm(argv.peer, { - all: argv.all - }, (err, list) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const list = await argv.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 ec63896ea0..ebe72c29f4 100644 --- a/src/cli/commands/cat.js +++ b/src/cli/commands/cat.js @@ -18,13 +18,14 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, offset, length }) { - const stream = ipfs.catReadableStream(ipfsPath, { offset, length }) + handler ({ ipfs, ipfsPath, offset, length, resolve }) { + resolve(new Promise((resolve, reject) => { + const stream = ipfs.catReadableStream(ipfsPath, { offset, length }) - stream.once('error', (err) => { - throw err - }) + stream.on('error', reject) + stream.on('end', resolve) - stream.pipe(process.stdout) + stream.pipe(process.stdout) + })) } } diff --git a/src/cli/commands/config.js b/src/cli/commands/config.js index a8741633c6..70baeb0df1 100644 --- a/src/cli/commands/config.js +++ b/src/cli/commands/config.js @@ -24,47 +24,39 @@ module.exports = { }, handler (argv) { - if (argv._handled) { - return - } - argv._handled = true + argv.resolve((async () => { + if (argv._handled) { + return + } + argv._handled = true - const bool = argv.bool - const json = argv.json - const key = argv.key - let value = argv.value + const { bool, json, key } = argv + let value = argv.value - if (!value) { - // Get the value of a given key - argv.ipfs.config.get(key, (err, value) => { - if (err) { - throw new Error('failed to read the config') - } + if (!value) { + // Get the value of a given key + value = await argv.ipfs.config.get(key) if (typeof value === 'object') { print(JSON.stringify(value, null, 2)) } else { print(value) } - }) - } else { - // Set the new value of a given key - - if (bool) { - value = (value === 'true') - } else if (json) { - try { - value = JSON.parse(value) - } catch (err) { - throw new Error('invalid JSON provided') + } else { + // Set the new value of a given key + + if (bool) { + value = (value === 'true') + } else if (json) { + try { + value = JSON.parse(value) + } catch (err) { + throw new Error('invalid JSON provided') + } } - } - argv.ipfs.config.set(key, value, (err) => { - if (err) { - throw err - } - }) - } + await argv.ipfs.config.set(key, value) + } + })()) } } diff --git a/src/cli/commands/config/edit.js b/src/cli/commands/config/edit.js index 1238e4b4ad..ae56467ea1 100644 --- a/src/cli/commands/config/edit.js +++ b/src/cli/commands/config/edit.js @@ -3,8 +3,7 @@ const spawn = require('child_process').spawn const fs = require('fs') const temp = require('temp') -const waterfall = require('async/waterfall') - +const promisify = require('promisify-es6') const utils = require('../../utils') module.exports = { @@ -15,93 +14,79 @@ module.exports = { builder: {}, handler (argv) { - if (argv._handled) return - argv._handled = true + argv.resolve((async () => { + if (argv._handled) return + argv._handled = true - const editor = process.env.EDITOR + const editor = process.env.EDITOR - if (!editor) { - throw new Error('ENV variable $EDITOR not set') - } + if (!editor) { + throw new Error('ENV variable $EDITOR not set') + } - function getConfig (next) { - argv.ipfs.config.get((err, config) => { - if (err) { - next(new Error('failed to get the config')) + async function getConfig () { + try { + await argv.ipfs.config.get() + } catch (err) { + throw new Error('failed to get the config') } + } - next(null, config) - }) - } + async function saveTempConfig (config) { + const path = temp.path({ prefix: 'ipfs-config' }) - function saveTempConfig (config, next) { - temp.open('ipfs-config', (err, info) => { - if (err) { - next(new Error('failed to open the config')) + try { + await promisify(fs.writeFile)(JSON.stringify(config, null, 2)) + } catch (err) { + throw new Error('failed to write the config to a temporary file') } - fs.write(info.fd, JSON.stringify(config, null, 2)) - fs.close(info.fd, (err) => { - if (err) { - next(new Error('failed to open the config')) - } - }) - - next(null, info.path) - }) - } + return path + } - function openEditor (path, next) { - const child = spawn(editor, [path], { - stdio: 'inherit' - }) + function openEditor (path) { + return new Promise((resolve, reject) => { + const child = spawn(editor, [path], { stdio: 'inherit' }) - child.on('exit', (err, code) => { - if (err) { - throw new Error('error on the editor') - } + child.on('exit', (err, code) => { + if (err) return reject(new Error('error on the editor')) + resolve(path) + }) + }) + } - next(null, path) - }) - } + async function readTempConfig (path) { + let data - function readTempConfig (path, next) { - fs.readFile(path, 'utf8', (err, data) => { - if (err) { - next(new Error('failed to get the updated config')) + try { + data = await promisify(fs.readFile)(path, 'utf8') + } catch (err) { + throw new Error('failed to get the updated config') } try { - next(null, JSON.parse(data)) + return JSON.parse(data) } catch (err) { - next(new Error(`failed to parse the updated config "${err.message}"`)) + throw new Error(`failed to parse the updated config "${err.message}"`) } - }) - } + } - function saveConfig (config, next) { - config = utils.isDaemonOn() - ? Buffer.from(JSON.stringify(config)) : config + async function saveConfig (config) { + config = utils.isDaemonOn() + ? Buffer.from(JSON.stringify(config)) : config - argv.ipfs.config.replace(config, (err) => { - if (err) { - next(new Error('failed to save the config')) + try { + await argv.ipfs.config.replace(config) + } catch (err) { + throw new Error('failed to save the config') } - - next() - }) - } - - waterfall([ - getConfig, - saveTempConfig, - openEditor, - readTempConfig, - saveConfig - ], (err) => { - if (err) { - throw err } - }) + + const config = await getConfig() + const tmpPath = saveTempConfig(config) + await openEditor(tmpPath) + const updatedConfig = await readTempConfig(tmpPath) + await saveConfig(updatedConfig) + })()) } } diff --git a/src/cli/commands/config/replace.js b/src/cli/commands/config/replace.js index eef322aaf3..11c6087674 100644 --- a/src/cli/commands/config/replace.js +++ b/src/cli/commands/config/replace.js @@ -12,18 +12,16 @@ module.exports = { builder: {}, handler (argv) { - if (argv._handled) return - argv._handled = true + argv.resolve((async () => { + if (argv._handled) return + argv._handled = true - const filePath = path.resolve(process.cwd(), argv.file) + const filePath = path.resolve(process.cwd(), argv.file) - const config = utils.isDaemonOn() - ? filePath : JSON.parse(fs.readFileSync(filePath, 'utf8')) + const config = utils.isDaemonOn() + ? filePath : JSON.parse(fs.readFileSync(filePath, 'utf8')) - argv.ipfs.config.replace(config, (err) => { - if (err) { - throw err - } - }) + return argv.ipfs.config.replace(config) + })()) } } diff --git a/src/cli/commands/config/show.js b/src/cli/commands/config/show.js index be3730602b..43db136343 100644 --- a/src/cli/commands/config/show.js +++ b/src/cli/commands/config/show.js @@ -13,15 +13,12 @@ module.exports = { builder: {}, handler (argv) { - if (argv._handled) return - argv._handled = true - - argv.ipfs.config.get((err, config) => { - if (err) { - throw err - } + argv.resolve((async () => { + if (argv._handled) return + argv._handled = true + const config = await argv.ipfs.config.get() print(JSON.stringify(config, null, 4)) - }) + })()) } } diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index e71d3a5d38..6f0a3fb406 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -1,5 +1,6 @@ 'use strict' +const promisify = require('promisify-es6') const utils = require('../utils') const print = utils.print @@ -36,39 +37,38 @@ module.exports = { }, handler (argv) { - print('Initializing IPFS daemon...') + argv.resolve((async () => { + print('Initializing IPFS daemon...') - const repoPath = utils.getRepoPath() + const repoPath = utils.getRepoPath() - // Required inline to reduce startup time - const HttpAPI = require('../../http') - httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv) + // Required inline to reduce startup time + const HttpAPI = require('../../http') + httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv) - httpAPI.start((err) => { - if (err && err.code === 'ENOENT' && err.message.match(/uninitialized/i)) { - print('Error: no initialized ipfs repo found in ' + repoPath) - print('please run: jsipfs init') - process.exit(1) - } - if (err) { + try { + await promisify(httpAPI.start)() + } catch (err) { + if (err.code === 'ENOENT' && err.message.match(/uninitialized/i)) { + print('Error: no initialized ipfs repo found in ' + repoPath) + print('please run: jsipfs init') + process.exit(1) + } throw err } + print('Daemon is ready') - }) - const cleanup = () => { - print(`Received interrupt signal, shutting down..`) - httpAPI.stop((err) => { - if (err) { - throw err - } + const cleanup = async () => { + print(`Received interrupt signal, shutting down..`) + await promisify(httpAPI.stop)() process.exit(0) - }) - } + } - // listen for graceful termination - process.on('SIGTERM', cleanup) - process.on('SIGINT', cleanup) - process.on('SIGHUP', cleanup) + // listen for graceful termination + process.on('SIGTERM', cleanup) + process.on('SIGINT', cleanup) + process.on('SIGHUP', cleanup) + })()) } } diff --git a/src/cli/commands/dag/get.js b/src/cli/commands/dag/get.js index 6088d2eb34..3831563f08 100644 --- a/src/cli/commands/dag/get.js +++ b/src/cli/commands/dag/get.js @@ -16,17 +16,21 @@ module.exports = { }, handler (argv) { - const refParts = argv.cidpath.split('/') - const cidString = refParts[0] - const path = refParts.slice(1).join('/') - const cid = new CID(cidString) + argv.resolve((async () => { + const refParts = argv.cidpath.split('/') + const cidString = refParts[0] + const path = refParts.slice(1).join('/') + const cid = new CID(cidString) - const options = { - localResolve: argv.localResolve - } + const options = { + localResolve: argv.localResolve + } + + let result - argv.ipfs.dag.get(cid, path, options, (err, result) => { - if (err) { + try { + result = await argv.ipfs.dag.get(cid, path, options) + } catch (err) { return print(`dag get failed: ${err.message}`) } @@ -56,6 +60,6 @@ module.exports = { } else { print(node) } - }) + })()) } } diff --git a/src/cli/commands/dns.js b/src/cli/commands/dns.js index f1d7270612..2d80479ce7 100644 --- a/src/cli/commands/dns.js +++ b/src/cli/commands/dns.js @@ -12,13 +12,10 @@ module.exports = { } }, - handler ({ ipfs, domain }) { - ipfs.dns(domain, (err, path) => { - if (err) { - throw err - } - + handler ({ ipfs, domain, resolve }) { + resolve((async () => { + 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 e9aeaee4e6..b4325e88ed 100644 --- a/src/cli/commands/file/ls.js +++ b/src/cli/commands/file/ls.js @@ -10,13 +10,12 @@ module.exports = { builder: {}, handler (argv) { - let path = argv.key - // `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.`) - argv.ipfs.ls(path, (err, links) => { - if (err) { - throw err - } + argv.resolve((async () => { + const path = argv.key + // `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) // Single file? Then print its hash if (links.length === 0) { @@ -24,6 +23,6 @@ module.exports = { } links.forEach((file) => print(file.hash)) - }) + })()) } } diff --git a/src/cli/commands/get.js b/src/cli/commands/get.js index 6a787363ed..5756aeb66b 100644 --- a/src/cli/commands/get.js +++ b/src/cli/commands/get.js @@ -58,20 +58,20 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, output }) { - const dir = checkArgs(ipfsPath, output) - const stream = ipfs.getReadableStream(ipfsPath) + handler ({ ipfs, ipfsPath, output, resolve }) { + resolve(new Promise((resolve, reject) => { + const dir = checkArgs(ipfsPath, output) + const stream = ipfs.getReadableStream(ipfsPath) - stream.once('error', (err) => { - if (err) { throw err } - }) - print(`Saving file(s) ${ipfsPath}`) - pull( - toPull.source(stream), - pull.asyncMap(fileHandler(dir)), - pull.onEnd((err) => { - if (err) { throw err } - }) - ) + 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 81ed38eef4..8778203093 100644 --- a/src/cli/commands/id.js +++ b/src/cli/commands/id.js @@ -14,13 +14,9 @@ module.exports = { }, handler (argv) { - // TODO: handle argv.format - argv.ipfs.id((err, id) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const id = await argv.ipfs.id() print(JSON.stringify(id, '', 2)) - }) + })()) } } diff --git a/src/cli/commands/init.js b/src/cli/commands/init.js index 9df7b199cc..3322979d5f 100644 --- a/src/cli/commands/init.js +++ b/src/cli/commands/init.js @@ -32,34 +32,36 @@ module.exports = { }, handler (argv) { - const path = utils.getRepoPath() + argv.resolve((async () => { + const path = utils.getRepoPath() - print(`initializing ipfs node at ${path}`) + print(`initializing ipfs node at ${path}`) - // Required inline to reduce startup time - const IPFS = require('../../core') - const Repo = require('ipfs-repo') + // Required inline to reduce startup time + const IPFS = require('../../core') + const Repo = require('ipfs-repo') - const node = new IPFS({ - repo: new Repo(path), - init: false, - start: false, - config: argv.config || {} - }) + const node = new IPFS({ + repo: new Repo(path), + init: false, + start: false, + config: argv.config || {} + }) - node.init({ - bits: argv.bits, - privateKey: argv.privateKey, - emptyRepo: argv.emptyRepo, - pass: argv.pass, - log: print - }, (err) => { - if (err) { + try { + await node.init({ + bits: argv.bits, + privateKey: argv.privateKey, + emptyRepo: argv.emptyRepo, + pass: argv.pass, + log: print + }) + } catch (err) { if (err.code === 'EACCES') { err.message = `EACCES: permission denied, stat $IPFS_PATH/version` } throw err } - }) + })()) } } diff --git a/src/cli/commands/key/export.js b/src/cli/commands/key/export.js index 66adde248c..b59250fce6 100644 --- a/src/cli/commands/key/export.js +++ b/src/cli/commands/key/export.js @@ -23,15 +23,13 @@ module.exports = { }, handler (argv) { - argv.ipfs.key.export(argv.name, argv.passout, (err, pem) => { - if (err) { - throw err - } + argv.resolve((async () => { + const pem = await argv.ipfs.key.export(argv.name, argv.passout) if (argv.output === 'stdout') { process.stdout.write(pem) } else { fs.writeFileSync(argv.output, pem) } - }) + })()) } } diff --git a/src/cli/commands/key/gen.js b/src/cli/commands/key/gen.js index 811fbe2a1e..8b321df787 100644 --- a/src/cli/commands/key/gen.js +++ b/src/cli/commands/key/gen.js @@ -22,15 +22,13 @@ module.exports = { }, handler (argv) { - const opts = { - type: argv.type, - size: argv.size - } - argv.ipfs.key.gen(argv.name, opts, (err, key) => { - if (err) { - throw err + argv.resolve((async () => { + const opts = { + type: argv.type, + size: argv.size } + const key = await argv.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 ae0363b25d..1bc02bf6d9 100644 --- a/src/cli/commands/key/import.js +++ b/src/cli/commands/key/import.js @@ -24,11 +24,9 @@ module.exports = { }, handler (argv) { - argv.ipfs.key.import(argv.name, argv.input, argv.passin, (err, key) => { - if (err) { - throw err - } + argv.resolve((async () => { + const key = await argv.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 d50db99697..c2ef37d2d3 100644 --- a/src/cli/commands/key/list.js +++ b/src/cli/commands/key/list.js @@ -10,11 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.key.list((err, keys) => { - if (err) { - throw err - } + argv.resolve((async () => { + const keys = await argv.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 9126dbbb36..9c9a86e8b8 100644 --- a/src/cli/commands/key/rename.js +++ b/src/cli/commands/key/rename.js @@ -10,11 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.key.rename(argv.name, argv.newName, (err, res) => { - if (err) { - throw err - } + argv.resolve((async () => { + const res = await argv.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 a7a5daf658..dccf65323b 100644 --- a/src/cli/commands/key/rm.js +++ b/src/cli/commands/key/rm.js @@ -10,11 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.key.rm(argv.name, (err, key) => { - if (err) { - throw err - } + argv.resolve((async () => { + const key = await argv.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 66667326bd..a4f6333401 100644 --- a/src/cli/commands/ls.js +++ b/src/cli/commands/ls.js @@ -34,11 +34,9 @@ module.exports = { } }, - handler ({ ipfs, key, recursive, headers, cidBase }) { - ipfs.ls(key, { recursive }, (err, links) => { - if (err) { - throw err - } + handler ({ ipfs, key, recursive, headers, cidBase, resolve }) { + resolve((async () => { + let links = await ipfs.ls(key, { recursive }) links = links.map(file => Object.assign(file, { hash: cidToString(file.hash, { base: cidBase }) })) @@ -64,6 +62,6 @@ module.exports = { ' '.repeat(padding) + fileName ) }) - }) + })()) } } diff --git a/src/cli/commands/name/publish.js b/src/cli/commands/name/publish.js index 34507c50a6..2cd51e4c9a 100644 --- a/src/cli/commands/name/publish.js +++ b/src/cli/commands/name/publish.js @@ -30,27 +30,24 @@ module.exports = { }, handler (argv) { - // yargs-promise adds resolve/reject properties to argv - // resolve should use the alias as resolve will always be overwritten to a function - let resolve = true + argv.resolve((async () => { + // yargs-promise adds resolve/reject properties to argv + // resolve should use the alias as resolve will always be overwritten to a function + let resolve = true - if (argv.r === false || argv.r === 'false') { - resolve = false - } - - const opts = { - resolve, - lifetime: argv.lifetime, - key: argv.key, - ttl: argv.ttl - } + if (argv.r === false || argv.r === 'false') { + resolve = false + } - argv.ipfs.name.publish(argv.ipfsPath, opts, (err, result) => { - if (err) { - throw err + const opts = { + resolve, + lifetime: argv.lifetime, + key: argv.key, + ttl: argv.ttl } + const result = await argv.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 5f0d709294..eeab1146e7 100644 --- a/src/cli/commands/name/pubsub/cancel.js +++ b/src/cli/commands/name/pubsub/cancel.js @@ -8,12 +8,9 @@ module.exports = { describe: 'Cancel a name subscription.', handler (argv) { - argv.ipfs.name.pubsub.cancel(argv.name, (err, result) => { - if (err) { - throw err - } else { - print(result.canceled ? 'canceled' : 'no subscription') - } - }) + argv.resolve((async () => { + const result = await argv.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 08c65fbed1..c826789d13 100644 --- a/src/cli/commands/name/pubsub/state.js +++ b/src/cli/commands/name/pubsub/state.js @@ -8,12 +8,9 @@ module.exports = { describe: 'Query the state of IPNS pubsub.', handler (argv) { - argv.ipfs.name.pubsub.state((err, result) => { - if (err) { - throw err - } else { - print(result.enabled ? 'enabled' : 'disabled') - } - }) + argv.resolve((async () => { + const result = await argv.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 ced5682626..ef6b29aeae 100644 --- a/src/cli/commands/name/pubsub/subs.js +++ b/src/cli/commands/name/pubsub/subs.js @@ -8,14 +8,9 @@ module.exports = { describe: 'Show current name subscriptions.', handler (argv) { - argv.ipfs.name.pubsub.subs((err, result) => { - if (err) { - throw err - } else { - result.forEach((s) => { - print(s) - }) - } - }) + argv.resolve((async () => { + const result = await argv.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 7a5f49675d..c93fa7ba47 100644 --- a/src/cli/commands/name/resolve.js +++ b/src/cli/commands/name/resolve.js @@ -21,21 +21,19 @@ module.exports = { }, handler (argv) { - const opts = { - nocache: argv.nocache, - recursive: argv.recursive - } - - argv.ipfs.name.resolve(argv.name, opts, (err, result) => { - if (err) { - throw err + argv.resolve((async () => { + const opts = { + nocache: argv.nocache, + recursive: argv.recursive } + const result = await argv.ipfs.name.resolve(argv.name, opts) + if (result && result.path) { print(result.path) } else { print(result) } - }) + })()) } } diff --git a/src/cli/commands/object/data.js b/src/cli/commands/object/data.js index 13d0bfa7c7..e0ac085f24 100644 --- a/src/cli/commands/object/data.js +++ b/src/cli/commands/object/data.js @@ -10,14 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.object.data(argv.key, { - enc: 'base58' - }, (err, data) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const data = await argv.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 456449492c..b0351ddd7b 100644 --- a/src/cli/commands/object/get.js +++ b/src/cli/commands/object/get.js @@ -21,12 +21,9 @@ module.exports = { } }, - handler ({ ipfs, key, dataEncoding, cidBase }) { - ipfs.object.get(key, { enc: 'base58' }, (err, node) => { - if (err) { - throw err - } - + handler ({ ipfs, key, dataEncoding, cidBase, resolve }) { + resolve((async () => { + const node = await ipfs.object.get(key, { enc: 'base58' }) let data = node.data if (Buffer.isBuffer(data)) { @@ -47,6 +44,6 @@ module.exports = { } print(JSON.stringify(answer)) - }) + })()) } } diff --git a/src/cli/commands/object/links.js b/src/cli/commands/object/links.js index 768e42150c..c08ecac4c8 100644 --- a/src/cli/commands/object/links.js +++ b/src/cli/commands/object/links.js @@ -17,15 +17,14 @@ module.exports = { } }, - handler ({ ipfs, key, cidBase }) { - ipfs.object.links(key, { enc: 'base58' }, (err, links) => { - if (err) { - throw err - } + handler ({ ipfs, key, cidBase, resolve }) { + resolve((async () => { + const links = await ipfs.object.links(key, { enc: 'base58' }) links.forEach((link) => { - print(`${cidToString(link.cid, { base: cidBase, upgrade: false })} ${link.size} ${link.name}`) + const cidStr = cidToString(link.cid, { base: cidBase, upgrade: false }) + print(`${cidStr} ${link.size} ${link.name}`) }) - }) + })()) } } diff --git a/src/cli/commands/object/new.js b/src/cli/commands/object/new.js index d48f4c69ee..af3b99ed07 100644 --- a/src/cli/commands/object/new.js +++ b/src/cli/commands/object/new.js @@ -17,13 +17,10 @@ module.exports = { } }, - handler ({ ipfs, template, cidBase }) { - ipfs.object.new(template, (err, cid) => { - if (err) { - throw err - } - + handler ({ ipfs, template, cidBase, resolve }) { + resolve((async () => { + 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 a1a573a031..ad03de7d99 100644 --- a/src/cli/commands/object/patch/add-link.js +++ b/src/cli/commands/object/patch/add-link.js @@ -3,6 +3,7 @@ const dagPB = require('ipld-dag-pb') const DAGLink = dagPB.DAGLink const multibase = require('multibase') +const promisify = require('promisify-es6') const { print } = require('../../../utils') const { cidToString } = require('../../../../utils/cid') @@ -19,29 +20,13 @@ module.exports = { } }, - handler ({ ipfs, root, name, ref, cidBase }) { - ipfs.object.get(ref, { enc: 'base58' }, (err, nodeA) => { - if (err) { - throw err - } - - dagPB.util.cid(nodeA, (err, result) => { - if (err) { - throw err - } - - const link = new DAGLink(name, nodeA.size, result) - - ipfs.object.patch.addLink(root, link, { - enc: 'base58' - }, (err, cid) => { - if (err) { - throw err - } - - print(cidToString(cid, { base: cidBase, upgrade: false })) - }) - }) - }) + handler ({ ipfs, root, name, ref, cidBase, resolve }) { + resolve((async () => { + 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) + const cid = await ipfs.object.patch.addLink(root, link, { enc: 'base58' }) + print(cidToString(cid, { base: cidBase, upgrade: false })) + })()) } } diff --git a/src/cli/commands/object/patch/append-data.js b/src/cli/commands/object/patch/append-data.js index b54f301f62..606c676fc9 100644 --- a/src/cli/commands/object/patch/append-data.js +++ b/src/cli/commands/object/patch/append-data.js @@ -6,18 +6,6 @@ const multibase = require('multibase') const { print } = require('../../../utils') const { cidToString } = require('../../../../utils/cid') -function appendData (key, data, ipfs, options) { - ipfs.object.patch.appendData(key, data, { - enc: 'base58' - }, (err, cid) => { - if (err) { - throw err - } - - print(cidToString(cid, { base: options.cidBase, upgrade: false })) - }) -} - module.exports = { command: 'append-data [data]', @@ -32,17 +20,25 @@ module.exports = { }, handler (argv) { - const ipfs = argv.ipfs - if (argv.data) { - return appendData(argv.root, fs.readFileSync(argv.data), ipfs, argv) - } - - process.stdin.pipe(bl((err, input) => { - if (err) { - throw err + argv.resolve((async () => { + let data + + if (argv.data) { + data = fs.readFileSync(argv.data) + } else { + data = await new Promise((resolve, reject) => { + process.stdin.pipe(bl((err, input) => { + if (err) return reject(err) + resolve(input) + })) + }) } - appendData(argv.root, input, ipfs, argv) - })) + const cid = await argv.ipfs.object.patch.appendData(argv.root, data, { + enc: 'base58' + }) + + print(cidToString(cid, { base: argv.cidBase, upgrade: false })) + })()) } } diff --git a/src/cli/commands/object/patch/rm-link.js b/src/cli/commands/object/patch/rm-link.js index ca7be4e8a5..ea0376d8bb 100644 --- a/src/cli/commands/object/patch/rm-link.js +++ b/src/cli/commands/object/patch/rm-link.js @@ -17,15 +17,13 @@ module.exports = { } }, - handler ({ ipfs, root, link, cidBase }) { - ipfs.object.patch.rmLink(root, { name: link }, { - enc: 'base58' - }, (err, cid) => { - if (err) { - throw err - } + handler ({ ipfs, root, link, cidBase, resolve }) { + resolve((async () => { + const cid = await ipfs.object.patch.rmLink(root, { name: link }, { + enc: 'base58' + }) print(cidToString(cid, { base: cidBase, upgrade: false })) - }) + })()) } } diff --git a/src/cli/commands/object/patch/set-data.js b/src/cli/commands/object/patch/set-data.js index 7c7209ea57..eec0598f57 100644 --- a/src/cli/commands/object/patch/set-data.js +++ b/src/cli/commands/object/patch/set-data.js @@ -6,18 +6,6 @@ const multibase = require('multibase') const { print } = require('../../../utils') const { cidToString } = require('../../../../utils/cid') -function parseAndAddNode (key, data, ipfs, options) { - ipfs.object.patch.setData(key, data, { - enc: 'base58' - }, (err, cid) => { - if (err) { - throw err - } - - print(cidToString(cid, { base: options.cidBase, upgrade: false })) - }) -} - module.exports = { command: 'set-data [data]', @@ -32,17 +20,25 @@ module.exports = { }, handler (argv) { - const ipfs = argv.ipfs - if (argv.data) { - return parseAndAddNode(argv.root, fs.readFileSync(argv.data), ipfs, argv) - } - - process.stdin.pipe(bl((err, input) => { - if (err) { - throw err + argv.resolve((async () => { + let data + + if (argv.data) { + data = fs.readFileSync(argv.data) + } else { + data = await new Promise((resolve, reject) => { + process.stdin.pipe(bl((err, input) => { + if (err) return reject(err) + resolve(input) + })) + }) } - parseAndAddNode(argv.root, input, ipfs, argv) - })) + const cid = await argv.ipfs.object.patch.setData(argv.root, data, { + enc: 'base58' + }) + + print(cidToString(cid, { base: argv.cidBase, upgrade: false })) + })()) } } diff --git a/src/cli/commands/object/put.js b/src/cli/commands/object/put.js index c9999bb335..8979a79379 100644 --- a/src/cli/commands/object/put.js +++ b/src/cli/commands/object/put.js @@ -6,16 +6,6 @@ const multibase = require('multibase') const { print } = require('../../utils') const { cidToString } = require('../../../utils/cid') -function putNode (buf, options, ipfs) { - ipfs.object.put(buf, { enc: options.inputEnc }, (err, cid) => { - if (err) { - throw err - } - - print(`added ${cidToString(cid, { base: options.cidBase, upgrade: false })}`) - }) -} - module.exports = { command: 'put [data]', @@ -34,18 +24,22 @@ module.exports = { }, handler (argv) { - const ipfs = argv.ipfs - if (argv.data) { - const buf = fs.readFileSync(argv.data) - return putNode(buf, argv, ipfs) - } - - process.stdin.pipe(bl((err, input) => { - if (err) { - throw err + argv.resolve((async () => { + let data + + if (argv.data) { + data = fs.readFileSync(argv.data) + } else { + data = await new Promise((resolve, reject) => { + process.stdin.pipe(bl((err, input) => { + if (err) return reject(err) + resolve(input) + })) + }) } - putNode(input, argv, ipfs) - })) + const cid = await argv.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 e89fe64860..f9fd80474a 100644 --- a/src/cli/commands/object/stat.js +++ b/src/cli/commands/object/stat.js @@ -9,17 +9,11 @@ module.exports = { builder: {}, - handler ({ ipfs, key, cidBase }) { - ipfs.object.stat(key, { enc: 'base58' }, (err, stats) => { - if (err) { - throw err - } - + handler ({ ipfs, key, cidBase, resolve }) { + resolve((async () => { + 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]}`) - }) - }) + 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 8d7ec6ccdc..a37f5b0550 100644 --- a/src/cli/commands/pin/add.js +++ b/src/cli/commands/pin/add.js @@ -23,14 +23,13 @@ module.exports = { } }, - handler ({ ipfs, ipfsPath, recursive, cidBase }) { - const type = recursive ? 'recursive' : 'direct' - - ipfs.pin.add(ipfsPath, { recursive }, (err, results) => { - if (err) { throw err } + handler ({ ipfs, ipfsPath, recursive, cidBase, resolve }) { + resolve((async () => { + const type = recursive ? 'recursive' : 'direct' + 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 68792dc9d8..9aafdb8239 100644 --- a/src/cli/commands/pin/ls.js +++ b/src/cli/commands/pin/ls.js @@ -31,11 +31,10 @@ module.exports = { } }, - handler: ({ ipfs, ipfsPath, type, quiet, cidBase }) => { - const paths = ipfsPath - - ipfs.pin.ls(paths, { type }, (err, results) => { - if (err) { throw err } + handler: ({ ipfs, ipfsPath, type, quiet, cidBase, resolve }) => { + resolve((async () => { + const paths = ipfsPath + const results = await ipfs.pin.ls(paths, { type }) results.forEach((res) => { let line = cidToString(res.hash, { base: cidBase }) if (!quiet) { @@ -43,6 +42,6 @@ module.exports = { } print(line) }) - }) + })()) } } diff --git a/src/cli/commands/pin/rm.js b/src/cli/commands/pin/rm.js index d99f16ebc9..00c2f4c362 100644 --- a/src/cli/commands/pin/rm.js +++ b/src/cli/commands/pin/rm.js @@ -23,12 +23,12 @@ module.exports = { } }, - handler: ({ ipfs, ipfsPath, recursive, cidBase }) => { - ipfs.pin.rm(ipfsPath, { recursive }, (err, results) => { - if (err) { throw err } + handler: ({ ipfs, ipfsPath, recursive, cidBase, resolve }) => { + resolve((async () => { + 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 3760b33b75..a66767df59 100644 --- a/src/cli/commands/ping.js +++ b/src/cli/commands/ping.js @@ -17,19 +17,24 @@ module.exports = { }, handler (argv) { - 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) - } - }) - ) + 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() + }) + ) + })) } } diff --git a/src/cli/commands/pubsub/ls.js b/src/cli/commands/pubsub/ls.js index c10249400e..18a488ee88 100644 --- a/src/cli/commands/pubsub/ls.js +++ b/src/cli/commands/pubsub/ls.js @@ -10,14 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.pubsub.ls((err, subscriptions) => { - if (err) { - throw err - } - - subscriptions.forEach((sub) => { - print(sub) - }) - }) + argv.resolve((async () => { + const subscriptions = await argv.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 74fee9b1d5..21eb57b01b 100644 --- a/src/cli/commands/pubsub/peers.js +++ b/src/cli/commands/pubsub/peers.js @@ -10,12 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.pubsub.peers(argv.topic, (err, peers) => { - if (err) { - throw err - } - - peers.forEach((peer) => print(peer)) - }) + argv.resolve((async () => { + const peers = await argv.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 e0567cdaf7..5cf96a3c57 100644 --- a/src/cli/commands/pubsub/pub.js +++ b/src/cli/commands/pubsub/pub.js @@ -8,12 +8,9 @@ module.exports = { builder: {}, handler (argv) { - const data = Buffer.from(String(argv.data)) - - argv.ipfs.pubsub.publish(argv.topic, data, (err) => { - if (err) { - throw err - } - }) + argv.resolve((async () => { + const data = Buffer.from(String(argv.data)) + await argv.ipfs.pubsub.publish(argv.topic, data) + })()) } } diff --git a/src/cli/commands/pubsub/sub.js b/src/cli/commands/pubsub/sub.js index 21f3d2060a..a35bbf2a44 100644 --- a/src/cli/commands/pubsub/sub.js +++ b/src/cli/commands/pubsub/sub.js @@ -10,14 +10,9 @@ module.exports = { builder: {}, handler (argv) { - const handler = (msg) => { - print(msg.data.toString()) - } - - argv.ipfs.pubsub.subscribe(argv.topic, handler, (err) => { - if (err) { - throw err - } - }) + argv.resolve((async () => { + const handler = msg => print(msg.data.toString()) + await argv.ipfs.pubsub.subscribe(argv.topic, handler) + })()) } } diff --git a/src/cli/commands/repo/gc.js b/src/cli/commands/repo/gc.js index f427e5c966..13d11dc630 100644 --- a/src/cli/commands/repo/gc.js +++ b/src/cli/commands/repo/gc.js @@ -8,10 +8,8 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.repo.gc((err) => { - if (err) { - throw err - } - }) + argv.resolve((async () => { + await argv.ipfs.repo.gc() + })()) } } diff --git a/src/cli/commands/repo/stat.js b/src/cli/commands/repo/stat.js index 97b0813e29..8a262eb027 100644 --- a/src/cli/commands/repo/stat.js +++ b/src/cli/commands/repo/stat.js @@ -15,17 +15,14 @@ module.exports = { }, handler (argv) { - argv.ipfs.repo.stat({ human: argv.human }, (err, stats) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const stats = await argv.ipfs.repo.stat({ human: argv.human }) print(`repo status number of objects: ${stats.numObjects} repo size: ${stats.repoSize} repo path: ${stats.repoPath} version: ${stats.version} maximum storage: ${stats.storageMax}`) - }) + })()) } } diff --git a/src/cli/commands/repo/version.js b/src/cli/commands/repo/version.js index 9a0f5271a8..921cf0bb1e 100644 --- a/src/cli/commands/repo/version.js +++ b/src/cli/commands/repo/version.js @@ -10,12 +10,9 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.repo.version((err, version) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const version = await argv.ipfs.repo.version() print(version) - }) + })()) } } diff --git a/src/cli/commands/resolve.js b/src/cli/commands/resolve.js index 6cf4e891c8..61668b5d28 100644 --- a/src/cli/commands/resolve.js +++ b/src/cli/commands/resolve.js @@ -21,11 +21,10 @@ module.exports = { } }, - handler (argv) { - const { recursive, cidBase } = argv - argv.ipfs.resolve(argv.name, { recursive, cidBase }, (err, res) => { - if (err) throw err + handler ({ ipfs, name, recursive, cidBase, resolve }) { + resolve((async () => { + 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 99c6e8d6a7..de6dc0c6d3 100644 --- a/src/cli/commands/shutdown.js +++ b/src/cli/commands/shutdown.js @@ -8,10 +8,6 @@ module.exports = { builder: {}, handler (argv) { - argv.ipfs.shutdown((err) => { - if (err) { - throw err - } - }) + argv.resolve(argv.ipfs.shutdown()) } } diff --git a/src/cli/commands/stats/bw.js b/src/cli/commands/stats/bw.js index 843ed87bb8..45e7fbcb86 100644 --- a/src/cli/commands/stats/bw.js +++ b/src/cli/commands/stats/bw.js @@ -27,18 +27,24 @@ module.exports = { } }, - handler ({ ipfs, peer, proto, poll, interval }) { - const stream = ipfs.stats.bwPullStream({ peer, proto, poll, interval }) + handler ({ ipfs, peer, proto, poll, interval, resolve }) { + resolve(new Promise((resolve, reject) => { + const stream = ipfs.stats.bwPullStream({ peer, proto, poll, interval }) - pull( - stream, - pull.drain((chunk) => { + 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() + } + + pull(stream, pull.drain(onChunk, onEnd)) + })) } } diff --git a/src/cli/commands/stats/repo.js b/src/cli/commands/stats/repo.js index a0537e902d..1c7a42c0ed 100644 --- a/src/cli/commands/stats/repo.js +++ b/src/cli/commands/stats/repo.js @@ -15,17 +15,14 @@ module.exports = { }, handler (argv) { - argv.ipfs.stats.repo({ human: argv.human }, (err, stats) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const stats = await argv.ipfs.stats.repo({ human: argv.human }) print(`repo status number of objects: ${stats.numObjects} repo size: ${stats.repoSize} repo path: ${stats.repoPath} version: ${stats.version} maximum storage: ${stats.storageMax}`) - }) + })()) } } diff --git a/src/cli/commands/swarm/addrs.js b/src/cli/commands/swarm/addrs.js index ce4fb79eb1..d5bbe9cf2a 100644 --- a/src/cli/commands/swarm/addrs.js +++ b/src/cli/commands/swarm/addrs.js @@ -13,11 +13,8 @@ module.exports = { }, handler (argv) { - argv.ipfs.swarm.addrs((err, res) => { - if (err) { - throw err - } - + argv.resolve((async () => { + const res = await argv.ipfs.swarm.addrs() res.forEach((peer) => { const count = peer.multiaddrs.size print(`${peer.id.toB58String()} (${count})`) @@ -27,6 +24,6 @@ module.exports = { print(`\t${res}`) }) }) - }) + })()) } } diff --git a/src/cli/commands/swarm/addrs/local.js b/src/cli/commands/swarm/addrs/local.js index 5479deca1a..b321fea6b8 100644 --- a/src/cli/commands/swarm/addrs/local.js +++ b/src/cli/commands/swarm/addrs/local.js @@ -14,18 +14,12 @@ module.exports = { builder: {}, handler (argv) { - if (!utils.isDaemonOn()) { - throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') - } - - argv.ipfs.swarm.localAddrs((err, res) => { - if (err) { - throw err + argv.resolve((async () => { + if (!utils.isDaemonOn()) { + throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } - - res.forEach((addr) => { - print(addr.toString()) - }) - }) + const res = await argv.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 4f42a392bb..b1f26eeeee 100644 --- a/src/cli/commands/swarm/connect.js +++ b/src/cli/commands/swarm/connect.js @@ -11,16 +11,12 @@ module.exports = { builder: {}, handler (argv) { - if (!utils.isDaemonOn()) { - throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') - } - - argv.ipfs.swarm.connect(argv.address, (err, res) => { - if (err) { - throw err + argv.resolve((async () => { + 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) print(res.Strings[0]) - }) + })()) } } diff --git a/src/cli/commands/swarm/disconnect.js b/src/cli/commands/swarm/disconnect.js index 1d4ac123fb..36019177a3 100644 --- a/src/cli/commands/swarm/disconnect.js +++ b/src/cli/commands/swarm/disconnect.js @@ -11,16 +11,12 @@ module.exports = { builder: {}, handler (argv) { - if (!utils.isDaemonOn()) { - throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') - } - - argv.ipfs.swarm.disconnect(argv.address, (err, res) => { - if (err) { - throw err + argv.resolve((async () => { + 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) print(res.Strings[0]) - }) + })()) } } diff --git a/src/cli/commands/swarm/peers.js b/src/cli/commands/swarm/peers.js index 50cde65819..dc5ca9f3cd 100644 --- a/src/cli/commands/swarm/peers.js +++ b/src/cli/commands/swarm/peers.js @@ -13,15 +13,13 @@ module.exports = { builder: {}, handler (argv) { - if (!utils.isDaemonOn()) { - throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') - } - - argv.ipfs.swarm.peers((err, result) => { - if (err) { - throw err + argv.resolve((async () => { + if (!utils.isDaemonOn()) { + throw new Error('This command must be run in online mode. Try running \'ipfs daemon\' first.') } + const result = await argv.ipfs.swarm.peers() + result.forEach((item) => { let ma = multiaddr(item.addr.toString()) if (!mafmt.IPFS.matches(ma)) { @@ -30,6 +28,6 @@ module.exports = { const addr = ma.toString() print(addr) }) - }) + })()) } } diff --git a/src/cli/commands/version.js b/src/cli/commands/version.js index 6bb8447a2f..e5078bc95f 100644 --- a/src/cli/commands/version.js +++ b/src/cli/commands/version.js @@ -33,10 +33,8 @@ module.exports = { }, handler (argv) { - argv.ipfs.version((err, data) => { - if (err) { - throw err - } + argv.resolve((async () => { + const data = await argv.ipfs.version() const withCommit = argv.all || argv.commit const parsedVersion = `${data.version}${withCommit ? `-${data.commit}` : ''}` @@ -54,6 +52,6 @@ module.exports = { } else { print(`js-ipfs version: ${parsedVersion}`) } - }) + })()) } }