From 511e753256bd9efc240bf65589e12b5d41427352 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Wed, 3 Dec 2014 12:03:54 -0400 Subject: [PATCH] Support user defined configuration file --- lib/actions/auth.coffee | 4 +- lib/actions/keys.coffee | 8 +-- lib/actions/logs.coffee | 4 +- lib/actions/os.coffee | 4 +- lib/actions/preferences.coffee | 4 +- lib/app.coffee | 2 +- lib/resin/auth/auth.coffee | 4 +- lib/resin/auth/auth.spec.coffee | 12 ++--- lib/resin/cli/cli-permissions.spec.coffee | 6 +-- lib/resin/config/config.coffee | 17 +++++++ lib/resin/config/config.spec.coffee | 51 ++++++++++++++++++++ lib/resin/data/data-prefix.spec.coffee | 6 +-- lib/resin/data/data.spec.coffee | 10 ++-- lib/resin/data/fs-utils/fs-utils.spec.coffee | 6 +-- lib/resin/errors/errors.coffee | 5 ++ lib/resin/helpers/helpers.coffee | 16 ++++++ lib/resin/helpers/helpers.spec.coffee | 48 ++++++++++++++++++ lib/resin/index.coffee | 2 +- lib/resin/models/_canvas.coffee | 6 +-- lib/resin/models/_canvas.spec.coffee | 8 +-- lib/resin/models/application.coffee | 4 +- lib/resin/models/device.coffee | 4 +- lib/resin/server/server.coffee | 4 +- lib/resin/server/server.spec.coffee | 8 +-- lib/resin/{config.coffee => settings.coffee} | 22 ++++++--- lib/resin/token/token.spec.coffee | 4 +- package.json | 3 +- tests/utils/mock.coffee | 2 +- 28 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 lib/resin/config/config.coffee create mode 100644 lib/resin/config/config.spec.coffee create mode 100644 lib/resin/helpers/helpers.coffee create mode 100644 lib/resin/helpers/helpers.spec.coffee rename lib/resin/{config.coffee => settings.coffee} (55%) diff --git a/lib/actions/auth.coffee b/lib/actions/auth.coffee index 43cbee37..9f4af658 100644 --- a/lib/actions/auth.coffee +++ b/lib/actions/auth.coffee @@ -21,6 +21,6 @@ exports.logout = -> resin.auth.logout() exports.signup = -> - signupUrl = resin.config.urls.signup - absUrl = url.resolve(resin.config.remoteUrl, signupUrl) + signupUrl = resin.settings.urls.signup + absUrl = url.resolve(resin.settings.remoteUrl, signupUrl) open(absUrl) diff --git a/lib/actions/keys.coffee b/lib/actions/keys.coffee index 8ead5bf4..f9278149 100644 --- a/lib/actions/keys.coffee +++ b/lib/actions/keys.coffee @@ -3,7 +3,7 @@ resin = require('../resin') helpers = require('../helpers/helpers') exports.list = -> - resin.server.get resin.config.urls.keys, (error, response, keys) -> + resin.server.get resin.settings.urls.keys, (error, response, keys) -> resin.errors.handle(error) if error? resin.log.out resin.ui.widgets.table.horizontal keys, (key) -> delete key.public_key @@ -16,18 +16,18 @@ exports.info = (id) -> # TODO: We don't have a way to query a single ssh key yet. # As a workaround, we request all of them, and filter # the one we need. Fix once we have a better way. - resin.server.get resin.config.urls.keys, (error, response, keys) -> + resin.server.get resin.settings.urls.keys, (error, response, keys) -> resin.errors.handle(error) if error? key = _.findWhere(keys, { id }) if not key? resin.errors.handle(new resin.errors.NotFound("key #{id}")) - key.public_key = '\n' + helpers.formatLongString(key.public_key, resin.config.sshKeyWidth) + key.public_key = '\n' + helpers.formatLongString(key.public_key, resin.settings.sshKeyWidth) resin.log.out(resin.ui.widgets.table.vertical(key, _.identity, [ 'ID', 'Title', 'Public Key' ])) exports.remove = (id) -> confirmArgument = resin.cli.getArgument('yes') resin.ui.patterns.remove 'key', confirmArgument, (callback) -> - url = _.template(resin.config.urls.sshKey, { id }) + url = _.template(resin.settings.urls.sshKey, { id }) resin.server.delete(url, callback) , resin.errors.handle diff --git a/lib/actions/logs.coffee b/lib/actions/logs.coffee index e2fe9052..56138409 100644 --- a/lib/actions/logs.coffee +++ b/lib/actions/logs.coffee @@ -30,9 +30,9 @@ exports.logs = (uuid) -> # PubNub needs to be initialised after logs # action was called, otherwise it prevents # all other actions from exiting on completion - pubnub = PubNub.init(resin.config.pubnub) + pubnub = PubNub.init(resin.settings.pubnub) - channel = _.template(resin.config.events.deviceLogs, { uuid }) + channel = _.template(resin.settings.events.deviceLogs, { uuid }) pubnub.history count: LOGS_HISTORY_COUNT diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index ef9bb702..7553b469 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -13,7 +13,7 @@ exports.download = (id) -> wifiKey: resin.cli.getArgument('wifiKey') fileName = resin.os.generateCacheName(id, params) - outputFile = resin.cli.getArgument('output') or path.join(resin.config.directories.os, fileName) + outputFile = resin.cli.getArgument('output') or path.join(resin.settings.directories.os, fileName) async.waterfall [ @@ -30,7 +30,7 @@ exports.download = (id) -> parameters.appId = id query = url.format(query: parameters) - downloadUrl = url.resolve(resin.config.urls.download, query) + downloadUrl = url.resolve(resin.settings.urls.download, query) return callback(null, downloadUrl) diff --git a/lib/actions/preferences.coffee b/lib/actions/preferences.coffee index 7096a6e1..b0ba499f 100644 --- a/lib/actions/preferences.coffee +++ b/lib/actions/preferences.coffee @@ -3,6 +3,6 @@ url = require('url') resin = require('../resin') exports.preferences = -> - preferencesUrl = resin.config.urls.preferences - absUrl = url.resolve(resin.config.remoteUrl, preferencesUrl) + preferencesUrl = resin.settings.urls.preferences + absUrl = url.resolve(resin.settings.remoteUrl, preferencesUrl) open(absUrl) diff --git a/lib/app.coffee b/lib/app.coffee index 434d8cd5..077926b9 100644 --- a/lib/app.coffee +++ b/lib/app.coffee @@ -132,7 +132,7 @@ resin.cli.addCommand action: actions.os.download permission: 'user' -resin.data.prefix.set resin.config.dataPrefix, (error) -> +resin.data.prefix.set resin.settings.dataPrefix, (error) -> resin.errors.handle(error) if error? resin.cli.parse(process.argv) diff --git a/lib/resin/auth/auth.coffee b/lib/resin/auth/auth.coffee index 34b08f2c..4d9ff886 100644 --- a/lib/resin/auth/auth.coffee +++ b/lib/resin/auth/auth.coffee @@ -4,10 +4,10 @@ _ = require('lodash') token = require('../token/token') server = require('../server/server') errors = require('../errors/errors') -config = require('../config') +settings = require('../settings') exports.authenticate = (credentials, callback) -> - server.post config.urls.authenticate, credentials, (error, response) -> + server.post settings.urls.authenticate, credentials, (error, response) -> return callback(error, response?.body) exports.login = (credentials, callback) -> diff --git a/lib/resin/auth/auth.spec.coffee b/lib/resin/auth/auth.spec.coffee index 8c018d38..eb5d519b 100644 --- a/lib/resin/auth/auth.spec.coffee +++ b/lib/resin/auth/auth.spec.coffee @@ -4,7 +4,7 @@ _ = require('lodash') async = require('async') auth = require('./auth') data = require('../data/data') -config = require('../config') +settings = require('../settings') mock = require('../../../tests/utils/mock') johnDoeFixture = require('../../../tests/fixtures/johndoe') janeDoeFixture = require('../../../tests/fixtures/janedoe') @@ -19,7 +19,7 @@ describe 'Auth:', -> beforeEach (done) -> mock.fs.init() - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() @@ -27,7 +27,7 @@ describe 'Auth:', -> describe 'given valid credentials', -> beforeEach -> - nock(config.remoteUrl) + nock(settings.remoteUrl) .post('/login_', johnDoeFixture.credentials) .reply(200, johnDoeFixture.token) @@ -68,7 +68,7 @@ describe 'Auth:', -> describe 'given invalid credentials', -> beforeEach -> - nock(config.remoteUrl) + nock(settings.remoteUrl) .post('/login_') .reply(401) @@ -93,11 +93,11 @@ describe 'Auth:', -> describe 'given a logged in user', -> beforeEach (done) -> - nock(config.remoteUrl) + nock(settings.remoteUrl) .post('/login_', johnDoeFixture.credentials) .reply(200, johnDoeFixture.token) - nock(config.remoteUrl) + nock(settings.remoteUrl) .post('/login_', janeDoeFixture.credentials) .reply(200, janeDoeFixture.token) diff --git a/lib/resin/cli/cli-permissions.spec.coffee b/lib/resin/cli/cli-permissions.spec.coffee index 57171cfa..7e404397 100644 --- a/lib/resin/cli/cli-permissions.spec.coffee +++ b/lib/resin/cli/cli-permissions.spec.coffee @@ -4,7 +4,7 @@ sinon = require('sinon') expect = require('chai').expect data = require('../data/data') auth = require('../auth/auth') -config = require('../config') +settings = require('../settings') cliPermissions = require('./cli-permissions') johnDoeFixture = require('../../../tests/fixtures/johndoe') mock = require('../../../tests/utils/mock') @@ -21,7 +21,7 @@ describe 'CLI Permissions:', -> beforeEach (done) -> mock.fs.init() - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() @@ -59,7 +59,7 @@ describe 'CLI Permissions:', -> describe 'if logged in', -> beforeEach (done) -> - nock(config.remoteUrl) + nock(settings.remoteUrl) .post('/login_', johnDoeFixture.credentials) .reply(200, johnDoeFixture.token) diff --git a/lib/resin/config/config.coffee b/lib/resin/config/config.coffee new file mode 100644 index 00000000..45a3a633 --- /dev/null +++ b/lib/resin/config/config.coffee @@ -0,0 +1,17 @@ +fs = require('fs') +errors = require('../errors/errors') + +# User config loading should be sync, as we need to +# extend this module with the result before exporting +exports.loadUserConfig = (configFile) -> + return if not fs.existsSync(configFile) + + if not fs.statSync(configFile).isFile() + throw new errors.InvalidConfigFile(configFile) + + result = fs.readFileSync(configFile, encoding: 'utf8') + + try + return JSON.parse(result) + catch error + throw new errors.InvalidConfigFile(configFile) diff --git a/lib/resin/config/config.spec.coffee b/lib/resin/config/config.spec.coffee new file mode 100644 index 00000000..f8ccae18 --- /dev/null +++ b/lib/resin/config/config.spec.coffee @@ -0,0 +1,51 @@ +_ = require('lodash') +chai = require('chai') +expect = chai.expect +config = require('./config') +settings = require('../settings') +mock = require('../../../tests/utils/mock') + +FILESYSTEM = + config: + name: 'config' + contents: JSON.stringify + directories: + plugins: 'myPlugins' + remoteUrl: 'http://localhost:9001' + directoryConfig: + name: 'directoryConfig' + contents: {} + notJSON: + name: 'notJSON' + contents: 'Not JSON content' + +describe 'Config:', -> + + beforeEach -> + mock.fs.init(FILESYSTEM) + + afterEach -> + mock.fs.restore() + + describe '#loadUserConfig()', -> + + it 'should load the default config file', -> + configFile = FILESYSTEM.config.name + result = config.loadUserConfig(configFile) + expectedContents = JSON.parse(FILESYSTEM.config.contents) + expect(result).to.deep.equal(expectedContents) + + it 'should return undefined if config file does not exist', -> + configFile = 'foobar' + result = config.loadUserConfig(configFile) + expect(result).to.be.undefined + + it 'should throw an error if config file is not a file', -> + configFile = FILESYSTEM.directoryConfig.name + func = _.partial(config.loadUserConfig, configFile) + expect(func).to.throw(Error) + + it 'should throw an error if config is not a json file', -> + configFile = FILESYSTEM.notJSON.name + func = _.partial(config.loadUserConfig, configFile) + expect(func).to.throw(Error) diff --git a/lib/resin/data/data-prefix.spec.coffee b/lib/resin/data/data-prefix.spec.coffee index 51aced9d..436f1cc8 100644 --- a/lib/resin/data/data-prefix.spec.coffee +++ b/lib/resin/data/data-prefix.spec.coffee @@ -5,12 +5,12 @@ fs = require('fs') fsUtils = require('./fs-utils/fs-utils') rimraf = require('rimraf') dataPrefix = require('./data-prefix') -config = require('../config') +settings = require('../settings') mock = require('../../../tests/utils/mock') PREFIXES = - main: config.dataPrefix - new: "#{config.dataPrefix}-new" + main: settings.dataPrefix + new: "#{settings.dataPrefix}-new" invalid: { path: '/abc' } describe 'DataPrefix:', -> diff --git a/lib/resin/data/data.spec.coffee b/lib/resin/data/data.spec.coffee index 4a8c08fc..c39db0f1 100644 --- a/lib/resin/data/data.spec.coffee +++ b/lib/resin/data/data.spec.coffee @@ -3,7 +3,7 @@ _ = require('lodash') fsUtils = require('./fs-utils/fs-utils') mock = require('../../../tests/utils/mock') async = require('async') -config = require('../config') +settings = require('../settings') data = require('./data') FILES_FIXTURES = @@ -16,15 +16,15 @@ FILES_FIXTURES = FILESYSTEM = text: - name: "#{config.dataPrefix}/text" + name: "#{settings.dataPrefix}/text" contents: 'Hello World' key: 'text' directory: - name: "#{config.dataPrefix}/directory" + name: "#{settings.dataPrefix}/directory" contents: {} key: 'directory' nested: - name: "#{config.dataPrefix}/nested/text" + name: "#{settings.dataPrefix}/nested/text" contents: 'Nested Hello World' key: 'nested/text' @@ -60,7 +60,7 @@ describe 'Data:', -> beforeEach (done) -> mock.fs.init(FILESYSTEM) - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() diff --git a/lib/resin/data/fs-utils/fs-utils.spec.coffee b/lib/resin/data/fs-utils/fs-utils.spec.coffee index bc66ea46..58e503b9 100644 --- a/lib/resin/data/fs-utils/fs-utils.spec.coffee +++ b/lib/resin/data/fs-utils/fs-utils.spec.coffee @@ -1,7 +1,7 @@ expect = require('chai').expect mock = require('../../../../tests/utils/mock') fsUtils = require('./fs-utils') -config = require('../../config') +settings = require('../../settings') data = require('../../data/data') FILESYSTEM = @@ -30,7 +30,7 @@ describe 'FsUtils:', -> it 'should return true for valid paths', -> for validPath in [ - config.dataPrefix + settings.dataPrefix '/Users/johndoe' '../parent' './file/../file2' @@ -41,7 +41,7 @@ describe 'FsUtils:', -> beforeEach (done) -> mock.fs.init(FILESYSTEM) - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() diff --git a/lib/resin/errors/errors.coffee b/lib/resin/errors/errors.coffee index b54d46c4..f8b4d896 100644 --- a/lib/resin/errors/errors.coffee +++ b/lib/resin/errors/errors.coffee @@ -7,6 +7,11 @@ exports.NotFound = class NotFound extends TypedError @message = "Couldn't find #{name}" @code = 1 +exports.InvalidConfigFile = class NotFound extends TypedError + constructor: (file) -> + @message = "Invalid configuration file: #{file}" + @code = 1 + exports.InvalidCredentials = class InvalidCredentials extends TypedError constructor: -> @message = 'Invalid credentials' diff --git a/lib/resin/helpers/helpers.coffee b/lib/resin/helpers/helpers.coffee new file mode 100644 index 00000000..20af5632 --- /dev/null +++ b/lib/resin/helpers/helpers.coffee @@ -0,0 +1,16 @@ +_ = require('lodash') +path = require('path') + +exports.isAbsolutePath = (p) -> + return path.resolve(p) is p + +exports.prefixObjectValuesWithPath = (prefix, object) -> + return _.object _.map object, (value, key) -> + result = [ key ] + + if exports.isAbsolutePath(value) + result.push(value) + else + result.push(path.join(prefix, value)) + + return result diff --git a/lib/resin/helpers/helpers.spec.coffee b/lib/resin/helpers/helpers.spec.coffee new file mode 100644 index 00000000..813caf0a --- /dev/null +++ b/lib/resin/helpers/helpers.spec.coffee @@ -0,0 +1,48 @@ +chai = require('chai') +chai.use(require('chai-string')) +expect = chai.expect +helpers = require('./helpers') + +describe 'Helpers:', -> + + describe '#isAbsolutePath()', -> + + it 'should return true for absolute paths', -> + for path in [ + '/' + '/Users/me' + '/usr/share' + ] + expect(helpers.isAbsolutePath(path)).to.be.true + + it 'should return false for relative paths', -> + for path in [ + './hello' + '../../resin' + 'directory/' + ] + expect(helpers.isAbsolutePath(path)).to.be.false + + describe '#prefixObjectWithPath()', -> + + it 'should add the path to every value', -> + prefix = '/resin' + object = + first: 'first' + second: './second' + + result = helpers.prefixObjectValuesWithPath(prefix, object) + + for key, value of result + expect(value).to.startsWith(prefix) + + it 'should not add the prefix if the paths are absolute', -> + prefix = '/resin' + object = + first: '/first' + second: '/home/second' + third: '/usr/share/resin' + fourth: '/' + + result = helpers.prefixObjectValuesWithPath(prefix, object) + expect(result).to.deep.equal(object) diff --git a/lib/resin/index.coffee b/lib/resin/index.coffee index bbf9db04..2e14a1ea 100644 --- a/lib/resin/index.coffee +++ b/lib/resin/index.coffee @@ -10,4 +10,4 @@ module.exports = ui: require('./ui') cli: require('./cli/cli') os: require('./os/os') - config: require('./config') + settings: require('./settings') diff --git a/lib/resin/models/_canvas.coffee b/lib/resin/models/_canvas.coffee index 144b6010..7b707a6e 100644 --- a/lib/resin/models/_canvas.coffee +++ b/lib/resin/models/_canvas.coffee @@ -1,7 +1,7 @@ _ = require('lodash') Canvas = require('resin-platform-api') Promise = require('bluebird') -config = require('../config') +settings = require('../settings') server = require('../server/server') promisifiedServerRequest = Promise.promisify(server.request, server) @@ -15,6 +15,6 @@ class CanvasRequestService extends Canvas(_, Promise) throw new Error(body) module.exports = new CanvasRequestService - url: config.remoteUrl - apiPrefix: config.apiPrefix + url: settings.remoteUrl + apiPrefix: settings.apiPrefix withCredentials: true diff --git a/lib/resin/models/_canvas.spec.coffee b/lib/resin/models/_canvas.spec.coffee index 481c22ee..00878d09 100644 --- a/lib/resin/models/_canvas.spec.coffee +++ b/lib/resin/models/_canvas.spec.coffee @@ -9,10 +9,10 @@ chai.use(chaiAsPromised) data = require('../data/data') mock = require('../../../tests/utils/mock') canvas = require('./_canvas') -config = require('../config') +settings = require('../settings') URI = - application: url.resolve(config.apiPrefix, 'application') + application: url.resolve(settings.apiPrefix, 'application') RESPONSE = applications: @@ -25,7 +25,7 @@ describe 'Canvas:', -> beforeEach (done) -> mock.fs.init() - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() @@ -37,7 +37,7 @@ describe 'Canvas:', -> mock.connection.restore() beforeEach -> - nock(config.remoteUrl) + nock(settings.remoteUrl) .get(URI.application) .reply(200, RESPONSE.applications) diff --git a/lib/resin/models/application.coffee b/lib/resin/models/application.coffee index 2f7ac3d7..a73f1c2b 100644 --- a/lib/resin/models/application.coffee +++ b/lib/resin/models/application.coffee @@ -2,7 +2,7 @@ _ = require('lodash') canvas = require('./_canvas') errors = require('../errors/errors') server = require('../server/server') -config = require('../config') +settings = require('../settings') exports.getAll = (callback) -> return canvas.get @@ -61,5 +61,5 @@ exports.remove = (id, callback) -> return callback(error) exports.restart = (id, callback) -> - url = _.template(config.urls.applicationRestart, { id }) + url = _.template(settings.urls.applicationRestart, { id }) server.post(url, callback) diff --git a/lib/resin/models/device.coffee b/lib/resin/models/device.coffee index 41ddcb41..4245ada1 100644 --- a/lib/resin/models/device.coffee +++ b/lib/resin/models/device.coffee @@ -2,7 +2,7 @@ canvas = require('./_canvas') _ = require('lodash') errors = require('../errors/errors') server = require('../server/server') -config = require('../config') +settings = require('../settings') exports.getAll = (callback) -> return canvas.get @@ -46,4 +46,4 @@ exports.remove = (id, callback) -> return callback(error) exports.identify = (uuid, callback) -> - server.post(config.urls.identify, { uuid }, callback) + server.post(settings.urls.identify, { uuid }, callback) diff --git a/lib/resin/server/server.coffee b/lib/resin/server/server.coffee index 18177121..591bf957 100644 --- a/lib/resin/server/server.coffee +++ b/lib/resin/server/server.coffee @@ -4,7 +4,7 @@ progress = require('request-progress') urlResolve = require('url').resolve async = require('async') connection = require('../../connection/connection') -config = require('../config') +settings = require('../settings') token = require('../token/token') exports.request = (options = {}, outerCallback, onProgress) -> @@ -26,7 +26,7 @@ exports.request = (options = {}, outerCallback, onProgress) -> token.getToken(callback) (savedToken, callback) -> - options.url = urlResolve(config.remoteUrl, options.url) + options.url = urlResolve(settings.remoteUrl, options.url) if options.method? options.method = options.method.toUpperCase() diff --git a/lib/resin/server/server.spec.coffee b/lib/resin/server/server.spec.coffee index e21541aa..13d0bf07 100644 --- a/lib/resin/server/server.spec.coffee +++ b/lib/resin/server/server.spec.coffee @@ -4,13 +4,13 @@ nock = require('nock') url = require('url') sinon = require('sinon') server = require('./server') -config = require('../config') +settings = require('../settings') token = require('../token/token') data = require('../data/data') mock = require('../../../tests/utils/mock') johnDoeFixture = require('../../../tests/fixtures/johndoe.json') -TEST_URI = config.remoteUrl +TEST_URI = settings.remoteUrl URI = ok: '/ok' @@ -50,7 +50,7 @@ describe 'Server:', -> nock(TEST_URI)[lowercaseMethod](URI.ok).reply(200, status: STATUS.ok) mock.fs.init() - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() @@ -140,7 +140,7 @@ describe 'Server:', -> it 'should accept a full url', (done) -> server.request { method: 'GET' - url: url.resolve(config.remoteUrl, URI.ok) + url: url.resolve(settings.remoteUrl, URI.ok) }, (error, response) -> expect(error).to.not.exist expect(response.body.status).to.equal(STATUS.ok) diff --git a/lib/resin/config.coffee b/lib/resin/settings.coffee similarity index 55% rename from lib/resin/config.coffee rename to lib/resin/settings.coffee index 24b59a7f..2e5ad7f7 100644 --- a/lib/resin/config.coffee +++ b/lib/resin/settings.coffee @@ -1,10 +1,12 @@ _ = require('lodash') path = require('path') +fs = require('fs') userHome = require('user-home') +helpers = require('./helpers/helpers') +errors = require('./errors/errors') +config = require('./config/config') -config = - - # TODO: Should be configurable +settings = remoteUrl: 'https://staging.resin.io' apiPrefix: '/ewa/' @@ -16,6 +18,11 @@ config = plugins: 'plugins' os: 'os' + files: + + # TODO: Accept an option that overrides this + config: 'config' + pubnub: subscribe_key: 'sub-c-bbc12eba-ce4a-11e3-9782-02ee2ddab7fe' publish_key: 'pub-c-6cbce8db-bfd1-4fdf-a8c8-53671ae2b226' @@ -34,7 +41,10 @@ config = sshKey: '/user/keys/<%= id %>' download: '/download' -config.directories = _.object _.map config.directories, (value, key) -> - return [ key, path.join(config.dataPrefix, value) ] +settings.directories = helpers.prefixObjectValuesWithPath(settings.dataPrefix, settings.directories) +settings.files = helpers.prefixObjectValuesWithPath(settings.dataPrefix, settings.files) -module.exports = config +# Attempt to load user configuration +_.extend(settings, config.loadUserConfig(settings.files.config) or {}) + +module.exports = settings diff --git a/lib/resin/token/token.spec.coffee b/lib/resin/token/token.spec.coffee index 9485ddf6..a536f1e6 100644 --- a/lib/resin/token/token.spec.coffee +++ b/lib/resin/token/token.spec.coffee @@ -1,7 +1,7 @@ expect = require('chai').expect async = require('async') token = require('./token') -config = require('../config') +settings = require('../settings') data = require('../data/data') mock = require('../../../tests/utils/mock') @@ -12,7 +12,7 @@ describe 'Token:', -> beforeEach (done) -> mock.fs.init() - data.prefix.set(config.dataPrefix, done) + data.prefix.set(settings.dataPrefix, done) afterEach -> mock.fs.restore() diff --git a/package.json b/package.json index e29b47d4..6730635f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "sinon-chai": "~2.6.0", "gulp-coffee": "~2.2.0", "gulp-util": "~3.0.1", - "run-sequence": "~1.0.2" + "run-sequence": "~1.0.2", + "chai-string": "~1.1.0" }, "dependencies": { "request": "~2.47.0", diff --git a/tests/utils/mock.coffee b/tests/utils/mock.coffee index 32f27d7f..0c733b07 100644 --- a/tests/utils/mock.coffee +++ b/tests/utils/mock.coffee @@ -10,7 +10,7 @@ exports.fs = # Mock data prefix automatically to remove # duplication in most of the tests - mockFsOptions[resin.config.dataPrefix] = mockFs.directory() + mockFsOptions[resin.settings.dataPrefix] = mockFs.directory() for key, value of filesystemConfig mockFsOptions[value.name] = value.contents