mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-31 16:36:24 +00:00
Make use of conf.js instead of mantaining CliConf in the codebase
This commit is contained in:
parent
e4780b12f6
commit
bf9f1bb9c9
@ -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
|
@ -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
|
@ -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'
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user