Make use of conf.js instead of mantaining CliConf in the codebase

This commit is contained in:
Juan Cruz Viotti 2014-12-11 11:34:36 -04:00
parent e4780b12f6
commit bf9f1bb9c9
4 changed files with 4 additions and 386 deletions

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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"
}
}