From 9da37dff2acd10a104fdf483f9c85b327867cb39 Mon Sep 17 00:00:00 2001 From: indexzero Date: Sat, 14 May 2011 01:47:26 -0400 Subject: [PATCH] [dist api test] Refactor pluggable nconf-level logic into nconf.Provider. Update .gitignore for npm 1.0. Update pathing in source and tests to be more `require.paths` future-proof --- .gitignore | 3 +- lib/nconf.js | 146 ++++--------------------------------- lib/nconf/provider.js | 127 ++++++++++++++++++++++++++++++++ lib/nconf/stores.js | 17 ++++- lib/nconf/stores/memory.js | 2 +- lib/nconf/stores/redis.js | 4 +- package.json | 6 +- test/file-store-test.js | 4 +- test/memory-store-test.js | 4 +- test/nconf-test.js | 4 +- test/redis-store-test.js | 4 +- usage.js | 4 +- 12 files changed, 167 insertions(+), 158 deletions(-) create mode 100644 lib/nconf/provider.js diff --git a/.gitignore b/.gitignore index d6d4ffe..68f9021 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store config.json -test/fixtures/*.json \ No newline at end of file +test/fixtures/*.json +node_modules \ No newline at end of file diff --git a/lib/nconf.js b/lib/nconf.js index a9eb3b8..cadb34e 100644 --- a/lib/nconf.js +++ b/lib/nconf.js @@ -5,143 +5,14 @@ * */ -require.paths.unshift(__dirname); - -var nconf = exports; +var Provider = require('./nconf/provider').Provider, + nconf = module.exports = Object.create(Provider.prototype); // // ### Version 0.1.7 :: 4/20/2011 // nconf.version = [0, 1, 7]; -// -// Include the various store types exposed by nconf -// -nconf.stores = require('nconf/stores'); - -// -// ### function use (type, options) -// #### @type {string} Type of the nconf store to use. -// #### @options {Object} Options for the store instance. -// Sets the active `nconf.store` to a new instance of the -// specified `type`. -// -nconf.use = function (type, options) { - if (!nconf.store || type.toLowerCase() !== nconf.store.type) { - nconf.store = new nconf.stores.create(type, options); - } -}; - -// -// ### function get (key, callback) -// #### @key {string} Key to retrieve for this instance. -// #### @callback {function} **Optional** Continuation to respond to when complete. -// Retrieves the value for the specified key (if any). -// -nconf.get = function (key, callback) { - return nconf.store.get(key, callback); -}; - -// -// ### function set (key, value, callback) -// #### @key {string} Key to set in this instance -// #### @value {literal|Object} Value for the specified key -// #### @callback {function} **Optional** Continuation to respond to when complete. -// Sets the `value` for the specified `key` in this instance. -// -nconf.set = function (key, value, callback) { - return nconf.store.set(key, value, callback); -}; - -// -// ### function clear (key, callback) -// #### @key {string} Key to remove from this instance -// #### @callback {function} **Optional** Continuation to respond to when complete. -// Removes the value for the specified `key` from this instance. -// -nconf.clear = function (key, callback) { - return nconf.store.clear(key, callback); -}; - -// -// ### function load (callback) -// #### @callback {function} Continuation to respond to when complete. -// Responds with an Object representing all keys associated in this instance. -// -nconf.load = function (callback) { - // - // If we don't have a callback and the current - // store is capable of loading synchronously - // then do so. - // - if (!callback && nconf.store.loadSync) { - return nconf.store.loadSync(); - } - - - if (!nconf.store.load) { - var error = new Error('nconf store ' + nconf.store.type + ' has no load() method'); - if (callback) { - return callback (error); - } - - throw error; - } - - return nconf.store.load(callback); -}; - -// -// ### function save (value, callback) -// #### @value {Object} **Optional** Config object to set for this instance -// #### @callback {function} Continuation to respond to when complete. -// Removes any existing configuration settings that may exist in this -// instance and then adds all key-value pairs in `value`. -// -nconf.save = function (value, callback) { - if (!callback) { - callback = value; - value = null; - - // - // If we still don't have a callback and the - // current store is capable of saving synchronously - // then do so. - // - if (!callback && nconf.store.saveSync) { - return nconf.store.saveSync(); - } - } - - if (!nconf.store.save) { - var error = new Error('nconf store ' + nconf.store.type + ' has no save() method'); - if (callback) { - return callback (error); - } - - throw error; - } - - return nconf.store.save(value, callback); -}; - -// -// ### function reset (callback) -// #### @callback {function} **Optional** Continuation to respond to when complete. -// Clears all keys associated with this instance. -// -nconf.reset = function (callback) { - return nconf.store.reset(callback); -}; - -// -// ### function key (arguments) -// Returns a `:` joined string from the `arguments`. -// -nconf.key = function () { - return Array.prototype.slice.call(arguments).join(':'); -}; - // // ### function path (key) // #### @key {string} The ':' delimited key to split @@ -152,6 +23,15 @@ nconf.path = function (key) { }; // -// Use the `memory` engine by default +// ### function key (arguments) +// Returns a `:` joined string from the `arguments`. // -nconf.use('memory'); +nconf.key = function () { + return Array.prototype.slice.call(arguments).join(':'); +}; + +// +// Expose the various components included with nconf +// +nconf.stores = require('./nconf/stores'); +nconf.Provider = Provider; \ No newline at end of file diff --git a/lib/nconf/provider.js b/lib/nconf/provider.js new file mode 100644 index 0000000..9b755be --- /dev/null +++ b/lib/nconf/provider.js @@ -0,0 +1,127 @@ +/* + * provider.js: Abstraction providing an interface into pluggable configuration storage. + * + * (C) 2011, Charlie Robbins + * + */ + +var stores = require('./stores'); + +var Provider = exports.Provider = function (options) { + options = options || {}; +}; + +// +// ### function use (type, options) +// #### @type {string} Type of the nconf store to use. +// #### @options {Object} Options for the store instance. +// Sets the active `this.store` to a new instance of the +// specified `type`. +// +Provider.prototype.use = function (type, options) { + if (!this.store || type.toLowerCase() !== this.store.type) { + this.store = new stores.create(type, options); + } +}; + +// +// ### function get (key, callback) +// #### @key {string} Key to retrieve for this instance. +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Retrieves the value for the specified key (if any). +// +Provider.prototype.get = function (key, callback) { + return this.store.get(key, callback); +}; + +// +// ### function set (key, value, callback) +// #### @key {string} Key to set in this instance +// #### @value {literal|Object} Value for the specified key +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Sets the `value` for the specified `key` in this instance. +// +Provider.prototype.set = function (key, value, callback) { + return this.store.set(key, value, callback); +}; + +// +// ### function clear (key, callback) +// #### @key {string} Key to remove from this instance +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Removes the value for the specified `key` from this instance. +// +Provider.prototype.clear = function (key, callback) { + return this.store.clear(key, callback); +}; + +// +// ### function load (callback) +// #### @callback {function} Continuation to respond to when complete. +// Responds with an Object representing all keys associated in this instance. +// +Provider.prototype.load = function (callback) { + // + // If we don't have a callback and the current + // store is capable of loading synchronously + // then do so. + // + if (!callback && this.store.loadSync) { + return this.store.loadSync(); + } + + + if (!this.store.load) { + var error = new Error('nconf store ' + this.store.type + ' has no load() method'); + if (callback) { + return callback (error); + } + + throw error; + } + + return this.store.load(callback); +}; + +// +// ### function save (value, callback) +// #### @value {Object} **Optional** Config object to set for this instance +// #### @callback {function} Continuation to respond to when complete. +// Removes any existing configuration settings that may exist in this +// instance and then adds all key-value pairs in `value`. +// +Provider.prototype.save = function (value, callback) { + if (!callback) { + callback = value; + value = null; + + // + // If we still don't have a callback and the + // current store is capable of saving synchronously + // then do so. + // + if (!callback && this.store.saveSync) { + return this.store.saveSync(); + } + } + + if (!this.store.save) { + var error = new Error('nconf store ' + this.store.type + ' has no save() method'); + if (callback) { + return callback (error); + } + + throw error; + } + + return this.store.save(value, callback); +}; + +// +// ### function reset (callback) +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Clears all keys associated with this instance. +// +Provider.prototype.reset = function (callback) { + return this.store.reset(callback); +}; \ No newline at end of file diff --git a/lib/nconf/stores.js b/lib/nconf/stores.js index 2859780..e80f2e9 100644 --- a/lib/nconf/stores.js +++ b/lib/nconf/stores.js @@ -5,15 +5,24 @@ * */ -var stores = exports; +var fs = require('fs'), + stores = exports; function capitalize (str) { return str && str[0].toUpperCase() + str.slice(1); }; -stores.Memory = require('nconf/stores/memory').Memory; -stores.File = require('nconf/stores/file').File; -stores.Redis = require('nconf/stores/redis').Redis; +// +// Setup all stores as lazy-loaded getters. +// +fs.readdirSync(__dirname + '/stores').forEach(function (file) { + var store = file.replace('.js', ''), + name = capitalize(store); + + stores.__defineGetter__(name, function () { + return require('./stores/' + store)[name]; + }); +}); // // ### function create (type, options) diff --git a/lib/nconf/stores/memory.js b/lib/nconf/stores/memory.js index c0a7017..74b5520 100644 --- a/lib/nconf/stores/memory.js +++ b/lib/nconf/stores/memory.js @@ -5,7 +5,7 @@ * */ -var nconf = require('nconf'); +var nconf = require('../../nconf'); // // ### function Memory (options) diff --git a/lib/nconf/stores/redis.js b/lib/nconf/stores/redis.js index 1b7a8ee..b07ddeb 100644 --- a/lib/nconf/stores/redis.js +++ b/lib/nconf/stores/redis.js @@ -7,7 +7,7 @@ var async = require('async'), redis = require('redis'), - nconf = require('nconf'), + nconf = require('../../nconf'), Memory = require('./memory').Memory; // @@ -38,7 +38,7 @@ var Redis = exports.Redis = function (options) { // Suppress errors from the Redis client this.redis.on('error', function (err) { - require('eyes').inspect(err); + console.dir(err); }); }; diff --git a/package.json b/package.json index 0c163dd..1d88849 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,10 @@ }, "keywords": ["configuration", "key value store", "redis"], "dependencies": { - "async": ">= 0.1.8", - "redis": ">= 0.5.9", + "async": ">= 0.1.x", + "redis": ">= 0.5.x" + }, + "devDependencies": { "vows": ">= 0.5.8" }, "main": "./lib/nconf", diff --git a/test/file-store-test.js b/test/file-store-test.js index afd668d..7a020ac 100644 --- a/test/file-store-test.js +++ b/test/file-store-test.js @@ -5,13 +5,11 @@ * */ -require.paths.unshift(require('path').join(__dirname, '..', 'lib')); - var fs = require('fs'), path = require('path'), vows = require('vows'), assert = require('assert'), - nconf = require('nconf'), + nconf = require('../lib/nconf'), data = require('./fixtures/data').data, store; diff --git a/test/memory-store-test.js b/test/memory-store-test.js index 199ca3b..57c6244 100644 --- a/test/memory-store-test.js +++ b/test/memory-store-test.js @@ -5,11 +5,9 @@ * */ -require.paths.unshift(require('path').join(__dirname, '..', 'lib')); - var vows = require('vows'), assert = require('assert'), - nconf = require('nconf'); + nconf = require('../lib/nconf'); vows.describe('nconf/stores/memory').addBatch({ "When using the nconf memory store": { diff --git a/test/nconf-test.js b/test/nconf-test.js index 23e2132..03bdc8a 100644 --- a/test/nconf-test.js +++ b/test/nconf-test.js @@ -5,13 +5,11 @@ * */ -require.paths.unshift(require('path').join(__dirname, '..', 'lib')); - var fs = require('fs'), path = require('path'), vows = require('vows'), assert = require('assert'), - nconf = require('nconf'), + nconf = require('../lib/nconf'), data = require('./fixtures/data').data; vows.describe('nconf').addBatch({ diff --git a/test/redis-store-test.js b/test/redis-store-test.js index 1b059d8..a7ea55e 100644 --- a/test/redis-store-test.js +++ b/test/redis-store-test.js @@ -5,11 +5,9 @@ * */ -require.paths.unshift(require('path').join(__dirname, '..', 'lib')); - var vows = require('vows'), assert = require('assert'), - nconf = require('nconf'), + nconf = require('../lib/nconf'), data = require('./fixtures/data').data; vows.describe('nconf/stores/redis').addBatch({ diff --git a/usage.js b/usage.js index 2e4d78f..05ba1b3 100644 --- a/usage.js +++ b/usage.js @@ -1,8 +1,6 @@ -require.paths.unshift(require('path').join(__dirname, 'lib')); - var fs = require('fs'), path = require('path'), - nconf = require('nconf'); + nconf = require('./lib/nconf'); // // Setup nconf to user the 'file' store and set a couple of values;