From 259aa8219d529cc8ebd70ef4d6681e458db9921c Mon Sep 17 00:00:00 2001 From: achingbrain Date: Wed, 16 May 2018 17:08:10 +0100 Subject: [PATCH] feat: mfs implementation License: MIT Signed-off-by: achingbrain --- README.md | 3 +- package.json | 3 +- src/cli/bin.js | 57 ++++++++++++++------------- src/cli/commands/dag/get.js | 2 +- src/cli/commands/files/get.js | 1 + src/cli/utils.js | 3 +- src/core/components/index.js | 1 + src/core/config.js | 3 +- src/core/index.js | 10 +++++ src/http/index.js | 3 +- test/cli/file.js | 8 ++-- test/cli/files.js | 46 ++++++++++----------- test/cli/init.js | 2 +- test/cli/ls.js | 18 ++++----- test/core/interface/files-mfs.js | 38 ++++++++++++++++++ test/core/interface/interface.spec.js | 1 + test/utils/ipfs-exec.js | 2 +- 17 files changed, 129 insertions(+), 72 deletions(-) create mode 100644 test/core/interface/files-mfs.js diff --git a/README.md b/README.md index a373615839..0b230a274e 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,8 @@ Creates and returns an instance of an IPFS node. Use the `options` argument to s - `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`) - + - `mfs` (boolean): Enables Mutable File System commands - see `jsipfs files --help` for more (Default: `false`) + - `config` (object) Modify the default IPFS node config. Find the Node.js defaults at [`src/core/runtime/config-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-nodejs.js) and the browser defaults at [`src/core/runtime/config-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-browser.js). 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 diff --git a/package.json b/package.json index b9658e3f22..a807382c40 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "expose-loader": "~0.7.5", "form-data": "^2.3.2", "hat": "~0.0.3", - "interface-ipfs-core": "~0.65.7", + "interface-ipfs-core": "~0.66.2", "ipfsd-ctl": "~0.34.0", "lodash": "^4.17.10", "mocha": "^5.1.1", @@ -109,6 +109,7 @@ "ipfs-bitswap": "~0.20.0", "ipfs-block": "~0.7.1", "ipfs-block-service": "~0.14.0", + "ipfs-mfs": "~0.0.1", "ipfs-multipart": "~0.1.0", "ipfs-repo": "~0.20.0", "ipfs-unixfs": "~0.1.14", diff --git a/src/cli/bin.js b/src/cli/bin.js index 2ccf2f66a0..e75b1b8971 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -5,8 +5,6 @@ const yargs = require('yargs') const updateNotifier = require('update-notifier') const readPkgUp = require('read-pkg-up') -const fs = require('fs') -const path = require('path') const utils = require('./utils') const print = utils.print @@ -18,10 +16,6 @@ updateNotifier({ const args = process.argv.slice(2) -// Determine if the first argument is a sub-system command -const commandNames = fs.readdirSync(path.join(__dirname, 'commands')) -const isCommand = commandNames.includes(`${args[0]}.js`) - const cli = yargs .option('silent', { desc: 'Write no output', @@ -34,14 +28,6 @@ const cli = yargs type: 'string', default: '' }) - .commandDir('commands', { - // Only include the commands for the sub-system we're using, or include all - // if no sub-system command has been passed. - include (path, filename) { - if (!isCommand) return true - return `${args[0]}.js` === filename - } - }) .epilog(utils.ipfsPathHelp) .demandCommand(1) .fail((msg, err, yargs) => { @@ -56,20 +42,6 @@ const cli = yargs yargs.showHelp() }) -// If not a sub-system command then load the top level aliases -if (!isCommand) { - // NOTE: This creates an alias of - // `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`. - // This will stay until https://github.com/ipfs/specs/issues/98 is resolved. - const addCmd = require('./commands/files/add') - const catCmd = require('./commands/files/cat') - const getCmd = require('./commands/files/get') - const aliases = [addCmd, catCmd, getCmd] - aliases.forEach((alias) => { - cli.command(alias.command, alias.describe, alias.builder, alias.handler) - }) -} - // Need to skip to avoid locking as these commands // don't require a daemon if (args[0] === 'daemon' || args[0] === 'init') { @@ -77,6 +49,8 @@ if (args[0] === 'daemon' || args[0] === 'init') { .help() .strict() .completion() + .command(require('./commands/daemon')) + .command(require('./commands/init')) .parse(args) } else { // here we have to make a separate yargs instance with @@ -86,10 +60,37 @@ if (args[0] === 'daemon' || args[0] === 'init') { if (err) { throw err } + utils.getIPFS(argv, (err, ipfs, cleanup) => { if (err) { throw err } + const enableMfs = ipfs._options && ipfs._options.EXPERIMENTAL && ipfs._options && ipfs._options.EXPERIMENTAL.mfs + + if (enableMfs) { + require('ipfs-mfs/cli')(cli) + } + + // NOTE: This creates an alias of + // `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`. + // This will stay until https://github.com/ipfs/specs/issues/98 is resolved. + const addCmd = require('./commands/files/add') + const catCmd = require('./commands/files/cat') + const getCmd = require('./commands/files/get') + const aliases = [addCmd, catCmd, getCmd] + aliases.forEach((alias) => { + cli.command(alias) + }) + cli + .commandDir('commands', { + visit: (commandObject, pathToFile, filename) => { + if (commandObject.command === 'files ' && enableMfs) { + return null + } + + return commandObject + } + }) .help() .strict() .completion() diff --git a/src/cli/commands/dag/get.js b/src/cli/commands/dag/get.js index 6088d2eb34..d2795f7829 100644 --- a/src/cli/commands/dag/get.js +++ b/src/cli/commands/dag/get.js @@ -41,7 +41,7 @@ module.exports = { // * reads as 'agree in' if (node._json) { delete node._json.multihash - node._json.data = '0x' + node._json.data.toString('hex') + node._json.data = node._json.data.toString('base64') print(JSON.stringify(node._json)) return } diff --git a/src/cli/commands/files/get.js b/src/cli/commands/files/get.js index c177fb8719..d9e0a39a67 100644 --- a/src/cli/commands/files/get.js +++ b/src/cli/commands/files/get.js @@ -30,6 +30,7 @@ function fileHandler (dir) { callback(err) } else { const fullFilePath = path.join(dir, file.path) + if (file.content) { file.content .pipe(fs.createWriteStream(fullFilePath)) diff --git a/src/cli/utils.js b/src/cli/utils.js index f993e0caef..3336e811c5 100644 --- a/src/cli/utils.js +++ b/src/cli/utils.js @@ -51,7 +51,8 @@ exports.getIPFS = (argv, callback) => { start: false, pass: argv.pass, EXPERIMENTAL: { - pubsub: true + pubsub: true, + mfs: Boolean(process.env.IPFS_MFS) } }) diff --git a/src/core/components/index.js b/src/core/components/index.js index 4f4e410e43..b7f2b5970f 100644 --- a/src/core/components/index.js +++ b/src/core/components/index.js @@ -23,3 +23,4 @@ exports.dht = require('./dht') exports.dns = require('./dns') exports.key = require('./key') exports.stats = require('./stats') +exports.mfs = require('ipfs-mfs/core') diff --git a/src/core/config.js b/src/core/config.js index 493a30e5eb..82635162c4 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -16,7 +16,8 @@ const schema = Joi.object().keys({ EXPERIMENTAL: Joi.object().keys({ pubsub: Joi.boolean(), sharding: Joi.boolean(), - dht: Joi.boolean() + dht: Joi.boolean(), + mfs: Joi.boolean() }).allow(null), config: Joi.object().keys({ Addresses: Joi.object().keys({ diff --git a/src/core/index.js b/src/core/index.js index 46f8c9bb2c..5a2989617c 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -120,6 +120,16 @@ class IPFS extends EventEmitter { if (this._options.EXPERIMENTAL.relay) { this.log('EXPERIMENTAL Relay is enabled') } + if (this._options.EXPERIMENTAL.mfs) { + this.log('EXPERIMENTAL mfs is enabled') + const mfs = components.mfs(this) + + Object.keys(mfs).forEach(key => { + if (mfs.hasOwnProperty(key)) { + this.files[key] = mfs[key] + } + }) + } this.state = require('./state')(this) diff --git a/src/http/index.js b/src/http/index.js index 93a5ec172e..484b03885b 100644 --- a/src/http/index.js +++ b/src/http/index.js @@ -71,7 +71,8 @@ function HttpApi (repo, config, cliArgs) { EXPERIMENTAL: { pubsub: cliArgs && cliArgs.enablePubsubExperiment, dht: cliArgs && cliArgs.enableDhtExperiment, - sharding: cliArgs && cliArgs.enableShardingExperiment + sharding: cliArgs && cliArgs.enableShardingExperiment, + mfs: cliArgs && cliArgs.enableMfsExperiment }, libp2p: libp2p }) diff --git a/test/cli/file.js b/test/cli/file.js index afe4d98db0..e4a5e0c9ce 100644 --- a/test/cli/file.js +++ b/test/cli/file.js @@ -4,7 +4,7 @@ const expect = require('chai').expect const runOnAndOff = require('../utils/on-and-off') const file = 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV' -const dir = 'QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2' +const dir = 'Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z' describe('file ls', () => runOnAndOff((thing) => { let ipfs @@ -12,7 +12,7 @@ describe('file ls', () => runOnAndOff((thing) => { before(function () { this.timeout(50 * 1000) ipfs = thing.ipfs - return ipfs('files add -r test/fixtures/test-data/recursive-get-dir') + return ipfs('add -r test/fixtures/test-data/recursive-get-dir') }) it('prints a filename', () => { @@ -27,9 +27,9 @@ describe('file ls', () => runOnAndOff((thing) => { return ipfs(`file ls ${dir}`) .then((out) => expect(out).to.eql( `This functionality is deprecated, and will be removed in future versions. If possible, please use 'ipfs ls' instead.\n` + - 'QmQQHYDwAQms78fPcvx1uFFsfho23YJNoewfLbi9AtdyJ9\n' + + 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT\n' + 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN\n' + - 'Qma13ZrhKG52MWnwtZ6fMD8jGj8d4Q9sJgn5xtKgeZw5uz\n' + + 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv\n' + 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU\n' + 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV\n' )) diff --git a/test/cli/files.js b/test/cli/files.js index 07b5421aa7..6dd19614e3 100644 --- a/test/cli/files.js +++ b/test/cli/files.js @@ -44,12 +44,12 @@ describe('files', () => runOnAndOff((thing) => { 'added QmeiTxVN4xAjxUzHzBqCpK3GaT3GeiLQeJRpYDXDfLeEmR recursive-get-dir/datastore/MANIFEST-000014', 'added QmQpc75sJGUv59dAwHF7vazBGV9o6C7z587Dp9nv7HYAps recursive-get-dir/datastore/LOG.old', 'added QmbFNLNr9at9eK5LrNyUdyE5cdLb5yaT9DkjXw7BK68kcM recursive-get-dir/datastore/LOG', - 'added QmfJMCvenrj4SKKRc48DYPxwVdS44qCUCqqtbqhJuSTWXP recursive-get-dir/datastore/LOCK', + 'added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH recursive-get-dir/datastore/LOCK', 'added QmVJi93Yj5RW3NuqqxonGz3jAXUYHrdQvWrURxg1TiLEuX recursive-get-dir/datastore/CURRENT', 'added QmcJ6TXPMPm6puSC9vpxuG57PyfGpr8bvTgkKU9SHHU5Uo recursive-get-dir/datastore/000010.ldb', 'added QmPFVLPmp9zv5Z5KUqLhe2EivAGccQW2r7M7jhVJGLZoZU recursive-get-dir/datastore/000005.ldb', 'added QmfExFwdFKspsY2q5WnhQjd1QDKnjpTQ4UkiHqqQxV7h67 recursive-get-dir/datastore/000002.ldb', - 'added Qma13ZrhKG52MWnwtZ6fMD8jGj8d4Q9sJgn5xtKgeZw5uz recursive-get-dir/datastore', + 'added QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv recursive-get-dir/datastore', 'added QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN recursive-get-dir/config', 'added QmbJgQa4XNBFvGQcLbWBNtvWZetbCUKiyAQNfePoTzwf9L recursive-get-dir/blocks/CIQPD/CIQPDQJBGYDZNMOAGGYNRNMP2VDKWBWGAEDDEJDACM3SGG3VIANDDXI.data', 'added QmSCUPYy4CfFt9nA61J9v2DMfJygQAJjaUcRmygDbVME2D recursive-get-dir/blocks/CIQPD', @@ -61,8 +61,8 @@ describe('files', () => runOnAndOff((thing) => { 'added Qmec4atiyfysPR8HU5gPfjKY1NpQDY2kmSeeadx8wLEBqY recursive-get-dir/blocks/CIQOM', 'added QmeBypQ2yE4t4Loybhby15DjkeLDXJKCcgMfxTXeFnHa8F recursive-get-dir/blocks/CIQOL/CIQOLBQZSZAODJGGH6RYYVBUXHTS3SM5EORZDU63LYPEFUAFE4SBM4I.data', 'added Qmd6s8LXAEjW7y9QbGSzeuewrRBYjJHmcazG3Hk7cJ74da recursive-get-dir/blocks/CIQOL', - 'added QmfJMCvenrj4SKKRc48DYPxwVdS44qCUCqqtbqhJuSTWXP recursive-get-dir/blocks/CIQOH/CIQOHMGEIKMPYHAUTL57JSEZN64SIJ5OIHSGJG4TJSSJLGI3PBJLQVI.data', - 'added QmdiJnDhn4Bb1odByw1BA5qpXssjxgttVz42tpEfo7HNUe recursive-get-dir/blocks/CIQOH', + 'added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH recursive-get-dir/blocks/CIQOH/CIQOHMGEIKMPYHAUTL57JSEZN64SIJ5OIHSGJG4TJSSJLGI3PBJLQVI.data', + 'added QmTnaav9VTSVyLu8PvRzh4gJ8heF9rpdWzeDb7rMx5DkxV recursive-get-dir/blocks/CIQOH', 'added Qmc1nasezDdPyZiXB5VB6Aygzswcr6QkauzzXMeUGouHTN recursive-get-dir/blocks/CIQMB/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data', 'added QmeqJBkwmzsVR79HBKLW7AYhfAMxMaJs5dGHSgey5ezy7N recursive-get-dir/blocks/CIQMB', 'added QmaSjzSSRanYzRGPXQY6m5SWfSkkfcnzNkurJEQc4chPJx recursive-get-dir/blocks/CIQLB/CIQLBS5HG4PRCRQ7O4EBXFD5QN6MTI5YBYMCVQJDXPKCOVR6RMLHZFQ.data', @@ -113,8 +113,8 @@ describe('files', () => runOnAndOff((thing) => { 'added QmSCq2peGvGDXZKuX565UczxRpgzsiPPF3PgcJq9zDbByL recursive-get-dir/blocks/CIQDD', 'added QmdgaiKe1HFfhrZvLwTFCrXmgTojhSWuBvyFXUVc8KzJVc recursive-get-dir/blocks/CIQBE/CIQBED3K6YA5I3QQWLJOCHWXDRK5EXZQILBCKAPEDUJENZ5B5HJ5R3A.data', 'added QmYwUkwNwJN2cevwXKL48DRpbbjbdLWyyLANG3BKTtsTZ8 recursive-get-dir/blocks/CIQBE', - 'added QmQQHYDwAQms78fPcvx1uFFsfho23YJNoewfLbi9AtdyJ9 recursive-get-dir/blocks', - 'added QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2 recursive-get-dir' + 'added QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT recursive-get-dir/blocks', + 'added Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z recursive-get-dir' ] before(() => { @@ -124,7 +124,7 @@ describe('files', () => runOnAndOff((thing) => { it('add with progress', function () { this.timeout(30 * 1000) - return ipfs('files add -p src/init-files/init-docs/readme') + return ipfs('add -p src/init-files/init-docs/readme') .then((out) => { expect(out) .to.eql('added QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB readme\n') @@ -134,7 +134,7 @@ describe('files', () => runOnAndOff((thing) => { it('add', function () { this.timeout(30 * 1000) - return ipfs('files add src/init-files/init-docs/readme') + return ipfs('add src/init-files/init-docs/readme') .then((out) => { expect(out) .to.eql('added QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB readme\n') @@ -154,7 +154,7 @@ describe('files', () => runOnAndOff((thing) => { it('add recursively test', function () { this.timeout(60 * 1000) - return ipfs('files add -r test/fixtures/test-data/recursive-get-dir') + return ipfs('add -r test/fixtures/test-data/recursive-get-dir') .then((out) => { expect(out).to.eql(recursiveGetDirResults.join('\n') + '\n') }) @@ -163,7 +163,7 @@ describe('files', () => runOnAndOff((thing) => { it('add directory with trailing slash test', function () { this.timeout(30 * 1000) - return ipfs('files add -r test/fixtures/test-data/recursive-get-dir/') + return ipfs('add -r test/fixtures/test-data/recursive-get-dir/') .then((out) => { expect(out).to.eql(recursiveGetDirResults.join('\n') + '\n') }) @@ -177,7 +177,7 @@ describe('files', () => runOnAndOff((thing) => { 'added QmXJGoo27bg7ExNAtr9vRcivxDwcfHtkxatGno9HrUdR16 odd-name-[v0]' ] - return ipfs('files add -r test/fixtures/odd-name-[v0]') + return ipfs('add -r test/fixtures/odd-name-[v0]') .then((out) => { expect(out).to.eql(expected.join('\n') + '\n') }) @@ -258,7 +258,7 @@ describe('files', () => runOnAndOff((thing) => { it('add --quiet', function () { this.timeout(30 * 1000) - return ipfs('files add -q src/init-files/init-docs/readme') + return ipfs('add -q src/init-files/init-docs/readme') .then((out) => { expect(out) .to.eql('added QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB\n') @@ -268,7 +268,7 @@ describe('files', () => runOnAndOff((thing) => { it('add --quieter', function () { this.timeout(30 * 1000) - return ipfs('files add -Q -w test/fixtures/test-data/hello test/test-data/node.json') + return ipfs('add -Q -w test/fixtures/test-data/hello test/test-data/node.json') .then((out) => { expect(out) .to.eql('QmYRMUVULBfj7WrdPESnwnyZmtayN6Sdrwh1nKcQ9QgQeZ\n') @@ -278,7 +278,7 @@ describe('files', () => runOnAndOff((thing) => { it('add --silent', function () { this.timeout(30 * 1000) - return ipfs('files add --silent src/init-files/init-docs/readme') + return ipfs('add --silent src/init-files/init-docs/readme') .then((out) => { expect(out) .to.eql('') @@ -286,7 +286,7 @@ describe('files', () => runOnAndOff((thing) => { }) it('add --only-hash outputs correct hash', function () { - return ipfs('files add --only-hash src/init-files/init-docs/readme') + return ipfs('add --only-hash src/init-files/init-docs/readme') .then(out => expect(out) .to.eql('added QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB readme\n') @@ -330,7 +330,7 @@ describe('files', () => runOnAndOff((thing) => { it('cat', function () { this.timeout(30 * 1000) - return ipfs('files cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB') + return ipfs('cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB') .then((out) => { expect(out).to.eql(readme) }) @@ -348,7 +348,7 @@ describe('files', () => runOnAndOff((thing) => { it('cat part of a file using `count`', function () { this.timeout(30 * 1000) - return ipfs('files cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB --offset 21 --count 5') + return ipfs('cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB --offset 21 --count 5') .then((out) => { expect(out).to.eql(readme.substring(21, 26)) }) @@ -357,7 +357,7 @@ describe('files', () => runOnAndOff((thing) => { it('cat part of a file using `length`', function () { this.timeout(30 * 1000) - return ipfs('files cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB --offset 21 --length 5') + return ipfs('cat QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB --offset 21 --length 5') .then((out) => { expect(out).to.eql(readme.substring(21, 26)) }) @@ -374,7 +374,7 @@ describe('files', () => runOnAndOff((thing) => { it('get', function () { this.timeout(20 * 1000) - return ipfs('files get QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB') + return ipfs('get QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB') .then((out) => { expect(out) .to.eql('Saving file(s) QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB\n') @@ -406,16 +406,16 @@ describe('files', () => runOnAndOff((thing) => { it('get recursively', function () { this.timeout(20 * 1000) - const outDir = path.join(process.cwd(), 'QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2') + const outDir = path.join(process.cwd(), 'Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z') rimraf(outDir) - return ipfs('files get QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2') + return ipfs('get Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z') .then((out) => { expect(out).to.eql( - 'Saving file(s) QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2\n' + 'Saving file(s) Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z\n' ) - const outDir = path.join(process.cwd(), 'QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2') + const outDir = path.join(process.cwd(), 'Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z') const expectedDir = path.join(process.cwd(), 'test', 'fixtures', 'test-data', 'recursive-get-dir') const compareResult = compareDir(outDir, expectedDir, { diff --git a/test/cli/init.js b/test/cli/init.js index 86e0dbacda..b1a826c1db 100644 --- a/test/cli/init.js +++ b/test/cli/init.js @@ -42,7 +42,7 @@ describe('init', function () { // Test that the following was written when init-ing the repo // jsipfs files cat /ipfs/QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr/readme - let command = out.substring(out.indexOf('files cat'), out.length - 2 /* omit the newline char */) + let command = out.substring(out.indexOf('cat'), out.length - 2 /* omit the newline char */) return ipfs(command) }).then((out) => expect(out).to.equal(readme)) }) diff --git a/test/cli/ls.js b/test/cli/ls.js index 68acb5bcf3..4eccf82c07 100644 --- a/test/cli/ls.js +++ b/test/cli/ls.js @@ -9,17 +9,17 @@ describe('ls', () => runOnAndOff((thing) => { before(() => { ipfs = thing.ipfs - return ipfs('files add -r test/fixtures/test-data/recursive-get-dir') + return ipfs('add -r test/fixtures/test-data/recursive-get-dir') }) it('prints added files', function () { this.timeout(20 * 1000) - return ipfs('ls QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2') + return ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z') .then((out) => { expect(out).to.eql( - 'QmQQHYDwAQms78fPcvx1uFFsfho23YJNoewfLbi9AtdyJ9 123530 blocks/\n' + + 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT 123530 blocks/\n' + 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3939 config\n' + - 'Qma13ZrhKG52MWnwtZ6fMD8jGj8d4Q9sJgn5xtKgeZw5uz 5503 datastore/\n' + + 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv 5503 datastore/\n' + 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU 7397 init-docs/\n' + 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 10 version\n' ) @@ -38,13 +38,13 @@ describe('ls', () => runOnAndOff((thing) => { it('adds a header, -v', function () { this.timeout(20 * 1000) - return ipfs('ls /ipfs/QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2 -v') + return ipfs('ls /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z -v') .then((out) => { expect(out).to.eql( 'Hash Size Name\n' + - 'QmQQHYDwAQms78fPcvx1uFFsfho23YJNoewfLbi9AtdyJ9 123530 blocks/\n' + + 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT 123530 blocks/\n' + 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3939 config\n' + - 'Qma13ZrhKG52MWnwtZ6fMD8jGj8d4Q9sJgn5xtKgeZw5uz 5503 datastore/\n' + + 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv 5503 datastore/\n' + 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU 7397 init-docs/\n' + 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 10 version\n' ) @@ -54,7 +54,7 @@ describe('ls', () => runOnAndOff((thing) => { it('follows a path, /', function () { this.timeout(20 * 1000) - return ipfs('ls /ipfs/QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2/init-docs') + return ipfs('ls /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/init-docs') .then((out) => { expect(out).to.eql( 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1688 about\n' + @@ -73,7 +73,7 @@ describe('ls', () => runOnAndOff((thing) => { this.slow(2000) this.timeout(20 * 1000) - return ipfs('ls -r /ipfs/QmYmW4HiZhotsoSqnv2o1oUusvkRM8b9RweBoH7ao5nki2/init-docs') + return ipfs('ls -r /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/init-docs') .then(out => { expect(out).to.eql( 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1688 about\n' + diff --git a/test/core/interface/files-mfs.js b/test/core/interface/files-mfs.js new file mode 100644 index 0000000000..1941205cc0 --- /dev/null +++ b/test/core/interface/files-mfs.js @@ -0,0 +1,38 @@ +/* eslint-env mocha */ +'use strict' + +const test = require('interface-ipfs-core') +const parallel = require('async/parallel') + +const IPFS = require('../../../src') + +process.env.IPFS_MFS = true + +const DaemonFactory = require('ipfsd-ctl') +const df = DaemonFactory.create({ type: 'proc', exec: IPFS }) + +const nodes = [] +const common = { + setup: function (callback) { + callback(null, { + spawnNode: (cb) => { + df.spawn({ + initOptions: { bits: 1024 }, + args: ['--enable-mfs-experiment'] + }, (err, _ipfsd) => { + if (err) { + return cb(err) + } + + nodes.push(_ipfsd) + cb(null, _ipfsd.api) + }) + } + }) + }, + teardown: function (callback) { + parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) + } +} + +test.filesMFS(common) diff --git a/test/core/interface/interface.spec.js b/test/core/interface/interface.spec.js index 810b7f2198..47f204889c 100644 --- a/test/core/interface/interface.spec.js +++ b/test/core/interface/interface.spec.js @@ -9,6 +9,7 @@ describe('interface-ipfs-core tests', () => { require('./bootstrap') require('./config') require('./files') + require('./files-mfs') require('./generic') require('./object') require('./dag') diff --git a/test/utils/ipfs-exec.js b/test/utils/ipfs-exec.js index 2437f136a9..59876b787f 100644 --- a/test/utils/ipfs-exec.js +++ b/test/utils/ipfs-exec.js @@ -13,7 +13,7 @@ const _ = require('lodash') // The top level export is a function that can be passed a `repoPath` // and optional `opts` to customize the execution of the commands. // This function returns the actual executer, which consists of -// `ipfs('files get ')` and `ipfs.fail('files get ')` +// `ipfs('get ')` and `ipfs.fail('files get ')` // The first one executes and asserts that the command ran successfully // and returns a promise which is resolved to `stdout` of the command. // The `.fail` variation asserts that the command exited with `Code > 0`