Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added support for configuration file. #10

Closed
wants to merge 1 commit into from

2 participants

@ichernev

This patch enables the users to specify that an option points to
a configuration file containing json formated options. The options
specified in the configuration file are validated in the same manner as
the other command line options. Configuration file options have lower
precedence than command line options.

@ichernev ichernev Added support for configuration file.
This patch enables the users to specify that an option points to
a configuration file containing json formated options. The options
specified in the configuration file are validated in the same manner as
the other command line options. Configuration file options have lower
precedence than command line options.
c2f8ac4
@isaacs
Owner

Thanks. This is a nice idea (indeed, not far from what npm does itself with nopt), but I think I'm going to not pull it into nopt. I do plan to split out npm's config file management into a separate module, but I'd like to keep nopt as strictly options parsing and validating (which are safely synchronous), rather than file parsing.

A large part of that decision is that it would require a readFileSync call as you have here, or a callback, which would require changing around a lot of nopt-using code.

You can still use this in your own programs by putting this in your package.json, of course:

{ "name": "blah"
, "version": "1.2.4"
, "dependencies": { "nopt": "git://github.com/ichernev/nopt" }
, "bundledDependencies": [ "nopt" ]
}
@isaacs isaacs closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 8, 2011
  1. @ichernev

    Added support for configuration file.

    ichernev authored
    This patch enables the users to specify that an option points to
    a configuration file containing json formated options. The options
    specified in the configuration file are validated in the same manner as
    the other command line options. Configuration file options have lower
    precedence than command line options.
This page is out of date. Refresh to see the latest.
Showing with 52 additions and 7 deletions.
  1. +4 −0 examples/config.json
  2. +4 −0 examples/my-program.js
  3. +44 −7 lib/nopt.js
View
4 examples/config.json
@@ -0,0 +1,4 @@
+{ "browser": "firefox",
+ "t": ["foo", "is", "bar"],
+ "aoa": [1, 2, "quux"]
+}
View
4 examples/my-program.js
@@ -12,6 +12,10 @@ var nopt = require("../lib/nopt")
, "bloo" : [ "big", "medium", "small" ]
, "flag" : Boolean
, "pick" : Boolean
+ , "browser": String
+ , "t": [String, Array]
+ , "aoa": Array
+ , "config": nopt.configFile
}
, shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
, "b7" : ["--bar", "7"]
View
51 lib/nopt.js
@@ -8,18 +8,22 @@ var url = require("url")
, path = require("path")
, Stream = require("stream").Stream
, abbrev = require("abbrev")
+ , fs = require("fs")
+ , configFile = {}
module.exports = exports = nopt
exports.clean = clean
+exports.configFile = configFile
exports.typeDefs =
- { String : { type: String, validate: validateString }
- , Boolean : { type: Boolean, validate: validateBoolean }
- , url : { type: url, validate: validateUrl }
- , Number : { type: Number, validate: validateNumber }
- , path : { type: path, validate: validatePath }
- , Stream : { type: Stream, validate: validateStream }
- , Date : { type: Date, validate: validateDate }
+ { String : { type: String, validate: validateString }
+ , Boolean : { type: Boolean, validate: validateBoolean }
+ , url : { type: url, validate: validateUrl }
+ , Number : { type: Number, validate: validateNumber }
+ , path : { type: path, validate: validatePath }
+ , Stream : { type: Stream, validate: validateStream }
+ , Date : { type: Date, validate: validateDate }
+ , configFile : { type: configFile, validate: validatePath }
}
function nopt (types, shorthands, args, slice) {
@@ -39,6 +43,7 @@ function nopt (types, shorthands, args, slice) {
parse(args, data, remain, types, shorthands)
// now data is full
+ loadConfig(data, types, exports.typeDefs)
clean(data, types, exports.typeDefs)
data.argv = {remain:remain,cooked:cooked,original:original}
data.argv.toString = function () {
@@ -47,6 +52,32 @@ function nopt (types, shorthands, args, slice) {
return data
}
+function loadConfig (data, types, typeDefs) {
+ typeDefs = typeDefs || exports.typeDefs
+ var key
+ , config_buf
+ , config_opts
+
+ Object.keys(types).forEach(function(k) {
+ if (types[k] === configFile) key = k
+ })
+
+ if (key && data[key]) {
+ try {
+ config_buf = fs.readFileSync(data[key])
+ config_opts = JSON.parse(config_buf.toString("ascii"))
+ Object.keys(config_opts).forEach(function(k) {
+ if (!data.hasOwnProperty(k))
+ data[k] = config_opts[k]
+ })
+ return true
+ } catch(e) {
+ console.error(e)
+ }
+ }
+ return false
+}
+
function clean (data, types, typeDefs) {
typeDefs = typeDefs || exports.typeDefs
var remove = {}
@@ -442,6 +473,7 @@ var assert = require("assert")
, version : Boolean
, viewer: path
, _exit : Boolean
+ , config: configFile
}
; [["-v", {version:true}, []]
@@ -530,6 +562,11 @@ var assert = require("assert")
,["--date 2011-01-25"
,{date: new Date("2011-01-25")}
,[]]
+ ,["--config examples/config.json"
+ ,{browser: "firefox"
+ ,t: ["foo", "is", "bar"]
+ ,aoa: [1, 2, 'quux']}
+ ,[]]
].forEach(function (test) {
var argv = test[0].split(/\s+/)
, opts = test[1]
Something went wrong with that request. Please try again.