From 3f0061d2b9ede708071049a4163222825d676dbd Mon Sep 17 00:00:00 2001
From: legodude17
Date: Sun, 14 Aug 2016 13:42:25 -0700
Subject: [PATCH 1/3] Adds support for #82's conclusion.
This adds support for the file extensions and for parsers
by specific extension. All tests pass and a new one was
added to test the extensions.
---
index.js | 25 +++++++------
lib/utils.js | 48 +++++++++++++++++++------
package.json | 7 ++--
test/extensions.js | 87 ++++++++++++++++++++++++++++++++++++++++++++++
test/ini.js | 9 +++--
test/test.js | 2 ++
6 files changed, 151 insertions(+), 27 deletions(-)
create mode 100644 test/extensions.js
diff --git a/index.js b/index.js
index 6f8f113..d72db4e 100755
--- a/index.js
+++ b/index.js
@@ -8,7 +8,7 @@ var home = win
? process.env.USERPROFILE
: process.env.HOME
-module.exports = function (name, defaults, argv, parse) {
+module.exports = function (name, defaults, argv, parsers) {
if('string' !== typeof name)
throw new Error('rc(name): name *must* be string')
if(!argv)
@@ -18,34 +18,39 @@ module.exports = function (name, defaults, argv, parse) {
? cc.json(defaults) : defaults
) || {}
- parse = parse || cc.parse
+ parsers = parsers || cc.parsers
var env = cc.env(name + '_')
-
var configs = [defaults]
var configFiles = []
function addConfigFile (file) {
if (configFiles.indexOf(file) >= 0) return
var fileConfig = cc.file(file)
if (fileConfig) {
- configs.push(parse(fileConfig))
+ configs.push(cc.parse(fileConfig, file, parsers))
configFiles.push(file)
}
}
// which files do we look at?
if (!win)
- [join(etc, name, 'config'),
- join(etc, name + 'rc')].forEach(addConfigFile)
+ [join(etc, name, 'config')].concat(Object.keys(parsers).map(function (v) {
+ return [etc, '.' + name + 'rc.' + v.toLowerCase()]
+ })).forEach(addConfigFile)
if (home)
[join(home, '.config', name, 'config'),
join(home, '.config', name),
- join(home, '.' + name, 'config'),
- join(home, '.' + name + 'rc')].forEach(addConfigFile)
- addConfigFile(cc.find('.'+name+'rc'))
+ join(home, '.' + name, 'config')].concat(Object.keys(parsers).map(function (v) {
+ return [home, '.' + name + 'rc.' + v.toLowerCase()]
+ })).forEach(addConfigFile)
+ Object.keys(parsers).map(function (v) {
+ return v.toLowerCase();
+ }).forEach(function (v) {
+ addConfigFile(cc.find('.' + name + 'rc' + (v ? '.' + v : '')))
+ })
if (env.config) addConfigFile(env.config)
if (argv.config) addConfigFile(argv.config)
-
+
return deepExtend.apply(null, configs.concat([
env,
argv,
diff --git a/lib/utils.js b/lib/utils.js
index ae6dec0..a018b79 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -4,17 +4,46 @@ var ini = require('ini')
var path = require('path')
var stripJsonComments = require('strip-json-comments')
-var parse = exports.parse = function (content) {
-
- //if it ends in .json or starts with { then it must be json.
- //must be done this way, because ini accepts everything.
- //can't just try and parse it and let it throw if it's not ini.
- //everything is ini. even json with a syntax error.
+var parsers = exports.parsers = {
+ '': function (content) {
+ try {
+ return JSON.parse(stripJsonComments(content));
+ } catch (e) {
+ return ini.parse(content)
+ }
+ },
+ 'json': function (content) {
+ try {
+ return JSON.parse(stripJsonComments(content));
+ } catch (e) {
+ return null;
+ }
+ },
+ 'ini': function (content) {
+ return ini.parse(content)
+ }
+};
- if(/^\s*{/.test(content))
- return JSON.parse(stripJsonComments(content))
- return ini.parse(content)
+function getExt(file) {
+ var ext = file.split('.').pop()
+ if (ext.slice(-2) === 'rc') {
+ return '';
+ }
+ return ext;
+}
+var parse = exports.parse = function (contents, file, ps) {
+ var ext
+ if (file) {
+ ext = getExt(file)
+ } else {
+ ext = ''
+ }
+ ps = ps || parsers
+ if (typeof ps[ext] !== 'function') {
+ throw new Error('Extension ' + ext + ' does not have a parser. Valid parsers: ' + Object.keys(ps).join(', '))
+ }
+ return ps[ext](contents)
}
var file = exports.file = function () {
@@ -100,4 +129,3 @@ var find = exports.find = function () {
}
return find(process.cwd(), rel)
}
-
diff --git a/package.json b/package.json
index 38991a7..230123b 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "rc",
- "version": "1.1.6",
+ "version": "2.1.6",
"description": "hardwired configuration loader",
"main": "index.js",
"browserify": "browser.js",
"scripts": {
- "test": "set -e; node test/test.js; node test/ini.js; node test/nested-env-vars.js"
+ "test": "set -e; node test/test.js; node test/ini.js; node test/nested-env-vars.js; node test/extensions.js"
},
"repository": {
"type": "git",
@@ -25,5 +25,8 @@
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~1.0.4"
+ },
+ "devDependencies": {
+
}
}
diff --git a/test/extensions.js b/test/extensions.js
new file mode 100644
index 0000000..03a503b
--- /dev/null
+++ b/test/extensions.js
@@ -0,0 +1,87 @@
+
+var n = 'rc'+Math.random()
+var assert = require('assert')
+var yaml = require('yaml')
+var fs = require('fs')
+var path = require('path')
+var jsonrc = path.resolve('.' + n + 'rc.json');
+
+console.log('---extensions---\n\n')
+
+process.env[n + '_envOption'] = 42
+
+fs.writeFileSync(jsonrc, [
+ '{',
+ '// json overrides default',
+ '"option": false,',
+ '/* env overrides json */',
+ '"envOption": 24',
+ '}'
+].join('\n'));
+
+var commentedJSON = require('../')(n, {
+ option: true
+})
+
+fs.unlinkSync(jsonrc);
+
+console.log('Commented:', commentedJSON, commentedJSON.configs)
+
+assert.equal(commentedJSON.option, false)
+assert.equal(commentedJSON.envOption, 42)
+
+assert.equal(commentedJSON.config, jsonrc)
+assert.equal(commentedJSON.configs.length, 1)
+assert.equal(commentedJSON.configs[0], jsonrc)
+
+var inirc = path.resolve('.' + n + 'rc.ini');
+
+fs.writeFileSync(inirc, [
+ '; ini overrides default',
+ 'option=false',
+ '; env overrides ini',
+ 'envOption=24'
+].join('\n'));
+
+var ini = require('../')(n, {
+ option: true
+})
+
+fs.unlinkSync(inirc);
+
+console.log(ini)
+
+assert.equal(ini.option, false)
+assert.equal(ini.envOption, 42)
+
+assert.equal(ini.config, inirc)
+assert.equal(ini.configs.length, 1)
+assert.equal(ini.configs[0], inirc)
+
+var yamlrc = path.resolve('.' + n + 'rc.yaml');
+
+fs.writeFileSync(yamlrc, [
+ '---',
+ ' envOption: 24',
+ ' option: false',
+ ''
+].join('\n'));
+
+var yamlconfig = require('../')(n, {
+ option: true
+}, false, {
+ 'yaml': function (contents) {
+ return yaml.eval(contents)
+ }
+})
+
+fs.unlinkSync(yamlrc);
+
+console.log(yamlconfig)
+
+assert.equal(yamlconfig.option, false)
+assert.equal(yamlconfig.envOption, 42)
+
+assert.equal(yamlconfig.config, yamlrc)
+assert.equal(yamlconfig.configs.length, 1)
+assert.equal(yamlconfig.configs[0], yamlrc)
diff --git a/test/ini.js b/test/ini.js
index e6857f8..5ddbf0a 100644
--- a/test/ini.js
+++ b/test/ini.js
@@ -2,15 +2,14 @@ var cc =require('../lib/utils')
var INI = require('ini')
var assert = require('assert')
-function test(obj) {
+console.log('---ini---\n\n')
+function test(obj) {
var _json, _ini
- var json = cc.parse (_json = JSON.stringify(obj))
- var ini = cc.parse (_ini = INI.stringify(obj))
+ var json = cc.parse(_json = JSON.stringify(obj))
+ var ini = cc.parse(_ini = INI.stringify(obj))
console.log(_ini, _json)
assert.deepEqual(json, ini)
}
-
test({hello: true})
-
diff --git a/test/test.js b/test/test.js
index 4f63351..78b4295 100644
--- a/test/test.js
+++ b/test/test.js
@@ -2,6 +2,8 @@
var n = 'rc'+Math.random()
var assert = require('assert')
+console.log('---Main test---\n\n')
+
process.env[n+'_envOption'] = 42
var config = require('../')(n, {
From 4c89a4141b03cc3304fa223a85ad564ac66ee94e Mon Sep 17 00:00:00 2001
From: legodude17
Date: Sun, 14 Aug 2016 14:14:02 -0700
Subject: [PATCH 2/3] Add yaml to dev deps
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 230123b..f3a517f 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,6 @@
"strip-json-comments": "~1.0.4"
},
"devDependencies": {
-
+ "yaml": "^0.3.0"
}
}
From 4c9069dd62e67dc2133af4035a7ed74018afa135 Mon Sep 17 00:00:00 2001
From: legodude17
Date: Mon, 15 Aug 2016 07:49:19 -0700
Subject: [PATCH 3/3] Expose parsers and parse
---
index.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/index.js b/index.js
index d72db4e..4acaf59 100755
--- a/index.js
+++ b/index.js
@@ -50,7 +50,7 @@ module.exports = function (name, defaults, argv, parsers) {
})
if (env.config) addConfigFile(env.config)
if (argv.config) addConfigFile(argv.config)
-
+
return deepExtend.apply(null, configs.concat([
env,
argv,
@@ -58,6 +58,9 @@ module.exports = function (name, defaults, argv, parsers) {
]))
}
+module.exports.parsers = cc.parsers;
+module.exports.parse = cc.parse;
+
if(!module.parent) {
console.log(
JSON.stringify(module.exports(process.argv[2]), false, 2)