From bf9f1bb9c9f6208ca379c70f9917892770a58f3d Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Thu, 11 Dec 2014 11:34:36 -0400 Subject: [PATCH] Make use of conf.js instead of mantaining CliConf in the codebase --- lib/cli-conf/cli-conf.coffee | 64 ------ lib/cli-conf/cli-conf.spec.coffee | 319 ------------------------------ lib/resin/settings.coffee | 4 +- package.json | 3 +- 4 files changed, 4 insertions(+), 386 deletions(-) delete mode 100644 lib/cli-conf/cli-conf.coffee delete mode 100644 lib/cli-conf/cli-conf.spec.coffee diff --git a/lib/cli-conf/cli-conf.coffee b/lib/cli-conf/cli-conf.coffee deleted file mode 100644 index e7344c6c..00000000 --- a/lib/cli-conf/cli-conf.coffee +++ /dev/null @@ -1,64 +0,0 @@ -_ = require('lodash-contrib') -fs = require('fs') -path = require('path') - -class CliConf - constructor: (@_options = {}) -> - _.defaults @_options, - configFileParse: JSON.parse - encoding: 'utf8' - - @_data = @_options.default or {} - - # Ordering is important here. We give precendece - # to local config over user config and defaults. - @extendWithFile(@_getOptionWithKey('userConfig')) - @extendWithFile(@_getLocalConfigPath()) - - extendWithFile: (file) -> - return if not fs.existsSync(file) - fileContents = @_readFile(file) - @extend(fileContents) - - set: (key, value) -> - @_data[key] = value - - get: (key) -> - return @_getKeyFromObject(@_data, key) - - has: (key) -> - return _.has(@_data, key) - - extend: (objects...) -> - return _.extend(@_data, objects...) - - isEmpty: -> - return _.isEmpty(@_data) - - parse: (input) -> - return @_options.configFileParse(input) - - # Private functions - - _getKeyFromObject: (object, key) -> - return if not key? - return _.getPath(object, key) - - _getOptionKey: (key) -> - return @_getKeyFromObject(@_options.keys, key) - - _getOptionWithKey: (key) -> - get = _.bind(@get, this) - getOptionKey = _.bind(@_getOptionKey, this) - return _.compose(get, getOptionKey)(key) - - _getLocalConfigPath: -> - localConfigFile = @_getOptionWithKey('localConfig') - return if not localConfigFile? - return path.join(process.cwd(), localConfigFile) - - _readFile: (file) -> - fileContents = fs.readFileSync(file, @_options.encoding) - return @parse(fileContents) - -module.exports = CliConf diff --git a/lib/cli-conf/cli-conf.spec.coffee b/lib/cli-conf/cli-conf.spec.coffee deleted file mode 100644 index 43352545..00000000 --- a/lib/cli-conf/cli-conf.spec.coffee +++ /dev/null @@ -1,319 +0,0 @@ -_ = require('lodash') -path = require('path') -sinon = require('sinon') -chai = require('chai') -expect = chai.expect -CliConf = require('./cli-conf') -mock = require('../../tests/utils/mock') - -describe 'CliConf:', -> - - describe 'given an empty conf', -> - - beforeEach -> - @conf = new CliConf() - - describe '#set()', -> - - it 'should be able to set values', -> - key = 'foo' - value = 'bar' - expect(@conf.get(key)).to.not.exist - @conf.set(key, value) - expect(@conf.get(key)).to.exist - - describe '#get()', -> - - it 'should be able to get values', -> - key = 'foo' - value = 'bar' - @conf.set(key, value) - expect(@conf.get(key)).to.equal(value) - - it 'should be able to get nested values', -> - @conf._data.nested = - value: 'ok' - - expect(@conf.get('nested.value')).to.equal('ok') - - it 'should return undefined if not nested value', -> - expect(@conf.get('unexistent.nested.value')).to.be.undefined - - it 'should return undefined if value does not exist', -> - expect(@conf.get('unknownKey')).to.be.undefined - - it 'should return undefined if no key', -> - expect(@conf.get()).to.be.undefined - - describe '#has()', -> - - it 'should return check if data has key', -> - key = 'foo' - value = 'bar' - - expect(@conf.has(key)).to.be.false - @conf.set(key, value) - expect(@conf.has(key)).to.be.true - - describe '#extendWithFile()', -> - - filesystem = - userConfig: - name: '/userConfig' - contents: JSON.stringify - remoteUrl: 'https://alpha.resin.io' - notJSONUserConfig: - name: '/notJSONUserConfig' - contents: 'Just a plain file' - - beforeEach -> - mock.fs.init(filesystem) - - afterEach -> - mock.fs.restore() - - describe 'if no file is passed', -> - - it 'should return undefined', -> - expect(@conf.extendWithFile()).to.be.undefined - - it 'should keep the content unmodified', -> - data = _.cloneDeep(@conf._data) - @conf.extendWithFile() - expect(@conf._data).to.deep.equal(data) - - describe 'if file does not exist', -> - - it 'should return undefined', -> - expect(@conf.extendWithFile('/unexistent_file')).to.be.undefined - - it 'should keep the content unmodified', -> - data = _.cloneDeep(@conf._data) - @conf.extendWithFile('/unexistent_file') - expect(@conf._data).to.deep.equal(data) - - it 'should throw an error if file is not a json file', -> - func = _.partial(@conf.extendWithFile, filesystem.notJSONUserConfig.name) - expect(func).to.throw(Error) - - it 'should extend data with a file', -> - expect(@conf.isEmpty()).to.be.true - @conf.extendWithFile(filesystem.userConfig.name) - expectedContent = JSON.parse(filesystem.userConfig.contents) - expect(@conf._data).to.deep.equal(expectedContent) - - describe '#isEmpty()', -> - - it 'should return true', -> - expect(@conf.isEmpty()).to.be.true - - describe 'given a conf with default values', -> - - object = - one: 'first' - two: 'second' - - beforeEach -> - @conf = new CliConf(default: object) - - it 'should have the data', -> - expect(@conf._data).to.deep.equal(object) - - describe '#isEmpty()', -> - - it 'should return false', -> - expect(@conf.isEmpty()).to.be.false - - describe '#extend()', -> - - beforeEach -> - @conf = new CliConf - default: - greeting: 'Hi' - - it 'should override data values', -> - object = - greeting: 'Hola' - name: 'John Doe' - - @conf.extend(object) - expect(@conf._data).to.deep.equal(object) - - it 'should handle multiple overrides', -> - @conf.extend { - greeting: 'Hola' - name: 'John Doe' - }, { - greeting: 'Pronto' - } - - expect(@conf._data).to.deep.equal - greeting: 'Pronto' - name: 'John Doe' - - describe 'given a supplied user config default', -> - - options = - keys: - userConfig: 'config.user' - default: - remoteUrl: 'https://staging.resin.io' - config: - user: '/Users/jviotti/.resin/config' - - filesystem = - userConfig: - name: options.default.config.user - contents: JSON.stringify - remoteUrl: 'https://alpha.resin.io' - - beforeEach -> - mock.fs.init(filesystem) - @conf = new CliConf(options) - - afterEach -> - mock.fs.restore() - - it 'should load that file and extend _data', -> - parsedUserConfig = JSON.parse(filesystem.userConfig.contents) - expectedResult = _.extend(_.cloneDeep(options.default), parsedUserConfig) - expect(@conf._data).to.deep.equal(expectedResult) - - describe 'given a supplied user and local config', -> - - options = - keys: - userConfig: 'config.user' - localConfig: 'config.local' - default: - remoteUrl: 'https://staging.resin.io' - config: - user: '/Users/jviotti/.resin/config' - local: '.resinconfig' - - filesystem = - localConfig: - name: path.join(process.cwd(), options.default.config.local) - contents: JSON.stringify - remoteUrl: 'https://localhost.resin.io' - userConfig: - name: options.default.config.user - contents: JSON.stringify - remoteUrl: 'https://alpha.resin.io' - - beforeEach -> - mock.fs.init(filesystem) - @conf = new CliConf(options) - - afterEach -> - mock.fs.restore() - - it 'local config should have precedence', -> - parsedUserConfig = JSON.parse(filesystem.userConfig.contents) - parsedLocalConfig = JSON.parse(filesystem.localConfig.contents) - defaultsCopy = _.cloneDeep(options.default) - - expectedResult = _.extend(defaultsCopy, parsedUserConfig, parsedLocalConfig) - expect(@conf._data).to.deep.equal(expectedResult) - - describe 'given supplied keys', -> - - keys = - userConfig: 'config.user' - localConfig: 'config.local' - - beforeEach -> - @conf = new CliConf({ keys }) - - describe '#_getOptionKey()', -> - - it 'should be able to get a key', -> - result = @conf._getOptionKey('userConfig') - expect(result).to.equal(keys.userConfig) - - it 'should return undefined if no input', -> - result = @conf._getOptionKey() - expect(result).to.be.undefined - - it 'should return undefined if key does not exist', -> - result = @conf._getOptionKey('nonexistentkey') - expect(result).to.be.undefined - - describe 'given a user config that changes the local config file name', -> - options = - keys: - userConfig: 'config.user' - localConfig: 'config.local' - default: - remoteUrl: 'https://staging.resin.io' - config: - user: '/Users/jviotti/.resin/config' - local: '.resinconfig' - - newLocalConfig = '.resinrc' - - filesystem = - userConfig: - name: options.default.config.user - contents: JSON.stringify - config: - local: newLocalConfig - localConfig: - name: path.join(process.cwd(), newLocalConfig) - contents: JSON.stringify - remoteUrl: 'https://alpha.resin.io' - - beforeEach -> - mock.fs.init(filesystem) - @conf = new CliConf(options) - - afterEach -> - mock.fs.restore() - - it 'should make use of the renamed config file name', -> - parsedUserConfig = JSON.parse(filesystem.userConfig.contents) - parsedLocalConfig = JSON.parse(filesystem.localConfig.contents) - defaultsCopy = _.cloneDeep(options.default) - - expect(@conf._getLocalConfigPath()).to.equal(filesystem.localConfig.name) - - expectedResult = _.extend(defaultsCopy, parsedUserConfig, parsedLocalConfig) - expect(@conf._data).to.deep.equal(expectedResult) - - describe '#parse()', -> - - beforeEach -> - @conf = new CliConf() - - it 'should use parse JSON by default', -> - input = '{ "hello": 123 }' - result = @conf.parse(input) - parsedInput = JSON.parse(input) - expect(result).to.deep.equal(parsedInput) - - it 'should be able to replace parse function with options', -> - parseFunction = _.identity - @conf = new CliConf(configFileParse: parseFunction) - - expect(@conf._options.configFileParse).to.equal(parseFunction) - input = 'Hello' - result = @conf.parse(input) - expect(result).to.equal(input) - - describe '#_getLocalConfigPath()', -> - - it 'should contruct the path correctly', -> - filename = 'resin' - @conf = new CliConf - keys: - localConfig: 'config.local' - default: - config: - local: filename - - expectedPath = path.join(process.cwd(), filename) - expect(@conf._getLocalConfigPath()).to.equal(expectedPath) - - it 'should return undefined if no local path', -> - @conf = new CliConf() - expect(@conf._getLocalConfigPath()).to.be.undefined diff --git a/lib/resin/settings.coffee b/lib/resin/settings.coffee index 9ab61c8b..2db20f5a 100644 --- a/lib/resin/settings.coffee +++ b/lib/resin/settings.coffee @@ -2,7 +2,7 @@ path = require('path') userHome = require('user-home') helpers = require('./helpers/helpers') -CliConf = require('../cli-conf/cli-conf') +ConfJS = require('conf.js') settings = remoteUrl: 'https://staging.resin.io' @@ -42,7 +42,7 @@ settings = settings.directories = helpers.prefixObjectValuesWithPath(settings.dataPrefix, settings.directories) settings.files = helpers.prefixObjectValuesWithPath(settings.dataPrefix, settings.files) -module.exports = new CliConf +module.exports = new ConfJS keys: userConfig: 'files.config' localConfig: 'localConfig' diff --git a/package.json b/package.json index eb1c5763..c3992dee 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "user-home": "~1.1.0", "fs-plus": "~2.3.2", "lodash-contrib": "~241.4.14", - "coffee-script": "~1.8.0" + "coffee-script": "~1.8.0", + "conf.js": "~0.1.1" } }