diff --git a/.travis.yml b/.travis.yml index ff1813beb8..1672d57a02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,28 +76,44 @@ jobs: - stage: test name: interop - node script: + - mkdir -p node_modules/ipfs-interop/node_modules + - ln -s `pwd` node_modules/ipfs-interop/node_modules/ipfs + - export IPFS_JS_EXEC=`pwd`/src/cli/bin.js + - export IPFS_REUSEPORT=false - cd node_modules/ipfs-interop - - IPFS_JS_EXEC=./../../src/cli/bin.js IPFS_REUSEPORT=false npx aegir test -t node --bail + - npx aegir test -t node --bail - stage: test name: interop - browser script: + - mkdir -p node_modules/ipfs-interop/node_modules + - ln -s `pwd` node_modules/ipfs-interop/node_modules/ipfs + - export IPFS_JS_EXEC=`pwd`/src/cli/bin.js + - export IPFS_REUSEPORT=false - cd node_modules/ipfs-interop - - IPFS_JS_EXEC=./../../src/cli/bin.js IPFS_REUSEPORT=false npx aegir test -t browser --bail + - npx aegir test -t browser --bail - stage: test name: interop - electron-main os: osx script: + - mkdir -p node_modules/ipfs-interop/node_modules + - ln -s `pwd` node_modules/ipfs-interop/node_modules/ipfs + - export IPFS_JS_EXEC=`pwd`/src/cli/bin.js + - export IPFS_REUSEPORT=false - cd node_modules/ipfs-interop - - IPFS_JS_EXEC=./../../src/cli/bin.js IPFS_REUSEPORT=false npx aegir test -t electron-main -f ./test/node.js --bail --timeout 10000 + - npx aegir test -t electron-main -f ./test/node.js --bail --timeout 10000 - stage: test name: interop - electron-renderer os: osx script: + - mkdir -p node_modules/ipfs-interop/node_modules + - ln -s `pwd` node_modules/ipfs-interop/node_modules/ipfs + - export IPFS_JS_EXEC=`pwd`/src/cli/bin.js + - export IPFS_REUSEPORT=false - cd node_modules/ipfs-interop - - IPFS_JS_EXEC=./../../src/cli/bin.js IPFS_REUSEPORT=false npx aegir test -t electron-renderer -f ./test/browser.js --bail --timeout 10000 + - npx aegir test -t electron-renderer -f ./test/browser.js --bail --timeout 10000 - stage: test name: external - ipfs-companion @@ -142,6 +158,7 @@ jobs: - stage: test name: example - browser-add-readable-stream script: + - npm run build - cd examples - npm install - npm run test -- browser-add-readable-stream @@ -149,6 +166,7 @@ jobs: - stage: test name: example - browser-browserify script: + - npm run build - cd examples - npm install - npm run test -- browser-browserify @@ -156,6 +174,7 @@ jobs: - stage: test name: example - browser-create-react-app script: + - npm run build - cd examples - npm install - npm run test -- browser-create-react-app @@ -163,6 +182,7 @@ jobs: - stage: test name: example - browser-mfs script: + - npm run build - cd examples - npm install - npm run test -- browser-mfs @@ -170,6 +190,7 @@ jobs: - stage: test name: example - browser-parceljs script: + - npm run build - cd examples - npm install - npm run test -- browser-parceljs @@ -177,6 +198,7 @@ jobs: - stage: test name: example - browser-readablestream script: + - npm run build - cd examples - npm install - npm run test -- browser-readablestream @@ -184,6 +206,7 @@ jobs: - stage: test name: example - browser-script-tag script: + - npm run build - cd examples - npm install - npm run test -- browser-script-tag @@ -191,6 +214,7 @@ jobs: - stage: test name: example - browser-video-streaming script: + - npm run build - cd examples - npm install - npm run test -- browser-video-streaming @@ -198,6 +222,7 @@ jobs: - stage: test name: example - browser-vue script: + - npm run build - cd examples - npm install - npm run test -- browser-vue @@ -205,6 +230,7 @@ jobs: - stage: test name: example - browser-webpack script: + - npm run build - cd examples - npm install - npm run test -- browser-webpack @@ -212,6 +238,7 @@ jobs: - stage: test name: example - circuit-relaying script: + - npm run build - cd examples - npm install - npm run test -- circuit-relaying @@ -219,6 +246,7 @@ jobs: - stage: test name: example - custom-ipfs-repo script: + - npm run build - cd examples - npm install - npm run test -- custom-ipfs-repo @@ -226,6 +254,7 @@ jobs: - stage: test name: example - custom-libp2p script: + - npm run build - cd examples - npm install - npm run test -- custom-libp2p @@ -233,6 +262,7 @@ jobs: - stage: test name: example - exchange-files-in-browser script: + - npm run build - cd examples - npm install - npm run test -- exchange-files-in-browser @@ -240,6 +270,7 @@ jobs: - stage: test name: example - explore-ethereum-blockchain script: + - npm run build - cd examples - npm install - npm run test -- explore-ethereum-blockchain @@ -247,6 +278,7 @@ jobs: - stage: test name: example - ipfs-101 script: + - npm run build - cd examples - npm install - npm run test -- ipfs-101 @@ -254,6 +286,7 @@ jobs: - stage: test name: example - running-multiple-nodes script: + - npm run build - cd examples - npm install - npm run test -- running-multiple-nodes @@ -261,6 +294,7 @@ jobs: - stage: test name: example - traverse-ipld-graphs script: + - npm run build - cd examples - npm install - npm run test -- traverse-ipld-graphs diff --git a/examples/running-multiple-nodes/test.js b/examples/running-multiple-nodes/test.js index ea0871d7d1..76eefe9cf2 100644 --- a/examples/running-multiple-nodes/test.js +++ b/examples/running-multiple-nodes/test.js @@ -1,6 +1,6 @@ 'use strict' -const IPFS = require('ipfs') +const IPFS = require('../../') const execa = require('execa') const os = require('os') diff --git a/package.json b/package.json index affff2aa55..46b4688970 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "class-is": "^1.1.0", "dag-cbor-links": "^1.3.2", "datastore-core": "~0.7.0", - "datastore-pubsub": "^0.2.1", + "datastore-pubsub": "^0.2.3", "debug": "^4.1.0", "dlv": "^1.1.3", "err-code": "^2.0.0", @@ -95,18 +95,18 @@ "hashlru": "^2.3.0", "human-to-milliseconds": "^2.0.0", "interface-datastore": "~0.8.0", - "ipfs-bitswap": "^0.26.0", + "ipfs-bitswap": "^0.26.2", "ipfs-block": "~0.8.1", "ipfs-block-service": "~0.16.0", - "ipfs-http-client": "^40.1.0", + "ipfs-http-client": "^40.2.0", "ipfs-http-response": "~0.4.0", - "ipfs-mfs": "^0.13.2", - "ipfs-multipart": "^0.2.0", + "ipfs-mfs": "^0.14.0", + "ipfs-multipart": "^0.3.0", "ipfs-repo": "^0.30.0", - "ipfs-unixfs": "~0.1.16", - "ipfs-unixfs-exporter": "^0.38.0", - "ipfs-unixfs-importer": "^0.42.0", - "ipfs-utils": "~0.4.0", + "ipfs-unixfs": "^0.3.0", + "ipfs-unixfs-exporter": "^0.40.0", + "ipfs-unixfs-importer": "^0.43.0", + "ipfs-utils": "^0.4.2", "ipld": "~0.25.0", "ipld-bitcoin": "~0.3.0", "ipld-dag-cbor": "~0.15.0", @@ -137,7 +137,7 @@ "libp2p-floodsub": "^0.18.0", "libp2p-gossipsub": "~0.0.5", "libp2p-kad-dht": "~0.16.0", - "libp2p-keychain": "^0.5.2", + "libp2p-keychain": "^0.5.4", "libp2p-mdns": "~0.12.0", "libp2p-record": "~0.7.0", "libp2p-secio": "~0.11.0", @@ -154,7 +154,7 @@ "multiaddr": "^6.1.1", "multiaddr-to-uri": "^5.0.0", "multibase": "~0.6.0", - "multicodec": "~0.5.5", + "multicodec": "^1.0.0", "multihashes": "~0.4.14", "multihashing-async": "^0.8.0", "node-fetch": "^2.3.0", @@ -204,8 +204,8 @@ "execa": "^3.0.0", "form-data": "^3.0.0", "hat": "0.0.3", - "interface-ipfs-core": "^0.125.0", - "ipfs-interop": "^0.1.1", + "interface-ipfs-core": "^0.126.0", + "ipfs-interop": "^0.2.0", "ipfsd-ctl": "^1.0.2", "libp2p-websocket-star": "~0.10.2", "lodash": "^4.17.15", diff --git a/src/cli/commands/add.js b/src/cli/commands/add.js index e60e0c78c0..052982e3f5 100644 --- a/src/cli/commands/add.js +++ b/src/cli/commands/add.js @@ -122,6 +122,50 @@ module.exports = { type: 'boolean', default: false, describe: 'Include files that are hidden. Only takes effect on recursive add.' + }, + 'preserve-mode': { + type: 'boolean', + default: false, + describe: 'Apply permissions to created UnixFS entries' + }, + 'preserve-mtime': { + type: 'boolean', + default: false, + describe: 'Apply modification time to created UnixFS entries' + }, + mode: { + type: 'string', + describe: 'File mode to apply to created UnixFS entries' + }, + mtime: { + type: 'number', + coerce: (value) => { + value = parseInt(value) + + if (isNaN(value)) { + throw new Error('mtime must be a number') + } + + return value + }, + describe: 'Modification time in seconds before or since the Unix Epoch to apply to created UnixFS entries' + }, + 'mtime-nsecs': { + type: 'number', + coerce: (value) => { + value = parseInt(value) + + if (isNaN(value)) { + throw new Error('mtime-nsecs must be a number') + } + + if (value < 0 || value > 999999999) { + throw new Error('mtime-nsecs must be in the range [0,999999999]') + } + + return value + }, + describe: 'Modification time fraction in nanoseconds' } }, @@ -171,9 +215,28 @@ module.exports = { } } + let mtime + + if (argv.mtime != null) { + mtime = { + secs: argv.mtime + } + + if (argv.mtimeNsecs != null) { + mtime.nsecs = argv.mtimeNsecs + } + } + const source = argv.file - ? globSource(argv.file, { recursive: argv.recursive, hidden: argv.hidden }) - : process.stdin // Pipe directly to ipfs.add + ? globSource(argv.file, { + recursive: argv.recursive, + hidden: argv.hidden, + preserveMode: argv.preserveMode, + preserveMtime: argv.preserveMtime, + mode: argv.mode, + mtime + }) + : argv.getStdin() // Pipe directly to ipfs.add let finalHash diff --git a/src/cli/commands/block/put.js b/src/cli/commands/block/put.js index 78bfac9fe0..6d3862da80 100644 --- a/src/cli/commands/block/put.js +++ b/src/cli/commands/block/put.js @@ -44,7 +44,7 @@ module.exports = { data = await promisify(fs.readFile)(argv.block) } else { data = await new Promise((resolve, reject) => { - process.stdin.pipe(bl((err, input) => { + argv.getStdin().pipe(bl((err, input) => { if (err) return reject(err) resolve(input) })) diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index f018362e99..2c345221b3 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -48,6 +48,7 @@ module.exports = { handler (argv) { argv.resolve((async () => { const { print } = argv + print('Initializing IPFS daemon...') print(`js-ipfs version: ${require('../../../package.json').version}`) print(`System version: ${os.arch()}/${os.platform()}`) diff --git a/src/cli/commands/dag/put.js b/src/cli/commands/dag/put.js index 5c469d8c6c..1234fe993c 100644 --- a/src/cli/commands/dag/put.js +++ b/src/cli/commands/dag/put.js @@ -79,7 +79,7 @@ module.exports = { } }, - handler ({ data, format, inputEncoding, pin, hashAlg, cidVersion, cidBase, preload, onlyHash, getIpfs, print, resolve }) { + handler ({ data, format, inputEncoding, pin, hashAlg, cidVersion, cidBase, preload, onlyHash, getIpfs, print, resolve, getStdin }) { resolve((async () => { const ipfs = await getIpfs() @@ -101,7 +101,7 @@ module.exports = { // pipe from stdin source = Buffer.alloc(0) - for await (const buf of process.stdin) { + for await (const buf of getStdin()) { source = Buffer.concat([source, buf]) } } else { diff --git a/src/cli/commands/ls.js b/src/cli/commands/ls.js index c79eaeee04..56fc6a3685 100644 --- a/src/cli/commands/ls.js +++ b/src/cli/commands/ls.js @@ -3,6 +3,8 @@ const multibase = require('multibase') const { rightpad } = require('../utils') const { cidToString } = require('../../utils/cid') +const formatMode = require('ipfs-utils/src/files/format-mode') +const formatMtime = require('ipfs-utils/src/files/format-mtime') module.exports = { command: 'ls ', @@ -39,14 +41,21 @@ module.exports = { const ipfs = await getIpfs() let links = await ipfs.ls(key, { recursive }) - links = links.map(file => Object.assign(file, { hash: cidToString(file.hash, { base: cidBase }) })) + links = links.map(file => { + return Object.assign(file, { + hash: cidToString(file.hash, { base: cidBase }), + mode: formatMode(file.mode, file.type === 'dir'), + mtime: formatMtime(file.mtime) + }) + }) if (headers) { - links = [{ hash: 'Hash', size: 'Size', name: 'Name' }].concat(links) + links = [{ mode: 'Mode', mtime: 'Mtime', hash: 'Hash', size: 'Size', name: 'Name' }].concat(links) } const multihashWidth = Math.max.apply(null, links.map((file) => file.hash.length)) const sizeWidth = Math.max.apply(null, links.map((file) => String(file.size).length)) + const mtimeWidth = Math.max.apply(null, links.map((file) => file.mtime.length)) // replace multiple slashes key = key.replace(/\/(\/+)/g, '/') @@ -69,6 +78,8 @@ module.exports = { const padding = Math.max(link.depth - pathParts.length, 0) print( + rightpad(link.mode, 11) + + rightpad(link.mtime || '-', mtimeWidth + 1) + rightpad(link.hash, multihashWidth + 1) + rightpad(link.size || '-', sizeWidth + 1) + ' '.repeat(padding) + fileName diff --git a/src/cli/commands/object/patch/append-data.js b/src/cli/commands/object/patch/append-data.js index 94a34eb31b..a931212d30 100644 --- a/src/cli/commands/object/patch/append-data.js +++ b/src/cli/commands/object/patch/append-data.js @@ -26,7 +26,7 @@ module.exports = { data = fs.readFileSync(argv.data) } else { data = await new Promise((resolve, reject) => { - process.stdin.pipe(bl((err, input) => { + argv.getStdin().pipe(bl((err, input) => { if (err) return reject(err) resolve(input) })) diff --git a/src/cli/commands/object/patch/set-data.js b/src/cli/commands/object/patch/set-data.js index b61534f768..c18496b512 100644 --- a/src/cli/commands/object/patch/set-data.js +++ b/src/cli/commands/object/patch/set-data.js @@ -26,7 +26,7 @@ module.exports = { data = fs.readFileSync(argv.data) } else { data = await new Promise((resolve, reject) => { - process.stdin.pipe(bl((err, input) => { + argv.getStdin().pipe(bl((err, input) => { if (err) return reject(err) resolve(input) })) diff --git a/src/cli/parser.js b/src/cli/parser.js index f28979feec..767e07fd21 100644 --- a/src/cli/parser.js +++ b/src/cli/parser.js @@ -36,6 +36,7 @@ const parser = yargs .commandDir('commands') .middleware(argv => Object.assign(argv, { getIpfs: utils.singleton(cb => utils.getIPFS(argv, cb)), + getStdin: () => process.stdin, print: utils.print, isDaemonOn: utils.isDaemonOn, getRepoPath: utils.getRepoPath diff --git a/src/core/components/files-mfs.js b/src/core/components/files-mfs.js index 2a17d9e39c..d2d93290ab 100644 --- a/src/core/components/files-mfs.js +++ b/src/core/components/files-mfs.js @@ -28,7 +28,9 @@ const mapLsFile = (options) => { hash: long ? cidToString(file.cid, { base: options.cidBase }) : '', name: file.name, type: long ? file.type : 0, - size: long ? file.size || 0 : 0 + size: long ? file.size || 0 : 0, + mode: file.mode, + mtime: file.mtime } } } @@ -64,6 +66,26 @@ module.exports = (/** @type { import("../index") } */ ipfs) => { } return { + /** + * Change file mode + * + * @param {String} path - The path of the source to modify. + * @param {Object} mode - The mode to set the path + * @param {Object} [opts] - Options for modification. + * @param {boolean} [opts.recursive=false] - Whether to change modes recursively. (default: false) + * @param {boolean} [opts.flush=true] - Whether or not to immediately flush MFS changes to disk (default: true). + * @param {number} [opts.shardSplitThreshold] - If the modified path has more than this many links it will be turned into a HAMT shard + * @param {function(Error): void} [cb] - Callback function. + * @returns {Promise | void} When callback is provided nothing is returned. + */ + chmod: (path, mode, opts, cb) => { + if (typeof opts === 'function') { + cb = opts + opts = {} + } + return nodeify(methods.chmod(path, mode, opts), cb) + }, + /** * Copy files * @@ -208,6 +230,26 @@ module.exports = (/** @type { import("../index") } */ ipfs) => { */ readPullStream: (path, opts = {}) => toPullStream.source(methods.read(path, opts)), + /** + * Update modification time + * + * @param {String} path - The path of the source to modify. + * @param {number} mtime - Time to use as the new modification time in seconds since (+ve) or before (-ve) the Unix Epoch + * @param {Object} [opts] - Options for touch. + * @param {boolean} [opts.parents=false] - Whether or not to make the parent directories if they don't exist. (default: false) + * @param {number} [opts.cidVersion=0] - CID version to use with the newly updated node + * @param {number} [opts.shardSplitThreshold] - If the modified path has more than this many links it will be turned into a HAMT shard + * @param {function(Error): void} [cb] - Callback function. + * @returns {Promise | void} When callback is provided nothing is returned. + */ + touch: (path, mtime, opts, cb) => { + if (typeof opts === 'function') { + cb = opts + opts = {} + } + return nodeify(methods.touch(path, mtime, opts), cb) + }, + /** * Write to a file. * diff --git a/src/core/components/files-regular/utils.js b/src/core/components/files-regular/utils.js index 8cd05f45d4..b889d73075 100644 --- a/src/core/components/files-regular/utils.js +++ b/src/core/components/files-regular/utils.js @@ -101,25 +101,27 @@ const parseChunkSize = (str, name) => { const mapFile = (file, options) => { options = options || {} - let size = 0 - let type = 'dir' - - if (file.unixfs && file.unixfs.type === 'file') { - size = file.unixfs.fileSize() - type = 'file' - } - const output = { hash: cidToString(file.cid, { base: options.cidBase }), path: file.path, name: file.name, depth: file.path.split('/').length, - size, - type + size: 0, + type: 'dir' } - if (options.includeContent && file.unixfs && file.unixfs.type === 'file') { - output.content = file.content + if (file.unixfs) { + if (file.unixfs.type === 'file') { + output.size = file.unixfs.fileSize() + output.type = 'file' + + if (options.includeContent) { + output.content = file.content + } + } + + output.mode = file.unixfs.mode + output.mtime = file.unixfs.mtime } return output diff --git a/src/http/api/resources/file.js b/src/http/api/resources/file.js index 7418a512e1..e28fb36cc7 100644 --- a/src/http/api/resources/file.js +++ b/src/http/api/resources/file.js @@ -15,11 +15,19 @@ function toFileObject (file) { const fo = { Hash: toB58String(file.hash), Size: file.size, - Type: fileTypeMap[file.type] || file.type + Type: fileTypeMap[file.type] || file.type, + Mode: file.mode, + Mtime: file.mtime } if (fo.Hash !== file.name) { fo.Name = file.name } + if (file.mtime) { + fo.Mtime = Math.round(file.mtime.getTime() / 1000) + } + if (file.mode) { + fo.Mode = file.mode + } return fo } diff --git a/src/http/api/resources/files-regular.js b/src/http/api/resources/files-regular.js index 4c466f6959..294349199c 100644 --- a/src/http/api/resources/files-regular.js +++ b/src/http/api/resources/files-regular.js @@ -196,7 +196,9 @@ exports.add = { yield { path: entry.name, - content: entry.content + content: entry.content, + mode: entry.mode, + mtime: entry.mtime } } @@ -234,7 +236,9 @@ exports.add = { output.write(JSON.stringify({ Name: file.path, Hash: cidToString(file.hash, { base: request.query['cid-base'] }), - Size: file.size + Size: file.size, + Mode: file.mode === undefined ? undefined : file.mode.toString(8).padStart(4, '0'), + Mtime: file.mtime }) + '\n') } } @@ -294,13 +298,26 @@ exports.ls = { return h.response({ Objects: [{ Hash: key, - Links: files.map((file) => ({ - Name: file.name, - Hash: cidToString(file.hash, { base: cidBase }), - Size: file.size, - Type: toTypeCode(file.type), - Depth: file.depth - })) + Links: files.map((file) => { + const output = { + Name: file.name, + Hash: cidToString(file.hash, { base: cidBase }), + Size: file.size, + Type: toTypeCode(file.type), + Depth: file.depth, + Mode: file.mode.toString(8).padStart(4, '0') + } + + if (file.mtime) { + output.Mtime = file.mtime.secs + + if (file.mtime.nsecs !== null && file.mtime.nsecs !== undefined) { + output.MtimeNsecs = file.mtime.nsecs + } + } + + return output + }) }] }) } diff --git a/test/cli/files.js b/test/cli/files.js index b1376b7d59..e418dabfcd 100644 --- a/test/cli/files.js +++ b/test/cli/files.js @@ -342,6 +342,30 @@ describe('files', () => runOnAndOff((thing) => { await clean(filePath) }) + it('add with mtime', async function () { + this.timeout(30 * 1000) + + const out = await ipfs('add --mtime 5 src/init-files/init-docs/readme') + expect(out) + .to.eql('added Qmd7enmVy7ZZnSMQnsCKnMkLXfCYq11naCTiqXqHKe6YRg readme\n') + }) + + it('add with mtime-nsecs', async function () { + this.timeout(30 * 1000) + + const out = await ipfs('add --mtime 5 --mtime-nsecs 100 src/init-files/init-docs/readme') + expect(out) + .to.eql('added QmXbVCG5go62V1g7UQtyrJ3svYArc53stCxLx9CNtv1GGT readme\n') + }) + + it('add with mode', async function () { + this.timeout(30 * 1000) + + const out = await ipfs('add --mode 0655 src/init-files/init-docs/readme') + expect(out) + .to.eql('added QmUkGGwA3MvnutubCDQmW9MUC9oSHbZw58PcJERy4bNnDW readme\n') + }) + HASH_ALGS.forEach((name) => { it(`add with hash=${name} and raw-leaves=false`, async function () { this.timeout(30 * 1000) diff --git a/test/cli/ls.js b/test/cli/ls.js index dc4d1de661..d59bcd8e75 100644 --- a/test/cli/ls.js +++ b/test/cli/ls.js @@ -17,11 +17,11 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z') expect(out).to.eql( - 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + - 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + - 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + - 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + - 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' + 'drwxr-xr-x - QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + + '-rw-r--r-- - QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + + 'drwxr-xr-x - QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + + 'drwxr-xr-x - QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + + '-rw-r--r-- - QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' ) }) @@ -29,11 +29,11 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/') expect(out).to.eql( - 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + - 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + - 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + - 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + - 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' + 'drwxr-xr-x - QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + + '-rw-r--r-- - QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + + 'drwxr-xr-x - QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + + 'drwxr-xr-x - QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + + '-rw-r--r-- - QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' ) }) @@ -41,11 +41,11 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z///') expect(out).to.eql( - 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + - 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + - 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + - 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + - 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' + 'drwxr-xr-x - QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + + '-rw-r--r-- - QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + + 'drwxr-xr-x - QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + + 'drwxr-xr-x - QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + + '-rw-r--r-- - QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' ) }) @@ -53,14 +53,14 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z///init-docs') expect(out).to.eql( - 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + - 'QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + - 'QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + - 'QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + - 'QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + - 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + - 'QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + - 'QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' + '-rw-r--r-- - QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + + '-rw-r--r-- - QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + + 'drwxr-xr-x - QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + + '-rw-r--r-- - QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + + '-rw-r--r-- - QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + + '-rw-r--r-- - QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + + '-rw-r--r-- - QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + + 'drwxr-xr-x - QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' ) }) @@ -68,8 +68,8 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls -r Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/blocks/CIQLB') expect(out).to.eql( - 'QmQ8ag7ysVyCMzJGFjxrUStwWtniQ69c7G9aezbmsKeNYD 10849 CIQLBK52T5EHVHZY5URTG5JS3JCUJDQM2DRB5RVF33DCUUOFJNGVDUI.data\n' + - 'QmaSjzSSRanYzRGPXQY6m5SWfSkkfcnzNkurJEQc4chPJx 10807 CIQLBS5HG4PRCRQ7O4EBXFD5QN6MTI5YBYMCVQJDXPKCOVR6RMLHZFQ.data\n' + '-rw-r--r-- - QmQ8ag7ysVyCMzJGFjxrUStwWtniQ69c7G9aezbmsKeNYD 10849 CIQLBK52T5EHVHZY5URTG5JS3JCUJDQM2DRB5RVF33DCUUOFJNGVDUI.data\n' + + '-rw-r--r-- - QmaSjzSSRanYzRGPXQY6m5SWfSkkfcnzNkurJEQc4chPJx 10807 CIQLBS5HG4PRCRQ7O4EBXFD5QN6MTI5YBYMCVQJDXPKCOVR6RMLHZFQ.data\n' ) }) @@ -90,12 +90,12 @@ describe('ls', () => runOnAndOff((thing) => { this.timeout(20 * 1000) const out = await ipfs('ls /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z -v') expect(out).to.eql( - 'Hash Size Name\n' + - 'QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + - 'QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + - 'QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + - 'QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + - 'QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' + 'Mode Mtime Hash Size Name\n' + + 'drwxr-xr-x - QmamKEPmEH9RUsqRQsfNf5evZQDQPYL9KXg1ADeT7mkHkT - blocks/\n' + + '-rw-r--r-- - QmPkWYfSLCEBLZu7BZt4kigGDMe3cpogMbeVf97gN2xJDN 3928 config\n' + + 'drwxr-xr-x - QmUqyZtPmsRy1U5Mo8kz2BAMmk1hfJ7yW1KAFTMB2odsFv - datastore/\n' + + 'drwxr-xr-x - QmUhUuiTKkkK8J6JZ9zmj8iNHPuNfGYcszgRumzhHBxEEU - init-docs/\n' + + '-rw-r--r-- - QmR56UJmAaZLXLdTT1ALrE9vVqV8soUEekm9BMd4FnuYqV 2 version\n' ) }) @@ -104,14 +104,14 @@ describe('ls', () => runOnAndOff((thing) => { const out = await ipfs('ls /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/init-docs') expect(out).to.eql( - 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + - 'QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + - 'QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + - 'QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + - 'QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + - 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + - 'QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + - 'QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' + '-rw-r--r-- - QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + + '-rw-r--r-- - QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + + 'drwxr-xr-x - QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + + '-rw-r--r-- - QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + + '-rw-r--r-- - QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + + '-rw-r--r-- - QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + + '-rw-r--r-- - QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + + 'drwxr-xr-x - QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' ) }) @@ -121,16 +121,16 @@ describe('ls', () => runOnAndOff((thing) => { const out = await ipfs('ls -r /ipfs/Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z/init-docs') expect(out).to.eql( - 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + - 'QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + - 'QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + - 'QmQN88TEidd3RY2u3dpib49fERTDfKtDpvxnvczATNsfKT 6 index\n' + - 'QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + - 'QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + - 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + - 'QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + - 'QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' + - 'QmYE7xo6NxbHEVEHej1yzxijYaNY51BaeKxjXxn6Ssa6Bs 796 0.0-intro\n' + '-rw-r--r-- - QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1677 about\n' + + '-rw-r--r-- - QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 189 contact\n' + + 'drwxr-xr-x - QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC - docs/\n' + + '-rw-r--r-- - QmQN88TEidd3RY2u3dpib49fERTDfKtDpvxnvczATNsfKT 6 index\n' + + '-rw-r--r-- - QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 311 help\n' + + '-rw-r--r-- - QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1717 quick-start\n' + + '-rw-r--r-- - QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1091 readme\n' + + '-rw-r--r-- - QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1016 security-notes\n' + + 'drwxr-xr-x - QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te - tour/\n' + + '-rw-r--r-- - QmYE7xo6NxbHEVEHej1yzxijYaNY51BaeKxjXxn6Ssa6Bs 796 0.0-intro\n' ) }) @@ -139,11 +139,11 @@ describe('ls', () => runOnAndOff((thing) => { const out = await ipfs('ls Qmaj2NmcyAXT8dFmZRRytE12wpcaHADzbChKToMEjBsj5Z --cid-base=base64') expect(out).to.eql( - 'mAXASILidvV1YroHLqBvmuXko1Ly1UVenZV1K+MvhsjXhdvZQ - blocks/\n' + - 'mAXASIBT4ZYkQw0IApLoNHBxSjpezyayKZHJyxmFKpt0I3sK5 3928 config\n' + - 'mAXASIGCpScP8zpa0CqUgyVCR/Cm0Co8pnULGe3seXSsOnJsJ - datastore/\n' + - 'mAXASIF58POI3+TbHb69iXpD3dRqfXusEj1mHMwPCFenM6HWZ - init-docs/\n' + - 'mAXASICiW5ai+KiU60glImEMMkiHaNSOAivpXspriIhJO8iHI 2 version\n' + 'drwxr-xr-x - mAXASILidvV1YroHLqBvmuXko1Ly1UVenZV1K+MvhsjXhdvZQ - blocks/\n' + + '-rw-r--r-- - mAXASIBT4ZYkQw0IApLoNHBxSjpezyayKZHJyxmFKpt0I3sK5 3928 config\n' + + 'drwxr-xr-x - mAXASIGCpScP8zpa0CqUgyVCR/Cm0Co8pnULGe3seXSsOnJsJ - datastore/\n' + + 'drwxr-xr-x - mAXASIF58POI3+TbHb69iXpD3dRqfXusEj1mHMwPCFenM6HWZ - init-docs/\n' + + '-rw-r--r-- - mAXASICiW5ai+KiU60glImEMMkiHaNSOAivpXspriIhJO8iHI 2 version\n' ) }) })) diff --git a/test/core/interface.spec.js b/test/core/interface.spec.js index 5a8fefcb1b..0b14ef3671 100644 --- a/test/core/interface.spec.js +++ b/test/core/interface.spec.js @@ -56,10 +56,24 @@ describe('interface-ipfs-core tests', function () { }, { name: 'addFromFs', reason: 'Not designed to run in the browser' + }, { + name: 'should add with mtime as hrtime', + reason: 'Not designed to run in the browser' }] }) - tests.filesMFS(commonFactory) + tests.filesMFS(commonFactory, { + skip: isNode ? null : [{ + name: 'should make directory and specify mtime as hrtime', + reason: 'Not designed to run in the browser' + }, { + name: 'should set mtime as hrtime', + reason: 'Not designed to run in the browser' + }, { + name: 'should write file and specify mtime as hrtime', + reason: 'Not designed to run in the browser' + }] + }) tests.key(commonFactory)