tohagan / cli-config

NodeJS API to assist command line apps reading and merging config objects from: defaults.json, ./<app>.json, process.argv, custom config
Other
6 stars 1 forks source link

DESCRIPTION

A simple getConfig() call that combines properties from ...

If your app uses commands verbs you can implement your entire command line interface using a single run() method that ...

Simplest API calls:

This might be all you need to create a complete command line interface to your lib:

#!/usr/bin/env node
require('cli-config').run({dirname: __dirname, cmdTree: require(__dirname + '/lib'});

If you only need to fetch configuration and command line options:

var config = require('cli-config').getConfig({dirname: __dirname});

Design & Features:

Details:

API

getConfig(options)

Returns configuration settings object.

var config = require('cli-config').getConfig(options);

Options:

.json files are parsed as UTF8 JSON format that can contain // or /* ... */ comments.

Returns:

As of v0.4.0, All settings files have the same name which defaults to .<appname>.json where <appname> is the appname defined in package.json. This can be changed by setting options.configFile.

Example 1:

Assume that the package.json file defines appnam to myapp.

This example will combine settings from the package settings file .myapp.json then users settings from ~/.myapp.json then command line options then force the debug option to be true. Uses a shallow merge so only the top level properties are merged.

#!/usr/bin/env node

var config = require('../cli-config').getConfig({dirname: __dirname, override: {debug: true}});

console.log(config.pkg.appName + ' ' + config.pkg.version); // Use package.json fields
console.log(config);

Example 2:

This example will deep merge nested settings from a package settings file named $__dirname/app.yaml then ~/app.yaml then command line options. If $HOME/app.yaml does not exist, it clones a copy from the package settings file $__dirname/app.yaml so the user can override the default package settings with their own.

var config = require('../cli-config').getConfig({
    dirname: __dirname,      // Looks for `package.json` and a package settings file (named `configFile`) in this folder
    configFile: 'app.yaml',  // Name of settings files (Default '.<appname>.json')
    clone: true,             // Creates a ~/app.yaml file if none exists.
    parser: YAML.parse,      // Parse settings files using YAML parser.  require 'yamljs' package.
    merge: 'deep'            // Deep merge all config file settings & command line settings.
});

Example 3:

The command line parser returns an object that can be used to override the system settings or user settings options. You can configure this parser using the cli option. Refer to minimist used by this lib for more details about command line parsing options.

var config = require('../cli-config').getConfig({
    dirname: __dirname,
    cli: {
        boolean: {
            'd': 'debug',
            'v': 'verbose'
        }
    }
});

Sets the config.debug and config.verbose options to true.

$ myapp -d -v

findCommand(options, config, callback)

Finds a command function from a command tree.

Options:

Returns:

Example:

// libs containing action functions that accept `config` object as single argument created by `getConfig()`
var pigs = require('lib/pigs");
var farm = require('lib/farm");

// Map of command line verbs
var cmdTree = {
    version: function(options) {
        // Use fields from your package.json file
        console.info(options.pkg.name + ' ' + options.pkg.version);
    },
    settings: function(options) {
        console.info(options);
    },
    // 'help' function is called if no commands match and options. fnHelp is not defined.
    help: function() {
        var appName = path.basename(process.argv[1]);
        [
            'Commands:',
            'pigs add  -n <name>   - Add Pigs to the farm',
            'pigs remove -n <name> - Remove last pig from the farm',
            'pigs fly              - Makes all pigs fly',
            'farm init -n <name>   - Initialise farm',
            'farm list             - List farm animals',
            'version               - Displays app name & version',
            'settings              - Displays app settings'
            'help                  - Displays this help message'
        ].forEach(function(line) {
            console.info(appName + ' ' + line);
        });
    },

    // LIB commands
    // Replace with just "pigs: require('lib/pigs")" and any new exported functions become commands!
    pigs: {
        add:    pigs.add,
        remove: pigs.remove,
        fly:    pigs.fly
    }
    // Replace with just "farm: require('lib/farm")" and any new exported functions become commands!
    farm: {
        init: farm.init,
        list: farm.list
    }
};

var cli = require('cli-config');
var config = cli.getConfig({ dirname: __dirname });
var result = cli.findCommand({cmdTree: cmdTree}, config, function(fnCmd, args) {   // <== EXAMPLE API CALL
    return fnCmd.call(this, config, args); // Execute command function
});

run(options)

Combines getConfig() and findCommand() into a single run() call.

Loads configuration settings and executes a command function from the command tree and returns it's result.

Options:

Returns:

Example

#!/usr/bin/env node

try {
    var cmdTree = { ... } // Same as getCommandFn() example above.

    var cli = require('cli-config');
    cli.run({
        dirname: __dirname,
        clone: true,
        cli: {
            boolean: {
                'v': 'verbose'  // -v = true/false flag
            },
            string: {
                'n': 'name'     // -n <name> = abbreviation for -name <name>
            }
        },
        cmdTree: cmdTree,
        fnHelp: cmdTree.help
    });
} catch (err) {
    console.error(err);
    process.exit(1);
}