From a849d2f4ec9d66d788709112b366d97d70dea301 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 5 Apr 2018 17:40:57 +0100 Subject: [PATCH 1/7] fix: Display error when using unkown cli option --- src/cli/bin.js | 13 +++++++++---- src/cli/commands/files/cat.js | 4 ++-- src/cli/commands/files/get.js | 5 +++-- test/cli/general.js | 8 ++++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/cli/bin.js b/src/cli/bin.js index 67e60f8362..1d53444ac9 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -14,6 +14,8 @@ updateNotifier({ updateCheckInterval: 1000 * 60 * 60 * 24 * 7 // 1 week }).notify() +const args = process.argv.slice(2) + const cli = yargs .option('silent', { desc: 'Write no output', @@ -32,6 +34,11 @@ const cli = yargs if (err) { throw err // preserve stack } + + if (args.length > 0) { + print(msg) + } + yargs.showHelp() }) @@ -46,14 +53,12 @@ aliases.forEach((alias) => { cli.command(alias.command, alias.describe, alias.builder, alias.handler) }) -const args = process.argv.slice(2) - // Need to skip to avoid locking as these commands // don't require a daemon if (args[0] === 'daemon' || args[0] === 'init') { cli .help() - .strict(false) + .strict() .completion() .parse(args) } else { @@ -69,7 +74,7 @@ if (args[0] === 'daemon' || args[0] === 'init') { cli .help() - .strict(false) + .strict() .completion() .parse(args, { ipfs: ipfs }, (err, argv, output) => { if (output) { print(output) } diff --git a/src/cli/commands/files/cat.js b/src/cli/commands/files/cat.js index c9cc3037d6..43c22ceb21 100644 --- a/src/cli/commands/files/cat.js +++ b/src/cli/commands/files/cat.js @@ -1,14 +1,14 @@ 'use strict' module.exports = { - command: 'cat ', + command: 'cat ', describe: 'Fetch and cat an IPFS path referencing a file', builder: {}, handler (argv) { - let path = argv['ipfs-path'] + let path = argv['ipfsPath'] if (path.indexOf('/ipfs/') !== 1) { path = path.replace('/ipfs/', '') } diff --git a/src/cli/commands/files/get.js b/src/cli/commands/files/get.js index 85ee810671..c177fb8719 100644 --- a/src/cli/commands/files/get.js +++ b/src/cli/commands/files/get.js @@ -45,7 +45,7 @@ function fileHandler (dir) { } module.exports = { - command: 'get ', + command: 'get ', describe: 'Fetch a file or directory with files references from an IPFS Path', @@ -58,7 +58,8 @@ module.exports = { }, handler (argv) { - const ipfsPath = argv['ipfs-path'] + const ipfsPath = argv['ipfsPath'] + const dir = checkArgs(ipfsPath, argv.output) const stream = argv.ipfs.files.getReadableStream(ipfsPath) diff --git a/test/cli/general.js b/test/cli/general.js index 5a36e1529b..0f20466fcd 100644 --- a/test/cli/general.js +++ b/test/cli/general.js @@ -10,4 +10,12 @@ describe('general cli options', () => runOnAndOff.off((thing) => { expect(out).to.be.empty() }) }) + + it('should handle unknown arguments correctly', () => { + return thing.ipfs('random --again').then((out) => { + expect(out).to.include('Unknown arguments: again, random') + expect(out).to.include('random') + expect(out).to.include('again') + }) + }) })) From 93d2bf553aa4369fe4f53af07d4ca3f1b59272d1 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 6 Apr 2018 17:37:43 +0100 Subject: [PATCH 2/7] chore: updates joi-multiaddr dependency so that it uses multiaddr@4 with better IP4 and IP6 validation --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa93799263..b74ac3e23a 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "is-stream": "^1.1.0", "joi": "^13.1.2", "joi-browser": "^13.0.1", - "joi-multiaddr": "^1.0.1", + "joi-multiaddr": "^2.0.0", "libp2p": "~0.19.2", "libp2p-circuit": "~0.1.5", "libp2p-floodsub": "~0.14.1", From c307eb938307644f5b00c672a3c01832c81d33d1 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Tue, 10 Apr 2018 08:43:24 -0700 Subject: [PATCH 3/7] docs: Document constructor options more formally (#1294) * Document constructor options more formally This adds more descriptive and organized definitions for all the available options to the `IPFS` constructor as well as a full reference of events and the `start()` and `stop()` methods. License: MIT Signed-off-by: Rob Brackett * Clarify return values for `start()/stop()` License: MIT Signed-off-by: Rob Brackett * Replace link to deprecated FAQ repo with discuss The FAQ repo has been deprecated, so remove the contribution section's link to it. Instead, link to discuss.ipfs.io and IRC at the end of the FAQ. License: MIT Signed-off-by: Rob Brackett --- README.md | 216 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 154 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index ade402ea68..5b32ecb218 100644 --- a/README.md +++ b/README.md @@ -58,14 +58,19 @@ You can check the development status at the [Waffle Board](https://waffle.io/ipf - [IPFS CLI](#ipfs-cli) - [IPFS Daemon](#ipfs-daemon) - [IPFS Module (use IPFS as a module in Node.js or in the Browser)](#ipfs-module) - - [How to create a IPFS node instance](#create-a-ipfs-node-instance) - [Tutorials and Examples](#tutorials-and-examples) - [API Docs](#api) - - [Files](#files) - - [Graph](#graph) - - [Network](#network) - - [Node Management](#node-management) - - [Domain data types](#domain-data-types) + - [Constructor](#ipfs-constructor) + - [Events](#events) + - [start](#nodestartcallback) + - [stop](#nodestopcallback) + - [Core API](#core-api) + - [Files](#files) + - [Graph](#graph) + - [Crypto and Key Management](#crypto-and-key-management) + - [Network](#network) + - [Node Management](#node-management) + - [Domain data types](#domain-data-types) - [FAQ](#faq) - [Running js-ipfs with Docker](#running-js-ipfs-with-docker) - [Packages](#packages) @@ -163,11 +168,7 @@ If you want a programmatic way to spawn a IPFS Daemon using JavaScript, check ou ### IPFS Module -Use the IPFS Module as a dependency of a project to __spawn in process instances of IPFS__. - -#### Create a IPFS node instance - -Creating an IPFS instance couldn't be easier, all you have to do is: +Use the IPFS Module as a dependency of a project to __spawn in process instances of IPFS__. Create an instance by calling `new IPFS()` and waiting for its `ready` event: ```JavaScript // Create the IPFS node instance @@ -183,70 +184,158 @@ node.on('ready', () => { }) ``` -#### Advanced options when creating an IPFS node. +### [Tutorials and Examples](/examples) -When starting a node, you can: +You can find some examples and tutorials in the [examples](/examples) folder, these exist to help you get started using `js-ipfs`. -```JavaScript -// IPFS will need a repo, it can create one for you or you can pass -// it a repo instance of the type IPFS Repo -// https://github.com/ipfs/js-ipfs-repo -const repo = +### API -const node = new IPFS({ - repo: repo, - init: true, // default - // init: false, // You will need to set init: false after time you start instantiate a node as - // // the repo will be already initiated then. - // init: { - // bits: 1024 // size of the RSA key generated - // }, - start: true, // default - // start: false, - pass: undefined // default - // pass: 'pass phrase for key access', - EXPERIMENTAL: { // enable experimental features - pubsub: true, - sharding: true, // enable dir sharding - dht: true, // enable KadDHT, currently not interopable with go-ipfs - relay: { - enabled: true, // enable circuit relay dialer and listener - hop: { - enabled: true // enable circuit relay HOP (make this node a relay) - } - } - }, - config: { // overload the default IPFS node config, find defaults at https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime - Addresses: { - Swarm: [ - '/ip4/127.0.0.1/tcp/1337' - ] - } - }, - libp2p: { // add custom modules to the libp2p stack of your node - modules: {} +#### IPFS Constructor + +```js +const node = new IPFS([options]) +``` + +Creates and returns an instance of an IPFS node. Use the `options` argument to specify advanced configuration. It is an object with any of these properties: + +- `repo` (string or [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance): The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance. (Default: `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers.) + + Example: + + ```js + // Store data outside your user directory + const node = new IPFS({ repo: '/var/ipfs/data' }) + ``` + +- `init` (boolean or object): Initialize the repo when creating the IPFS node. (Default: `true`) + + If you have already initialized a repo before creating your IPFS node (e.g. you are loading a repo that was saved to disk from a previous run of your program), you must make sure to set this to `false`. Note that *initializing* a repo is different from creating an instance of [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo). The IPFS constructor sets many special properties when initializing a repo, so you should usually not try and call `repoInstance.init()` yourself. + + Instead of a boolean, you may provide an object with custom initialization options. + +- `start` (boolean): If `false`, do not automatically start the IPFS node. Instead, you’ll need to manually call `node.start()` yourself. (Default: `true`) + +- `pass` (string): A passphrase to encrypt your keys. + +- `EXPERIMENTAL` (object): Enable and configure experimental features. + - `pubsub` (boolean): Enable libp2p pub-sub. (Default: `false`) + - `sharding` (boolean): Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`) + - `dht` (boolean): Enable KadDHT. **This is currently not interopable with `go-ipfs`.** + - `relay` (object): Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs/js-ipfs/tree/master/examples/circuit-relaying) to learn more). + - `enabled` (boolean): Enable circuit relay dialer and listener. (Default: `false`) + - `hop` (object) + - `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`) + - `active` (boolean): Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`) + +- `config` (object) Modify the default IPFS node config. Find the Node.js defaults at [`src/core/runtime/config-nodejs.json`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-nodejs.json) and the browser defaults at [`src/core/runtime/config-browser.json`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-browser.json). This object will be *merged* with the default config; it will not replace it. + +- `libp2p` (object) add custom modules to the libp2p stack of your node + - `modules` (object): + - `transport` (Array<[libp2p.Transport](https://github.com/libp2p/interface-transport)>): An array of additional Libp2p transport instances to use. See [libp2p/interface-transport](https://github.com/libp2p/interface-transport) for details. + - `discovery` (Array<[libp2p.PeerDiscovery](https://github.com/libp2p/interface-peer-discovery)>): An array of additional Libp2p peer discovery instances to use. See [libp2p/peer-discovery](https://github.com/libp2p/interface-peer-discovery) for details. + +#### Events + +IPFS instances are Node.js [EventEmitters](https://nodejs.org/dist/latest-v8.x/docs/api/events.html#events_class_eventemitter). You can listen for events by calling `node.on('event', handler)`: + +```js +const node = new IPFS({ repo: '/var/ipfs/data' }) +node.on('error', errorObject => console.error(errorObject)) +``` + +- `error` is always accompanied by an `Error` object with information about the error that ocurred. + + ```js + node.on('error', error => { + console.error(error.message) + }) + ``` + +- `init` is emitted after a new repo has been initialized. It will not be emitted if you set the `init: false` option on the constructor. + +- `ready` is emitted when a node is ready to use. This is the final event you will receive when creating a node (after `init` and `start`). + + When creating a new IPFS node, you should almost always wait for the `ready` event before calling methods or interacting with the node. + +- `start` is emitted when a node has started listening for connections. It will not be emitted if you set the `start: false` option on the constructor. + +- `stop` is emitted when a node has closed all connections and released access to its repo. This is usually the result of calling [`node.stop()`](#nodestopcallback). + +#### `node.start([callback])` + +Start listening for connections with other IPFS nodes on the network. In most cases, you do not need to call this method — `new IPFS()` will automatically do it for you. + +This method is asynchronous. There are several ways to be notified when the node has finished starting: + +1. If you call `node.start()` with no arguments, it returns a promise. +2. If you pass a function as the final argument, it will be called when the node is started. *(Note: this method will **not** return a promise if you use a callback function.)* +3. You can listen for the [`start` event](#events). + +```js +const node = new IPFS({ start: false }) + +// Use a promise: +node.start() + .then(() => console.log('Node started!')) + .catch(error => console.error('Node failed to start!', error)) + +// OR use a callback: +node.start(error => { + if (error) { + console.error('Node failed to start!', error) + return } + console.log('Node started!') }) -// Events +// OR use events: +node.on('error', error => console.error('Something went terribly wrong!', error)) +node.on('start', () => console.log('Node started!')) +node.start() +``` -node.on('ready', () => {}) // Node is ready to use when you first create it -node.on('error', (err) => {}) // Node has hit some error while initing/starting +#### `node.stop([callback])` -node.on('init', () => {}) // Node has successfully finished initing the repo -node.on('start', () => {}) // Node has started -node.on('stop', () => {}) // Node has stopped -``` +Close and stop listening for connections with other IPFS nodes, then release access to the node’s repo. -### [Tutorials and Examples](/examples) +This method is asynchronous. There are several ways to be notified when the node has completely stopped: -You can find some examples and tutorials in the [examples](/examples) folder, these exist to help you get started using `js-ipfs`. +1. If you call `node.stop()` with no arguments, it returns a promise. +2. If you pass a function as the final argument, it will be called when the node is stopped. *(Note: this method will **not** return a promise if you use a callback function.)* +3. You can listen for the [`stop` event](#events). -### API +```js +const node = new IPFS() +node.on('ready', () => { + console.log('Node is ready to use!') + + // Stop with a promise: + node.stop() + .then(() => console.log('Node stopped!')) + .catch(error => console.error('Node failed to stop cleanly!', error)) + + // OR use a callback: + node.stop(error => { + if (error) { + console.error('Node failed to stop cleanly!', error) + return + } + console.log('Node stopped!') + }) + + // OR use events: + node.on('error', error => console.error('Something went terribly wrong!', error)) + node.stop() +}) +``` + +#### Core API [![](https://github.com/ipfs/interface-ipfs-core/raw/master/img/badge.png)](https://github.com/ipfs/interface-ipfs-core) -A complete API definition is in the works. Meanwhile, you can learn how to you use js-ipfs through the standard interface at [![](https://img.shields.io/badge/interface--ipfs--core-API%20Docs-blue.svg)](https://github.com/ipfs/interface-ipfs-core). +The IPFS core API provides all functionality that is not specific to setting up and starting or stopping a node. This API is available directly on an IPFS instance, on the command line (when using the CLI interface), and as an HTTP REST API. For a complete reference, see [![](https://img.shields.io/badge/interface--ipfs--core-API%20Docs-blue.svg)](https://github.com/ipfs/interface-ipfs-core). + +The core API is grouped into several areas: #### `Files` @@ -513,6 +602,10 @@ HOME=~/.electron-gyp npm install If you find any other issue, please check the [`Electron Support` issue](https://github.com/ipfs/js-ipfs/issues/843). +#### Have more questions? + +Ask for help in our forum at https://discuss.ipfs.io or in IRC (#ipfs on Freenode). + ## Running js-ipfs with Docker We have automatic Docker builds setup with Docker Hub: https://hub.docker.com/r/ipfs/js-ipfs/ @@ -718,7 +811,6 @@ IPFS implementation in JavaScript is a work in progress. As such, there's a few * **Perform code reviews**. More eyes will help (a) speed the project along, (b) ensure quality, and (c) reduce possible future bugs. * Take a look at go-ipfs and some of the planning repositories or issues: for instance, the [libp2p spec](https://github.com/ipfs/specs/pull/19). Contributions here that would be most helpful are **top-level comments** about how it should look based on our understanding. Again, the more eyes the better. * **Add tests**. There can never be enough tests. - * **Contribute to the [FAQ repository](https://github.com/ipfs/faq/issues)** with any questions you have about IPFS or any of the relevant technology. A good example would be asking, 'What is a merkledag tree?'. If you don't know a term, odds are, someone else doesn't either. Eventually, we should have a good understanding of where we need to improve communications and teaching together to make IPFS and IPN better. ### Want to hack on IPFS? From a2954cba292036828c131c5acdba0d2aac240a0f Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 9 Apr 2018 15:21:07 +0100 Subject: [PATCH 4/7] feat: Add support for specifying hash algorithms in files.add --- src/cli/commands/files/add.js | 21 ++++++++++++++++++++- src/core/components/files.js | 25 +++++++++++++++++-------- src/core/components/object.js | 7 ++++++- src/http/api/resources/files.js | 3 ++- test/cli/files.js | 27 +++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/cli/commands/files/add.js b/src/cli/commands/files/add.js index 23c9fdb60d..87cdbbdf35 100644 --- a/src/cli/commands/files/add.js +++ b/src/cli/commands/files/add.js @@ -10,6 +10,7 @@ const zip = require('pull-zip') const getFolderSize = require('get-folder-size') const byteman = require('byteman') const waterfall = require('async/waterfall') +const mh = require('multihashes') const utils = require('../../utils') const print = require('../../utils').print const createProgressBar = require('../../utils').createProgressBar @@ -162,6 +163,11 @@ module.exports = { type: 'integer', describe: 'Cid version. Non-zero value will change default of \'raw-leaves\' to true. (experimental)' }, + hash: { + type: 'string', + choices: Object.keys(mh.names), + describe: 'Hash function to use. Will set Cid version to 1 if used. (experimental)' + }, quiet: { alias: 'q', type: 'boolean', @@ -191,7 +197,8 @@ module.exports = { : Infinity, cidVersion: argv.cidVersion, rawLeaves: argv.rawLeaves, - onlyHash: argv.onlyHash + onlyHash: argv.onlyHash, + hashAlg: argv.hash } // Temporary restriction on raw-leaves: @@ -206,6 +213,18 @@ module.exports = { throw new Error('Implied argument raw-leaves must be passed and set to false when cid-version is > 0') } + // Temporary restriction on raw-leaves: + // When hash != undefined then raw-leaves MUST be present and false. + // + // This is because raw-leaves is not yet implemented in js-ipfs, + // and go-ipfs changes the value of raw-leaves to true when + // hash != undefined unless explicitly set to false. + // + // This retains feature parity without having to implement raw-leaves. + if (options.hash && options.rawLeaves !== false) { + throw new Error('Implied argument raw-leaves must be passed and set to false when hash argument is specified') + } + if (options.rawLeaves) { throw new Error('Not implemented: raw-leaves') } diff --git a/src/core/components/files.js b/src/core/components/files.js index 3ec915065d..ee7eca713b 100644 --- a/src/core/components/files.js +++ b/src/core/components/files.js @@ -22,15 +22,15 @@ function noop () {} function prepareFile (self, opts, file, callback) { opts = opts || {} - waterfall([ - (cb) => opts.onlyHash ? cb(null, file) : self.object.get(file.multihash, cb), - (node, cb) => { - let cid = new CID(node.multihash) + let cid = new CID(file.multihash) - if (opts['cid-version'] === 1) { - cid = cid.toV1() - } + if (opts.cidVersion === 1) { + cid = cid.toV1() + } + waterfall([ + (cb) => opts.onlyHash ? cb(null, file) : self.object.get(file.multihash, opts, cb), + (node, cb) => { const b58Hash = cid.toBaseEncodedString() cb(null, { @@ -110,6 +110,10 @@ module.exports = function files (self) { : Infinity }, options) + if (opts.hashAlg && opts.cidVersion !== 1) { + opts.cidVersion = 1 + } + let total = 0 let prog = opts.progress || (() => {}) const progress = (bytes) => { @@ -182,7 +186,7 @@ module.exports = function files (self) { } return { - add: promisify((data, options, callback) => { + add: promisify((data, options = {}, callback) => { if (typeof options === 'function') { callback = options options = {} @@ -200,6 +204,11 @@ module.exports = function files (self) { return callback(new Error('first arg must be a buffer, readable stream, an object or array of objects')) } + // CID v0 is for multihashes encoded with sha2-256 + if (options.hashAlg && options.cidVersion !== 1) { + options.cidVersion = 1 + } + pull( pull.values([data]), _addPullStream(options), diff --git a/src/core/components/object.js b/src/core/components/object.js index 5ce053128f..0677eeccc4 100644 --- a/src/core/components/object.js +++ b/src/core/components/object.js @@ -191,7 +191,11 @@ module.exports = function object (self) { } catch (err) { return callback(err) } - const cid = new CID(mh) + let cid = new CID(mh) + + if (options.cidVersion === 1) { + cid = cid.toV1() + } self._ipld.get(cid, (err, result) => { if (err) { @@ -214,6 +218,7 @@ module.exports = function object (self) { if (err) { return callback(err) } + callback(null, node.data) }) }), diff --git a/src/http/api/resources/files.js b/src/http/api/resources/files.js index 91861965f3..f74cf0a7fe 100644 --- a/src/http/api/resources/files.js +++ b/src/http/api/resources/files.js @@ -207,7 +207,8 @@ exports.add = { cidVersion: request.query['cid-version'], rawLeaves: request.query['raw-leaves'], progress: request.query.progress ? progressHandler : null, - onlyHash: request.query['only-hash'] + onlyHash: request.query['only-hash'], + hashAlg: request.query['hash'] } const aborter = abortable() diff --git a/test/cli/files.js b/test/cli/files.js index 2e9fec39b5..be9a6d96a5 100644 --- a/test/cli/files.js +++ b/test/cli/files.js @@ -7,8 +7,22 @@ const expect = require('chai').expect const path = require('path') const compareDir = require('dir-compare').compareSync const rimraf = require('rimraf').sync +const CID = require('cids') +const mh = require('multihashes') const runOnAndOff = require('../utils/on-and-off') +// TODO: Test against all algorithms Object.keys(mh.names) +// This subset is known to work with both go-ipfs and js-ipfs as of 2017-09-05 +const HASH_ALGS = [ + 'sha1', + 'sha2-256', + 'sha2-512', + 'keccak-224', + 'keccak-256', + 'keccak-384', + 'keccak-512' +] + describe('files', () => runOnAndOff((thing) => { let ipfs const readme = fs.readFileSync(path.join(process.cwd(), '/src/init-files/init-docs/readme')) @@ -300,6 +314,19 @@ describe('files', () => runOnAndOff((thing) => { }) }) + HASH_ALGS.forEach((name) => { + it(`add with hash=${name} and raw-leaves=false`, function () { + this.timeout(30 * 1000) + + return ipfs(`add src/init-files/init-docs/readme --hash=${name} --raw-leaves=false`) + .then((out) => { + const hash = out.split(' ')[1] + const cid = new CID(hash) + expect(mh.decode(cid.multihash).name).to.equal(name) + }) + }) + }) + it('cat', function () { this.timeout(30 * 1000) From 5b2cf8cfe799615dbf52e87d53f7336a5d7a0210 Mon Sep 17 00:00:00 2001 From: Diogo Silva Date: Fri, 13 Apr 2018 13:06:42 +0100 Subject: [PATCH 5/7] feat: use class-is for type checks --- package.json | 52 +++++++++++++++++------------------ src/core/components/object.js | 3 +- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index b74ac3e23a..12cc68234e 100644 --- a/package.json +++ b/package.json @@ -73,8 +73,8 @@ "expose-loader": "^0.7.5", "form-data": "^2.3.2", "hat": "0.0.3", - "ipfsd-ctl": "~0.31.0", - "interface-ipfs-core": "~0.58.0", + "interface-ipfs-core": "^0.61.0", + "ipfsd-ctl": "^0.32.1", "lodash": "^4.17.5", "mocha": "^5.0.5", "ncp": "^2.0.0", @@ -106,47 +106,47 @@ "hapi-set-header": "^1.0.2", "hoek": "^5.0.3", "human-to-milliseconds": "^1.0.0", - "ipfs-api": "^19.0.0", - "ipfs-bitswap": "~0.19.0", - "ipfs-block": "~0.6.1", - "ipfs-block-service": "~0.13.0", + "ipfs-api": "^20.0.1", + "ipfs-bitswap": "~0.20.0", + "ipfs-block": "^0.7.1", + "ipfs-block-service": "~0.14.0", "ipfs-multipart": "~0.1.0", - "ipfs-repo": "~0.18.7", + "ipfs-repo": "^0.19.0", "ipfs-unixfs": "~0.1.14", - "ipfs-unixfs-engine": "~0.27.0", - "ipld": "^0.15.0", + "ipfs-unixfs-engine": "~0.28.1", + "ipld": "^0.17.0", "is-ipfs": "^0.3.2", "is-stream": "^1.1.0", "joi": "^13.1.2", "joi-browser": "^13.0.1", "joi-multiaddr": "^2.0.0", - "libp2p": "~0.19.2", - "libp2p-circuit": "~0.1.5", - "libp2p-floodsub": "~0.14.1", - "libp2p-kad-dht": "~0.9.0", + "libp2p": "^0.20.2", + "libp2p-circuit": "^0.2.0", + "libp2p-floodsub": "~0.15.0", + "libp2p-kad-dht": "~0.10.0", "libp2p-keychain": "~0.3.1", - "libp2p-mdns": "~0.9.2", - "libp2p-mplex": "^0.6.0", - "libp2p-railing": "~0.7.1", - "libp2p-secio": "~0.9.4", - "libp2p-tcp": "~0.11.6", - "libp2p-webrtc-star": "~0.13.4", - "libp2p-websocket-star": "~0.7.7", - "libp2p-websockets": "~0.10.5", + "libp2p-mdns": "~0.11.0", + "libp2p-mplex": "^0.7.0", + "libp2p-railing": "~0.8.0", + "libp2p-secio": "~0.10.0", + "libp2p-tcp": "^0.12.0", + "libp2p-webrtc-star": "0.14.0", + "libp2p-websocket-star": "^0.8.0", + "libp2p-websockets": "^0.11.0", "lodash.flatmap": "^4.5.0", "lodash.get": "^4.4.2", "lodash.sortby": "^4.7.0", "lodash.values": "^4.3.0", - "mafmt": "^4.0.0", + "mafmt": "^6.0.0", "mime-types": "^2.1.18", "mkdirp": "~0.5.1", - "multiaddr": "^3.1.0", + "multiaddr": "^4.0.0", "multihashes": "~0.4.13", "once": "^1.4.0", "path-exists": "^3.0.0", - "peer-book": "~0.5.4", - "peer-id": "~0.10.6", - "peer-info": "~0.11.6", + "peer-book": "~0.7.0", + "peer-id": "~0.10.7", + "peer-info": "~0.14.1", "progress": "^2.0.0", "promisify-es6": "^1.0.3", "pull-abortable": "^4.1.1", diff --git a/src/core/components/object.js b/src/core/components/object.js index 0677eeccc4..5e8be00e4a 100644 --- a/src/core/components/object.js +++ b/src/core/components/object.js @@ -280,8 +280,7 @@ module.exports = function object (self) { rmLink (multihash, linkRef, options, callback) { editAndSave((node, cb) => { - if (linkRef.constructor && - linkRef.constructor.name === 'DAGLink') { + if (DAGLink.isDAGLink(linkRef)) { linkRef = linkRef._name } DAGNode.rmLink(node, linkRef, cb) From 5b069450907de5ae5619c1ce81b3180a5e8fafa6 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 14 Apr 2018 20:08:21 +0900 Subject: [PATCH 6/7] docs: OKR.md (#1281) --- OKR.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 OKR.md diff --git a/OKR.md b/OKR.md new file mode 100644 index 0000000000..f2908bc776 --- /dev/null +++ b/OKR.md @@ -0,0 +1,11 @@ +# Quarterly Objectives and Key Results + +We try to frame our ongoing work using a process based on quarterly Objectives and Key Results (OKRs). Objectives reflect outcomes that are challenging, but realistic. Results are tangible and measurable. + +## 2018 Q2 + +Find the **js-ipfs OKRs** for 2018 Q2 at the [2018 Q2 IPFS OKRs Spreadsheet](https://docs.google.com/spreadsheets/d/1xIhKROxFlsY9M9on37D5rkbSsm4YtjRQvG2unHScApA/edit#gid=274358435) + +## 2018 Q1 + +Find the **js-ipfs OKRs** for 2018 Q1 at the [2018 Q1 IPFS OKRs Spreadsheet](https://docs.google.com/spreadsheets/u/1/d/1clB-W489rJpbOEs2Q7Q2Jf1WMXHQxXgccBcUJS9QTiI/edit#gid=2079514081) From 64c3bfb45cda27e268655cc9a2bce28eebd09454 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 9 Apr 2018 14:33:15 +0100 Subject: [PATCH 7/7] fix: Add ipfs path to cli help --- src/cli/bin.js | 1 + src/cli/commands/daemon.js | 20 +++++++++++--------- src/cli/commands/init.js | 7 +------ src/cli/utils.js | 4 ++++ test/cli/daemon.js | 9 +++++++++ test/cli/init.js | 9 +++++++++ 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/cli/bin.js b/src/cli/bin.js index 1d53444ac9..4e666d2a20 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -29,6 +29,7 @@ const cli = yargs default: '' }) .commandDir('commands') + .epilog(utils.ipfsPathHelp) .demandCommand(1) .fail((msg, err, yargs) => { if (err) { diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index ba9ca6ad6a..457dbc4c9d 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -11,15 +11,17 @@ module.exports = { describe: 'Start a long-running daemon process', - builder: { - 'enable-sharding-experiment': { - type: 'boolean', - default: false - }, - 'enable-pubsub-experiment': { - type: 'boolean', - default: false - } + builder (yargs) { + return yargs + .epilog(utils.ipfsPathHelp) + .option('enable-sharding-experiment', { + type: 'boolean', + default: false + }) + .option('enable-pubsub-experiment', { + type: 'boolean', + default: false + }) }, handler (argv) { diff --git a/src/cli/commands/init.js b/src/cli/commands/init.js index 920519f90c..36525419b4 100644 --- a/src/cli/commands/init.js +++ b/src/cli/commands/init.js @@ -5,19 +5,14 @@ const IPFS = require('../../core') const utils = require('../utils') const print = utils.print -const ipfsPathHelp = 'ipfs uses a repository in the local file system. By default, the repo is ' + - 'located at ~/.ipfs.\nTo change the repo location, set the $IPFS_PATH environment variable:\n\n' + - '\texport IPFS_PATH=/path/to/ipfsrepo\n' - module.exports = { command: 'init', describe: 'Initialize a local IPFS node', builder (yargs) { - print(ipfsPathHelp) - return yargs + .epilog(utils.ipfsPathHelp) .option('bits', { type: 'number', alias: 'b', diff --git a/src/cli/utils.js b/src/cli/utils.js index 37cd49010f..b0fd5ff742 100644 --- a/src/cli/utils.js +++ b/src/cli/utils.js @@ -111,3 +111,7 @@ exports.rightpad = (val, n) => { } return result } + +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' diff --git a/test/cli/daemon.js b/test/cli/daemon.js index 3245400320..4d5716df41 100644 --- a/test/cli/daemon.js +++ b/test/cli/daemon.js @@ -120,4 +120,13 @@ describe('daemon', () => { done() }) }) + + it('should present ipfs path help when option help is received', function (done) { + this.timeout(100 * 1000) + + ipfs('daemon --help').then((res) => { + expect(res).to.have.string('export IPFS_PATH=/path/to/ipfsrepo') + done() + }) + }) }) diff --git a/test/cli/init.js b/test/cli/init.js index 1c5fcf1a1d..86e0dbacda 100644 --- a/test/cli/init.js +++ b/test/cli/init.js @@ -66,4 +66,13 @@ describe('init', function () { expect(repoExistsSync('version')).to.equal(true) }) }) + + it('should present ipfs path help when option help is received', function (done) { + this.timeout(100 * 1000) + + ipfs('init --help').then((res) => { + expect(res).to.have.string('export IPFS_PATH=/path/to/ipfsrepo') + done() + }) + }) })