From 76b667046aa713892dcf14c0bd1494454d3c5f3a Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 1 Jul 2016 17:54:49 +0100 Subject: [PATCH] feat(config): make the config impl spec compliant --- package.json | 5 +- src/cli/commands/config.js | 4 +- src/cli/commands/config/edit.js | 2 +- src/cli/commands/config/show.js | 2 +- src/core/ipfs/config.js | 86 +++++++++++++++++++++++--- src/http-api/index.js | 2 +- src/http-api/resources/config.js | 6 +- test/core/both/test-bitswap.js | 2 +- test/core/both/test-config.js | 102 ++++--------------------------- test/http-api/test-config.js | 52 +++------------- 10 files changed, 112 insertions(+), 151 deletions(-) diff --git a/package.json b/package.json index 185ae71016..79cb4e60a9 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "interface-ipfs-core": "^0.6.0", "left-pad": "^1.1.1", "lodash": "^4.14.1", + "mocha": "^2.5.1", "ncp": "^2.0.0", "nexpect": "^0.5.0", "pre-commit": "^1.1.3", @@ -68,7 +69,7 @@ "glob": "^7.0.5", "hapi": "^14.0.0", "ipfs-bitswap": "^0.6.0", - "ipfs-api": "^6.0.3", + "ipfs-api": "ipfs/js-ipfs-api#91de5ac", "ipfs-block": "^0.3.0", "ipfs-block-service": "^0.4.0", "ipfs-merkle-dag": "^0.6.2", @@ -117,4 +118,4 @@ "kumavis ", "nginnever " ] -} \ No newline at end of file +} diff --git a/src/cli/commands/config.js b/src/cli/commands/config.js index 68d095f47b..8db0dbf4a5 100644 --- a/src/cli/commands/config.js +++ b/src/cli/commands/config.js @@ -46,7 +46,7 @@ module.exports = Command.extend({ }) } - ipfs.config.show((err, config) => { + ipfs.config.get((err, config) => { if (err) { log.error(err) throw new Error('failed to read the config') @@ -78,7 +78,7 @@ module.exports = Command.extend({ }) } - ipfs.config.show((err, originalConfig) => { + ipfs.config.get((err, originalConfig) => { if (err) { log.error(err) throw new Error('failed to read the config') diff --git a/src/cli/commands/config/edit.js b/src/cli/commands/config/edit.js index dfe9061199..a7dfc847af 100644 --- a/src/cli/commands/config/edit.js +++ b/src/cli/commands/config/edit.js @@ -25,7 +25,7 @@ module.exports = Command.extend({ } function getConfig (next) { - ipfs.config.show((err, config) => { + ipfs.config.get((err, config) => { if (err) { log.error(err) next(new Error('failed to get the config')) diff --git a/src/cli/commands/config/show.js b/src/cli/commands/config/show.js index 5a837bee6f..4da0e36c44 100644 --- a/src/cli/commands/config/show.js +++ b/src/cli/commands/config/show.js @@ -16,7 +16,7 @@ module.exports = Command.extend({ if (err) { throw err } - ipfs.config.show((err, config) => { + ipfs.config.get((err, config) => { if (err) { throw err } diff --git a/src/core/ipfs/config.js b/src/core/ipfs/config.js index 2029d8c7a8..3996a1bffb 100644 --- a/src/core/ipfs/config.js +++ b/src/core/ipfs/config.js @@ -1,14 +1,86 @@ 'use strict' +const promisify = require('promisify-es6') + module.exports = function config (self) { return { - // cli only feature built with show and replace - // edit: (callback) => {}, - replace: (config, callback) => { + get: promisify((key, callback) => { + if (typeof key === 'function') { + callback = key + key = undefined + } + + if (!key) { + return self._repo.config.get(callback) + } + + if (typeof key !== 'string') { + return callback(new Error('Invalid key type')) + } + + self._repo.config.get((err, config) => { + if (err) { + return callback(err) + } + const keys = key.split('.') + let finished = false + keys.forEach((key) => { + if (finished) { + return + } + if (config[key]) { + config = config[key] + } else { + finished = true + callback(new Error(('Key does not exist in config'))) + } + }) + if (!finished) { + callback(null, config) + } + }) + }), + set: promisify((key, value, callback) => { + if (!key || typeof key !== 'string') { + return callback(new Error('Invalid key type')) + } + + if (!value || Buffer.isBuffer(value)) { + return callback(new Error('Invalid value type')) + } + + self._repo.config.get((err, config) => { + const configBak = config + if (err) { + return callback(err) + } + const keys = key.split('.') + let finished = false + keys.forEach((key, index) => { + if (finished) { + return + } + if (config[key]) { + if (index === keys.length - 1) { + finished = true + config[key] = value + } + config = config[key] + } else { + if (index === keys.length - 1) { + finished = true + config[key] = value + } else { + config = config[key] = {} + } + } + }) + + self.config.replace(configBak, callback) + }) + }), + replace: promisify((config, callback) => { self._repo.config.set(config, callback) - }, - show: (callback) => { - self._repo.config.get(callback) - } + }) } } diff --git a/src/http-api/index.js b/src/http-api/index.js index b9b5c98b9a..e847577e6c 100644 --- a/src/http-api/index.js +++ b/src/http-api/index.js @@ -38,7 +38,7 @@ exports = module.exports = function HttpApi (repo) { fs.writeFileSync(apiPath, 'api is on by js-ipfs', {flag: 'w+'}) } - this.ipfs.config.show((err, config) => { + this.ipfs.config.get((err, config) => { if (err) { return callback(err) } diff --git a/src/http-api/resources/config.js b/src/http-api/resources/config.js index baecc4bfbf..c6dfca52f0 100644 --- a/src/http-api/resources/config.js +++ b/src/http-api/resources/config.js @@ -60,7 +60,7 @@ exports.getOrSet = { if (value === undefined) { // Get the value of a given key - return request.server.app.ipfs.config.show((err, config) => { + return request.server.app.ipfs.config.get((err, config) => { if (err) { log.error(err) return reply({ @@ -84,7 +84,7 @@ exports.getOrSet = { }) } else { // Set the new value of a given key - request.server.app.ipfs.config.show((err, originalConfig) => { + request.server.app.ipfs.config.get((err, originalConfig) => { if (err) { log.error(err) return reply({ @@ -114,7 +114,7 @@ exports.getOrSet = { } exports.show = (request, reply) => { - return request.server.app.ipfs.config.show((err, config) => { + return request.server.app.ipfs.config.get((err, config) => { if (err) { log.error(err) return reply({ diff --git a/test/core/both/test-bitswap.js b/test/core/both/test-bitswap.js index 6a69be55c2..d9fc88871d 100644 --- a/test/core/both/test-bitswap.js +++ b/test/core/both/test-bitswap.js @@ -26,7 +26,7 @@ describe('bitswap', () => { beforeEach((done) => { ipfs = new IPFS(require('../../utils/repo-path')) if (!isNode) { - ipfs.config.show((err, config) => { + ipfs.config.get((err, config) => { configBak = JSON.parse(JSON.stringify(config)) expect(err).to.not.exist config.Addresses.Swarm = [] diff --git a/test/core/both/test-config.js b/test/core/both/test-config.js index 649fbd2c6a..22ba7d6800 100644 --- a/test/core/both/test-config.js +++ b/test/core/both/test-config.js @@ -1,97 +1,19 @@ /* eslint-env mocha */ 'use strict' -const expect = require('chai').expect +const test = require('interface-ipfs-core') const IPFS = require('../../../src/core') -describe('config', () => { - var defaultConfig = { - Identity: { - PeerID: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A', - PrivKey: 'CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==' }, - Datastore: { Type: '', - Path: '', - StorageMax: '', - StorageGCWatermark: 0, - GCPeriod: '', - Params: null, - NoSync: false }, - Addresses: { Swarm: [ '/ip4/127.0.0.1/tcp/9999', '/ip4/127.0.0.1/tcp/9990/ws' ], - API: '/ip4/127.0.0.1/tcp/6001', - Gateway: '/ip4/127.0.0.1/tcp/0' }, - Mounts: { IPFS: '/ipfs', IPNS: '/ipns', FuseAllowOther: false }, - Version: { Current: '0.4.0-dev', - Check: 'error', - CheckDate: '0001-01-01T00:00:00Z', - CheckPeriod: '172800000000000', - AutoUpdate: 'minor' }, - Discovery: { MDNS: { Enabled: true, Interval: 10 } }, - Ipns: { RepublishPeriod: '', - RecordLifetime: '', - ResolveCacheSize: 128 }, - Bootstrap: [ '/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ', - '/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z', - '/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM', - '/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm', - '/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu', - '/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64', - '/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd', - '/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3', - '/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx' ], - Tour: { Last: '' }, - Gateway: { HTTPHeaders: null, RootRedirect: '', Writable: false }, - SupernodeRouting: { - Servers: [ - '/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U', - '/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6', - '/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH', - '/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP', - '/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R', - '/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4', - '/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v', - '/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN' - ] - }, - API: { - HTTPHeaders: null - }, - Swarm: { - AddrFilters: null - }, - Log: { - MaxSizeMB: 250, - MaxBackups: 1, - MaxAgeDays: 0 - } - } - - var ipfs - - before((done) => { - ipfs = new IPFS(require('../../utils/repo-path')) - ipfs.load(done) - }) - - it('show', (done) => { - ipfs.config.show((err, config) => { - expect(err).to.not.exist - expect(config).to.deep.equal(defaultConfig) - done() +const common = { + setup: function (cb) { + const ipfs = new IPFS(require('../../utils/repo-path')) + ipfs.load(() => { + cb(null, ipfs) }) - }) + }, + teardown: function (cb) { + cb() + } +} - it('replace', (done) => { - ipfs = new IPFS(require('../../utils/repo-path')) - ipfs.config.replace({}, (err) => { - expect(err).to.not.exist - ipfs.config.show((err, config) => { - expect(err).to.not.exist - expect(config).to.deep.equal({}) - ipfs.config.replace(defaultConfig, (err) => { - expect(err).to.not.exist - done() - }) - }) - }) - }) -}) +test.config(common) diff --git a/test/http-api/test-config.js b/test/http-api/test-config.js index 31d678a3e5..7d91cc4f0f 100644 --- a/test/http-api/test-config.js +++ b/test/http-api/test-config.js @@ -223,14 +223,6 @@ module.exports = (httpAPI) => { }) describe('ipfs.config', () => { - it('returns error for request without arguments', (done) => { - ctl.config.get(null, (err, res) => { - expect(err).to.exist - - done() - }) - }) - it('returns error for request with invalid argument', (done) => { ctl.config.get('kittens', (err, res) => { expect(err).to.exist @@ -240,72 +232,46 @@ module.exports = (httpAPI) => { }) it('returns value for request with argument', (done) => { - ctl.config.get('API.HTTPHeaders', (err, res) => { + ctl.config.get('API.HTTPHeaders', (err, value) => { expect(err).not.to.exist - expect(res.Key).to.equal('API.HTTPHeaders') - expect(res.Value).to.equal(null) - + expect(value).to.equal(null) done() }) }) it('updates value for request with both args', (done) => { - ctl.config.set('Datastore.Path', 'kitten', (err, res) => { + ctl.config.set('Datastore.Path', 'kitten', (err) => { expect(err).not.to.exist - expect(res.Key).to.equal('Datastore.Path') - expect(res.Value).to.equal('kitten') - expect(updatedConfig().Datastore.Path).to.equal('kitten') - done() }) }) it('returns error for request with both args and JSON flag with invalid JSON argument', (done) => { - ctl.config.set('Datastore.Path', 'kitten', { json: true }, (err, res) => { + ctl.config.set('Datastore.Path', 'kitten', { json: true }, (err) => { expect(err).to.exist - - done() - }) - }) - - it('updates value for request with both args and JSON flag with valid JSON argument', (done) => { - ctl.config.set('Datastore.Path', JSON.stringify({ kitten: true }), { json: true }, (err, res) => { - expect(err).not.to.exist - expect(res.Key).to.equal('Datastore.Path') - expect(res.Value).to.deep.equal({ kitten: true }) - expect(updatedConfig().Datastore.Path).to.deep.equal({ kitten: true }) - done() }) }) it('updates value for request with both args and bool flag and true argument', (done) => { - ctl.config.set('Datastore.Path', true, { bool: true }, (err, res) => { + ctl.config.set('Datastore.Path', true, (err) => { expect(err).not.to.exist - expect(res.Key).to.equal('Datastore.Path') - expect(res.Value).to.deep.equal(true) - expect(updatedConfig().Datastore.Path).to.deep.equal(true) - done() }) }) it('updates value for request with both args and bool flag and false argument', (done) => { - ctl.config.set('Datastore.Path', false, { bool: true }, (err, res) => { + ctl.config.set('Datastore.Path', false, (err) => { expect(err).not.to.exist - expect(res.Key).to.equal('Datastore.Path') - expect(res.Value).to.deep.equal(false) - expect(updatedConfig().Datastore.Path).to.deep.equal(false) - done() }) }) }) - it('ipfs.config.show', (done) => { - ctl.config.show((err, res) => { + it('ipfs.config.get', (done) => { + ctl.config.get((err, config) => { expect(err).not.to.exist - expect(res).to.deep.equal(updatedConfig()) + expect(config).to.deep.equal(updatedConfig()) done() }) })