¶ config modulemanages configuration and the there are multiple ways to configure, from lowest to highest priority..
just to complicate things, the plugin structure needs to allow configuration to occur within the plugin file.. so configuration needs to be able to happen in a decentralised way.
|
|
require the good stuff |
var _ = require('./underscore.js');
var ini = require('ini');
var path = require('path');
var cli = require('cli');
|
This is the real, unwrapped one, avoids circular require |
var fs = require('fs');
|
declaration |
var config;
var getCommandLine;
var getIni;
var filterOptions;
var options = {};
var validationFns = [];
var initFns = [];
|
¶ filterOptionsthis is a convenience function to deal with the fact that readIni and commander both return an object with various methods and properties which are not actually part of this app's configuration. so when you run readIni and commander, you can run the result through this function to strip out most of the nonsense. Params
list
object
settings object
|
filterOptions = function(list) {
return _.omit(list, function(value, key) {
return (
(_.isFunction(value)) ||
(!_.has(list, key))
);
});
};
|
getCommandLine = function() {
cli.enable('version', 'help');
cli.parse(options);
return cli.options;
};
|
|
command.option( '--err-no-match [action]', 'action where movie cannot be identified', /^(leave|delete)$/i ); command.option( '--err-vol-num [action]', 'action where multiple volumes are not numbered', /^(leave|delete)$/i ); command.option( '--err-target-exists [action]', 'action where target directory / movie already exists', /^(leave|delete)$/i ); |
|
getIni = function(configFile) {
var iniFile;
|
|
Find config file |
if (configFile) {
if (!fs.existsSync(configFile)) {
throw 'cant find config: ' + configFile;
}
}
console.log(configFile);
iniFile = fs.readFileSync(configFile, 'utf-8');
iniFile = ini.parse(iniFile);
iniFile = filterOptions(iniFile);
return iniFile;
}
|
¶ initdefaults doesn't work how it might appear, it's not really defaults or extend or whatever.
command line > ini file > defaults the only way I could find to do this was to collect options in Params
modOptions
Object
modOptions.fromIni
Boolean
load config from ini
modOptions.fromCli
Boolean
load config from cli
|
init = function(modOptions) {
var cliOptions = {};
var iniOptions = {};
var defaults = {};
|
populate options |
push({
options: {
configFile: [
'c',
'specify config file',
'file',
path.join(path.resolve(__dirname, '..'), 'config.ini')
]
}
});
push(require('./configShared'));
|
remove the defaults from options to be passed to cli |
_.each(options, function(value, key) {
if (value.length == 4) {
defaults[key] = value.pop();
}
});
if (modOptions.fromCli) {
|
get options from cli, purge null values |
cliOptions = _.compactObject(getCommandLine());
};
if (modOptions.fromIni) {
|
get options from ini |
iniOptions = getIni(cliOptions.configFile || defaults.configFile);
}
|
amalgamate, right most has precedence |
_.extend(config, defaults, iniOptions, cliOptions, modOptions);
_.each(validationFns, function(fn) {
fn(config);
});
_.each(initFns, function(fn) {
fn(config);
});
};
|
¶ pushsee lib/fsItems.js for example usage. Params
definition
Object
definition.options
Object
cli style arrays
[definition.validation]
Function
validation function
[definition.init]
Function
initialisation function
¶ initialisation functions
|
push = function(definition) {
_.extend(options, definition.options);
if (definition.validation) {
validationFns.push(definition.validation);
}
if (definition.init) {
initFns.push(definition.init);
}
};
|
¶ push.keyshere for reference, convenience |
push.keys = [ 'options', 'validation', 'init' ];
|
¶ configinitialize the object here.. this ensures the |
config = {
init: init,
push: push,
options: options
};
module.exports = config;
|