From b7cb2cc3f16f550e5639419f82be2f845fc55665 Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 14:48:00 -0800 Subject: [PATCH 01/10] Adding "dynamic mode", splitting out enabled/disable logic into it's own file This adds the ability for namespaces to be enabled or disabled on the fly (aka: dynamic mode) Rather than simply returning an enabled/disabled function, when dynamic mode is engaged, it will instead return a thin wrapper that checks the enabled status before each and every call. To accomodate this, the enable/disable lists needed to be upgraded. The new file (able.js) is a singleton that facilitates this feature. Before, the list was really only capable of being modified during init, but afterwards fell flat. This brings more capability there, and also makes that specific feature more testable. --- able.js | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ browser.js | 6 ++- component.json | 3 +- debug.js | 101 +++++++++++----------------------- node.js | 15 ++++-- package.json | 3 +- 6 files changed, 195 insertions(+), 76 deletions(-) create mode 100644 able.js diff --git a/able.js b/able.js new file mode 100644 index 00000000..d3921199 --- /dev/null +++ b/able.js @@ -0,0 +1,143 @@ +/** + * in-memory cache + */ + +var enabled = []; +var disabled = []; + +/** + * Checks if the specified `ns` is enabled. + * + * @param {String} ns Wildcards are not supported here + * @returns {Boolean} + */ + +exports.enabled = function (ns) { + if (find(disabled, ns, true) > -1) return false; + if (find(enabled, ns, true) > -1) return true; + return false; +}; + +/** + * Destroys the lists of enabled/disabled. (primarilly for testing purposes) + */ + +exports.clear = function () { + disabled.length = enabled.length = 0; // truncates w/o destroying +}; + +/** + * Outputs the list of enable/disabled in a single string. + * + * @returns {String} + */ + +exports.stringify = function () { + var e = enabled.map(function (item) { + return item.string; + }); + + var d = disabled.map(function (item) { + return '-' + item.string; + }); + + return e.concat(d).join(','); +}; + +/** + * Parses a list and enables/disables accordingly. + * + * This list can either be passed from the user directly, or from .stringify() + * + * @param {String} str + */ + +exports.parse = function (str) { + str.split(/[\s,]+/).forEach(function (ns) { + if (!ns) return; + else if ('-' == ns[0]) exports.disable(ns.slice(1)); + else exports.enable(ns); + }); +}; + +/** + * Enables the specified `ns`. + * + * @param {String} ns + */ + +exports.enable = function (ns) { + prune(disabled, ns); + if (find(enabled, ns) > -1) return; + + enabled.push({ + string: ns, + regex: regex(ns) + }); +}; + +/** + * Disables the specified `ns`. + * + * @param {String} ns + */ + +exports.disable = function (ns) { + prune(enabled, ns); + if (find(disabled, ns) > -1) return; + + disabled.push({ + string: ns, + regex: regex(ns) + }); +}; + +/** + * Searches for the given `ns` in the `arr`. + * + * By default, it only matches on the raw string, but if `regex` is set, it will + * match via the `RegExp` instead. + * + * Returns the index of the match, or -1 if not found. + * + * @param {Array} arr + * @param {String} ns + * @param {Boolean} [regex] + * @returns {Number} + */ + +function find(arr, ns, regex) { + var ret = -1; + arr.some(function (item, x) { + if (regex ? item.regex.test(ns) : ns === item.string) { + ret = x; + return true; + } + }); + return ret; +} + +/** + * Wraps around `find(...)`, but also removes the found item. + * + * @param {Array} arr + * @param {String} ns + * @param {Boolean} [regex] + */ + +function prune(arr, ns, regex) { + var x = find(arr, ns, regex); + if (x > -1) arr.splice(x, 1); +} + +/** + * Converts a raw `ns` into a `RegExp`. + * + * @param {String} ns + * @returns {RegExp} + */ + +function regex(ns) { + var pattern = ns.replace(/\*/g, '.*?'); + return new RegExp('^' + pattern + '$'); +} diff --git a/browser.js b/browser.js index ce6369f1..dc261356 100644 --- a/browser.js +++ b/browser.js @@ -115,8 +115,10 @@ function log() { * @api private */ -function save(namespaces) { +function save() { try { + var namespaces = exports.stringify(); + if (null == namespaces) { localStorage.removeItem('debug'); } else { @@ -144,4 +146,4 @@ function load() { * Enable namespaces listed in `localStorage.debug` initially. */ -exports.enable(load()); +exports.parse(load()); diff --git a/component.json b/component.json index 7ee3d13a..a1bc50aa 100644 --- a/component.json +++ b/component.json @@ -11,7 +11,8 @@ "main": "browser.js", "scripts": [ "browser.js", - "debug.js" + "debug.js", + "able.js" ], "dependencies": { "guille/ms.js": "0.6.1" diff --git a/debug.js b/debug.js index 7571a860..f1a17d9c 100644 --- a/debug.js +++ b/debug.js @@ -8,17 +8,13 @@ exports = module.exports = debug; exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; exports.humanize = require('ms'); +exports.dynamic = dynamic; -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; +var able = require('./able'); +exports.enabled = able.enabled; +exports.enable = able.enable; +exports.disable = able.disable; /** * Map of special "%n" handling functions, for the debug "format" argument. @@ -28,6 +24,12 @@ exports.skips = []; exports.formatters = {}; +/** + * Flag for dynamic status. + */ + +var isDynamic = false; + /** * Previously assigned color. */ @@ -117,70 +119,20 @@ function debug(namespace) { logFn.apply(self, args); } enabled.enabled = true; + enabled.namespace = namespace; - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } + function dynamic() { + if (!exports.enabled(namespace)) return disabled(); + return enabled.apply(enabled, arguments); } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ + dynamic.namespace = namespace; -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } + function fn() { + if (isDynamic) return dynamic; + return exports.enabled(namespace) ? enabled : disabled; } - return false; + + return fn(); } /** @@ -195,3 +147,14 @@ function coerce(val) { if (val instanceof Error) return val.stack || val.message; return val; } + +/** + * Get/set the dynamic flag + * + * @param {Boolean} [flag] + * @returns {Boolean} + */ + +function dynamic(flag) { + isDynamic = !!flag; +} diff --git a/node.js b/node.js index 5dc999fe..0821e7ec 100644 --- a/node.js +++ b/node.js @@ -109,11 +109,12 @@ function log() { /** * Save `namespaces`. * - * @param {String} namespaces * @api private */ -function save(namespaces) { +function save() { + var namespaces = exports.stringify(); + if (null == namespaces) { // If you set a process.env field to null or undefined, it gets cast to the // string 'null' or 'undefined'. Just delete instead. @@ -202,8 +203,16 @@ function createWritableStdioStream (fd) { return stream; } +/** + * Enable dynamic mode when `process.env.DEBUG_DYN` is set to `1` + */ + +if (process.env.DEBUG_DYN) { + exports.dynamic(process.env.DEBUG_DYN == 1); +} + /** * Enable namespaces listed in `process.env.DEBUG` initially. */ -exports.enable(load()); +exports.parse(load()); diff --git a/package.json b/package.json index 59c2aec4..e73d9e95 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "component": { "scripts": { "debug/index.js": "browser.js", - "debug/debug.js": "debug.js" + "debug/debug.js": "debug.js", + "debug/able.js": "able.js" } } } From 111b74de053377fa7573f2a17fc2386d3f9a38af Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 14:51:59 -0800 Subject: [PATCH 02/10] adding an example server to demonstrate dynamic mode --- example/dynamic/app.js | 43 ++++++++++++++++++++++++++++++++++++++ example/dynamic/index.html | 4 ++++ package.json | 4 +++- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 example/dynamic/app.js create mode 100644 example/dynamic/index.html diff --git a/example/dynamic/app.js b/example/dynamic/app.js new file mode 100644 index 00000000..ab263525 --- /dev/null +++ b/example/dynamic/app.js @@ -0,0 +1,43 @@ +// NOTE - run using: DEBUG=example DEBUG_DYN=1 node app.js + +var debug = require('../..') + , express = require('express') + , bodyParser = require('body-parser') + , app = express() + , name = 'example'; + +var log = debug(name) +log('booting example app'); + +app.use(bodyParser.urlencoded({ extended: false })); + +app.use(function (req, res, next) { + log(req.method + ' ' + req.url); + next(); +}); + +app.get('/', function (req, res) { + log('sending form'); + res.sendFile(__dirname + '/index.html'); +}); + +app.post('/debug', function (req, res) { + if ('enable' in req.body) { + log('enabling'); + debug.enable(name); + } else { + log('disabling'); + debug.disable(name); + } + res.redirect('/'); +}); + +app.post('/disable', function (req, res) { + log('disabling'); + debug.disable(name); + res.redirect('/'); +}); + +app.listen(3000, function () { + log('listening'); +}); diff --git a/example/dynamic/index.html b/example/dynamic/index.html new file mode 100644 index 00000000..88216854 --- /dev/null +++ b/example/dynamic/index.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/package.json b/package.json index e73d9e95..14a3a618 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,10 @@ "ms": "0.6.2" }, "devDependencies": { + "body-parser": "^1.9.2", "browserify": "6.1.0", - "mocha": "*" + "express": "^4.10.2", + "mocha": "^2.0.1" }, "main": "./node.js", "browser": "./browser.js", From d5e68c02b64463ec4f9e3088d49fb36b2284fc3f Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 14:52:18 -0800 Subject: [PATCH 03/10] adding tests for able.js --- Makefile | 6 ++- test/able.js | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/able.js diff --git a/Makefile b/Makefile index b0bde6e6..60c934b2 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ BIN := $(THIS_DIR)/node_modules/.bin NODE ?= $(shell which node) NPM ?= $(NODE) $(shell which npm) BROWSERIFY ?= $(NODE) $(BIN)/browserify +MOCHA ?= $(NODE) $(BIN)/_mocha all: dist/debug.js @@ -30,4 +31,7 @@ node_modules: package.json @NODE_ENV= $(NPM) install @touch node_modules -.PHONY: all install clean +test: + @$(MOCHA) -R dot + +.PHONY: all install clean test diff --git a/test/able.js b/test/able.js new file mode 100644 index 00000000..41769ee9 --- /dev/null +++ b/test/able.js @@ -0,0 +1,116 @@ +var able = require('../able'); +var assert = require('assert'); + +describe('enable/disable feature', function () { + afterEach(able.clear); + + describe('.enabled(ns)', function () { + it('should return booleans', function () { + assert.strictEqual(able.enabled('foo'), false); + able.enable('*'); + assert.strictEqual(able.enabled('foo'), true); + }); + + it('should not allow anything by default', function () { + assert(!able.enabled('express')); + assert(!able.enabled('connect')); + }); + + it('should work with basic strings', function () { + able.enable('express'); + assert(able.enabled('express')); + assert(!able.enabled('connect')); + }); + + it('should work with wildcards', function () { + able.enable('express*'); + assert(able.enabled('express')); + assert(able.enabled('express:router')); + assert(!able.enabled('connect')); + }); + }); + + describe('.stringify()', function () { + it('should return a string', function () { + assert.equal(typeof able.stringify(), 'string'); + }); + + it('should return a comma-separated list of enabled namespaces', function () { + able.enable('a'); + able.enable('b'); + able.enable('c'); + assert.equal(able.stringify(), 'a,b,c'); + }); + + it('should prefix disabled namespaces with a hyphen', function () { + able.enable('*'); + able.disable('express'); + able.disable('connect'); + assert.equal(able.stringify(), '*,-express,-connect'); + }); + }); + + describe('.parse(str)', function () { + it('should respect either white-space or comma separated values', function () { + able.parse('a,b c , d e'); + assert(able.enabled('a')); + assert(able.enabled('b')); + assert(able.enabled('c')); + assert(able.enabled('d')); + assert(able.enabled('e')); + }); + + it('should treat hyphen prefixs as disabled', function () { + able.enable('*'); + able.parse('-b,-c, -d -e'); + assert(able.enabled('a')); + assert(!able.enabled('b')); + assert(!able.enabled('c')); + assert(!able.enabled('d')); + assert(!able.enabled('e')); + assert(able.enabled('f')); + }); + }); + + describe('.enable(ns)', function () { + it('should enable the specified namespace', function () { + able.enable('express'); + assert(able.enabled('express')); + }); + + it('should enable the specified wildcard namespace', function () { + able.enable('express*'); + assert(able.enabled('express:router')); + }); + + it('should work correctly even when previously disabled', function () { + able.enable('*'); + assert(able.enabled('express')); + able.disable('express'); + assert(!able.enabled('express')); + able.enable('express'); + assert(able.enabled('express')); + }); + }); + + describe('.disable(ns)', function () { + it('should disable the specified namespace', function () { + able.enable('*'); + able.disable('express'); + assert(!able.enabled('express')); + }); + + it('should disable the specified wildcard namespace', function () { + able.enable('*'); + able.disable('express*'); + assert(!able.enabled('express:router')); + }); + + it('should work correctly even when previously enabled', function () { + able.enable('express'); + assert(able.enabled('express')); + able.disable('express'); + assert(!able.enabled('express')); + }); + }); +}); From 9ea71b69148c8341128ec38c116b58cbeeb1866b Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 15:06:42 -0800 Subject: [PATCH 04/10] fixing bugs found after trying out many examples --- Makefile | 2 +- able.js | 1 + browser.js | 32 +++++- dist/debug.js | 287 +++++++++++++++++++++++++++++++++++++------------- node.js | 10 +- 5 files changed, 253 insertions(+), 79 deletions(-) diff --git a/Makefile b/Makefile index 60c934b2..bc91c1cc 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ clean: dist: @mkdir -p $@ -dist/debug.js: node_modules browser.js debug.js dist +dist/debug.js: node_modules browser.js debug.js able.js | dist @$(BROWSERIFY) \ --standalone debug \ . > $@ diff --git a/able.js b/able.js index d3921199..3de65bbc 100644 --- a/able.js +++ b/able.js @@ -53,6 +53,7 @@ exports.stringify = function () { */ exports.parse = function (str) { + if (!str) return; str.split(/[\s,]+/).forEach(function (ns) { if (!ns) return; else if ('-' == ns[0]) exports.disable(ns.slice(1)); diff --git a/browser.js b/browser.js index dc261356..3aaf4aa8 100644 --- a/browser.js +++ b/browser.js @@ -12,6 +12,34 @@ exports.save = save; exports.load = load; exports.useColors = useColors; +/** + * Enabled/disabled lists management. + */ + +var able = require('./able'); + +/** + * Wrapped enable that saves after list modified. + * + * @param {String} ns + */ + +exports.enable = function (ns) { + able.enable(ns); + save(); +}; + +/** + * Wrapped disable that saves after list modified. + * + * @param {String} ns + */ + +exports.disable = function (ns) { + able.disable(ns); + save(); +}; + /** * Colors. */ @@ -117,7 +145,7 @@ function log() { function save() { try { - var namespaces = exports.stringify(); + var namespaces = able.stringify(); if (null == namespaces) { localStorage.removeItem('debug'); @@ -146,4 +174,4 @@ function load() { * Enable namespaces listed in `localStorage.debug` initially. */ -exports.parse(load()); +able.parse(load()); diff --git a/dist/debug.js b/dist/debug.js index 6045bd23..e330fb38 100644 --- a/dist/debug.js +++ b/dist/debug.js @@ -1,4 +1,150 @@ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.debug=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1) return false; + if (find(enabled, ns, true) > -1) return true; + return false; +}; + +/** + * Destroys the lists of enabled/disabled. (primarilly for testing purposes) + */ + +exports.clear = function () { + disabled.length = enabled.length = 0; // truncates w/o destroying +}; + +/** + * Outputs the list of enable/disabled in a single string. + * + * @returns {String} + */ + +exports.stringify = function () { + var e = enabled.map(function (item) { + return item.string; + }); + + var d = disabled.map(function (item) { + return '-' + item.string; + }); + + return e.concat(d).join(','); +}; + +/** + * Parses a list and enables/disables accordingly. + * + * This list can either be passed from the user directly, or from .stringify() + * + * @param {String} str + */ + +exports.parse = function (str) { + if (!str) return; + str.split(/[\s,]+/).forEach(function (ns) { + if (!ns) return; + else if ('-' == ns[0]) exports.disable(ns.slice(1)); + else exports.enable(ns); + }); +}; + +/** + * Enables the specified `ns`. + * + * @param {String} ns + */ + +exports.enable = function (ns) { + prune(disabled, ns); + if (find(enabled, ns) > -1) return; + + enabled.push({ + string: ns, + regex: regex(ns) + }); +}; + +/** + * Disables the specified `ns`. + * + * @param {String} ns + */ + +exports.disable = function (ns) { + prune(enabled, ns); + if (find(disabled, ns) > -1) return; + + disabled.push({ + string: ns, + regex: regex(ns) + }); +}; + +/** + * Searches for the given `ns` in the `arr`. + * + * By default, it only matches on the raw string, but if `regex` is set, it will + * match via the `RegExp` instead. + * + * Returns the index of the match, or -1 if not found. + * + * @param {Array} arr + * @param {String} ns + * @param {Boolean} [regex] + * @returns {Number} + */ + +function find(arr, ns, regex) { + var ret = -1; + arr.some(function (item, x) { + if (regex ? item.regex.test(ns) : ns === item.string) { + ret = x; + return true; + } + }); + return ret; +} + +/** + * Wraps around `find(...)`, but also removes the found item. + * + * @param {Array} arr + * @param {String} ns + * @param {Boolean} [regex] + */ + +function prune(arr, ns, regex) { + var x = find(arr, ns, regex); + if (x > -1) arr.splice(x, 1); +} + +/** + * Converts a raw `ns` into a `RegExp`. + * + * @param {String} ns + * @returns {RegExp} + */ + +function regex(ns) { + var pattern = ns.replace(/\*/g, '.*?'); + return new RegExp('^' + pattern + '$'); +} + +},{}],2:[function(require,module,exports){ /** * This is the common logic for both the Node.js and web browser @@ -9,17 +155,13 @@ exports = module.exports = debug; exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; exports.humanize = require('ms'); +exports.dynamic = dynamic; -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; +var able = require('./able'); +exports.enabled = able.enabled; +exports.enable = able.enable; +exports.disable = able.disable; /** * Map of special "%n" handling functions, for the debug "format" argument. @@ -29,6 +171,12 @@ exports.skips = []; exports.formatters = {}; +/** + * Flag for dynamic status. + */ + +var isDynamic = false; + /** * Previously assigned color. */ @@ -118,70 +266,20 @@ function debug(namespace) { logFn.apply(self, args); } enabled.enabled = true; + enabled.namespace = namespace; - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } + function dynamic() { + if (!exports.enabled(namespace)) return disabled(); + return enabled.apply(enabled, arguments); } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} + dynamic.namespace = namespace; -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } + function fn() { + if (isDynamic) return dynamic; + return exports.enabled(namespace) ? enabled : disabled; } - return false; + + return fn(); } /** @@ -197,7 +295,18 @@ function coerce(val) { return val; } -},{"ms":2}],2:[function(require,module,exports){ +/** + * Get/set the dynamic flag + * + * @param {Boolean} [flag] + * @returns {Boolean} + */ + +function dynamic(flag) { + isDynamic = !!flag; +} + +},{"./able":1,"ms":3}],3:[function(require,module,exports){ /** * Helpers. */ @@ -310,7 +419,7 @@ function plural(ms, n, name) { return Math.ceil(ms / n) + ' ' + name + 's'; } -},{}],3:[function(require,module,exports){ +},{}],4:[function(require,module,exports){ /** * This is the web browser implementation of `debug()`. @@ -325,6 +434,34 @@ exports.save = save; exports.load = load; exports.useColors = useColors; +/** + * Enabled/disabled lists management. + */ + +var able = require('./able'); + +/** + * Wrapped enable that saves after list modified. + * + * @param {String} ns + */ + +exports.enable = function (ns) { + able.enable(ns); + save(); +}; + +/** + * Wrapped disable that saves after list modified. + * + * @param {String} ns + */ + +exports.disable = function (ns) { + able.disable(ns); + save(); +}; + /** * Colors. */ @@ -428,8 +565,10 @@ function log() { * @api private */ -function save(namespaces) { +function save() { try { + var namespaces = able.stringify(); + if (null == namespaces) { localStorage.removeItem('debug'); } else { @@ -457,7 +596,7 @@ function load() { * Enable namespaces listed in `localStorage.debug` initially. */ -exports.enable(load()); +able.parse(load()); -},{"./debug":1}]},{},[3])(3) +},{"./able":1,"./debug":2}]},{},[4])(4) }); \ No newline at end of file diff --git a/node.js b/node.js index 0821e7ec..c2b198b7 100644 --- a/node.js +++ b/node.js @@ -19,6 +19,12 @@ exports.save = save; exports.load = load; exports.useColors = useColors; +/** + * Enabled/disabled lists management. + */ + +var able = require('./able'); + /** * Colors. */ @@ -113,7 +119,7 @@ function log() { */ function save() { - var namespaces = exports.stringify(); + var namespaces = able.stringify(); if (null == namespaces) { // If you set a process.env field to null or undefined, it gets cast to the @@ -215,4 +221,4 @@ if (process.env.DEBUG_DYN) { * Enable namespaces listed in `process.env.DEBUG` initially. */ -exports.parse(load()); +able.parse(load()); From 55d9af58a8d0b2c841249710bc5166cd33286e83 Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 15:09:59 -0800 Subject: [PATCH 05/10] adding special case for '*' wildcard to enable/disable --- able.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/able.js b/able.js index 3de65bbc..09db83a7 100644 --- a/able.js +++ b/able.js @@ -68,6 +68,9 @@ exports.parse = function (str) { */ exports.enable = function (ns) { + // special case, empty the current list and allow it to append + if ('*' == ns) exports.clear(); + prune(disabled, ns); if (find(enabled, ns) > -1) return; @@ -84,6 +87,9 @@ exports.enable = function (ns) { */ exports.disable = function (ns) { + // special case, empty the current list (since default is to allow nothing) + if ('*' == ns) return exports.clear(); + prune(enabled, ns); if (find(disabled, ns) > -1) return; From 6aba343a906eac27885d9909830f10971785a3c3 Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Wed, 12 Nov 2014 15:51:49 -0800 Subject: [PATCH 06/10] making changes to ensure we don't break the API --- able.js | 8 +++----- browser.js | 30 +----------------------------- debug.js | 43 +++++++++++++++++++++++++++++++++++++++---- node.js | 2 +- 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/able.js b/able.js index 09db83a7..e8a03238 100644 --- a/able.js +++ b/able.js @@ -53,11 +53,9 @@ exports.stringify = function () { */ exports.parse = function (str) { - if (!str) return; - str.split(/[\s,]+/).forEach(function (ns) { - if (!ns) return; - else if ('-' == ns[0]) exports.disable(ns.slice(1)); - else exports.enable(ns); + if (!str) return []; + return (str || '').trim().split(/[\s,]+/).filter(function (item) { + return !!item; }); }; diff --git a/browser.js b/browser.js index 3aaf4aa8..22acabb3 100644 --- a/browser.js +++ b/browser.js @@ -12,34 +12,6 @@ exports.save = save; exports.load = load; exports.useColors = useColors; -/** - * Enabled/disabled lists management. - */ - -var able = require('./able'); - -/** - * Wrapped enable that saves after list modified. - * - * @param {String} ns - */ - -exports.enable = function (ns) { - able.enable(ns); - save(); -}; - -/** - * Wrapped disable that saves after list modified. - * - * @param {String} ns - */ - -exports.disable = function (ns) { - able.disable(ns); - save(); -}; - /** * Colors. */ @@ -174,4 +146,4 @@ function load() { * Enable namespaces listed in `localStorage.debug` initially. */ -able.parse(load()); +exports.enable(load()); diff --git a/debug.js b/debug.js index f1a17d9c..0ffafdd8 100644 --- a/debug.js +++ b/debug.js @@ -1,4 +1,10 @@ +/** + * Enabled/disabled status management + */ + +var able = require('./able'); + /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. @@ -10,11 +16,10 @@ exports = module.exports = debug; exports.coerce = coerce; exports.humanize = require('ms'); exports.dynamic = dynamic; - -var able = require('./able'); +exports.enable = enable; +exports.disable = disable; exports.enabled = able.enabled; -exports.enable = able.enable; -exports.disable = able.disable; + /** * Map of special "%n" handling functions, for the debug "format" argument. @@ -158,3 +163,33 @@ function coerce(val) { function dynamic(flag) { isDynamic = !!flag; } + +/** + * Enables a string of namespaces (disables those with hyphen prefixes) + * + * @param {String} namespaces + */ + +function enable(namespaces) { + able.parse(namespaces).forEach(function (ns) { + if ('-' == ns[0]) able.disable(ns.slice(1)); + else able.enable(ns); + }); + + exports.save(); +} + +/** + * Disables a string of namespaces (ignores hyphen prefixs if found) + * + * @param {String} namespaces + */ + +function disable(namespaces) { + able.parse(namespaces).forEach(function (ns) { + if ('-' == ns[0]) ns = ns.slice(1); + able.disable(ns); + }); + + exports.save(); +} diff --git a/node.js b/node.js index c2b198b7..8708e0bc 100644 --- a/node.js +++ b/node.js @@ -221,4 +221,4 @@ if (process.env.DEBUG_DYN) { * Enable namespaces listed in `process.env.DEBUG` initially. */ -able.parse(load()); +exports.enable(load()); From 61092e9e4afd8063ab53db146b424734c16c5e2a Mon Sep 17 00:00:00 2001 From: Dominic Barnes Date: Mon, 17 Nov 2014 13:45:02 -0800 Subject: [PATCH 07/10] adding ability to retrieve dynamic flag externally --- debug.js | 1 + dist/debug.js | 90 +++++++++++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/debug.js b/debug.js index 0ffafdd8..28d89740 100644 --- a/debug.js +++ b/debug.js @@ -161,6 +161,7 @@ function coerce(val) { */ function dynamic(flag) { + if (0 == arguments.length) return isDynamic; isDynamic = !!flag; } diff --git a/dist/debug.js b/dist/debug.js index e330fb38..e50a8149 100644 --- a/dist/debug.js +++ b/dist/debug.js @@ -54,11 +54,9 @@ exports.stringify = function () { */ exports.parse = function (str) { - if (!str) return; - str.split(/[\s,]+/).forEach(function (ns) { - if (!ns) return; - else if ('-' == ns[0]) exports.disable(ns.slice(1)); - else exports.enable(ns); + if (!str) return []; + return (str || '').trim().split(/[\s,]+/).filter(function (item) { + return !!item; }); }; @@ -69,6 +67,9 @@ exports.parse = function (str) { */ exports.enable = function (ns) { + // special case, empty the current list and allow it to append + if ('*' == ns) exports.clear(); + prune(disabled, ns); if (find(enabled, ns) > -1) return; @@ -85,6 +86,9 @@ exports.enable = function (ns) { */ exports.disable = function (ns) { + // special case, empty the current list (since default is to allow nothing) + if ('*' == ns) return exports.clear(); + prune(enabled, ns); if (find(disabled, ns) > -1) return; @@ -146,6 +150,12 @@ function regex(ns) { },{}],2:[function(require,module,exports){ +/** + * Enabled/disabled status management + */ + +var able = require('./able'); + /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. @@ -157,11 +167,10 @@ exports = module.exports = debug; exports.coerce = coerce; exports.humanize = require('ms'); exports.dynamic = dynamic; - -var able = require('./able'); +exports.enable = enable; +exports.disable = disable; exports.enabled = able.enabled; -exports.enable = able.enable; -exports.disable = able.disable; + /** * Map of special "%n" handling functions, for the debug "format" argument. @@ -303,9 +312,40 @@ function coerce(val) { */ function dynamic(flag) { + if (1 == arguments.length) return isDynamic; isDynamic = !!flag; } +/** + * Enables a string of namespaces (disables those with hyphen prefixes) + * + * @param {String} namespaces + */ + +function enable(namespaces) { + able.parse(namespaces).forEach(function (ns) { + if ('-' == ns[0]) able.disable(ns.slice(1)); + else able.enable(ns); + }); + + exports.save(); +} + +/** + * Disables a string of namespaces (ignores hyphen prefixs if found) + * + * @param {String} namespaces + */ + +function disable(namespaces) { + able.parse(namespaces).forEach(function (ns) { + if ('-' == ns[0]) ns = ns.slice(1); + able.disable(ns); + }); + + exports.save(); +} + },{"./able":1,"ms":3}],3:[function(require,module,exports){ /** * Helpers. @@ -434,34 +474,6 @@ exports.save = save; exports.load = load; exports.useColors = useColors; -/** - * Enabled/disabled lists management. - */ - -var able = require('./able'); - -/** - * Wrapped enable that saves after list modified. - * - * @param {String} ns - */ - -exports.enable = function (ns) { - able.enable(ns); - save(); -}; - -/** - * Wrapped disable that saves after list modified. - * - * @param {String} ns - */ - -exports.disable = function (ns) { - able.disable(ns); - save(); -}; - /** * Colors. */ @@ -596,7 +608,7 @@ function load() { * Enable namespaces listed in `localStorage.debug` initially. */ -able.parse(load()); +exports.enable(load()); -},{"./able":1,"./debug":2}]},{},[4])(4) +},{"./debug":2}]},{},[4])(4) }); \ No newline at end of file From 4b173a6f2584777022933306252b675ce0253590 Mon Sep 17 00:00:00 2001 From: Martin Cizek Date: Mon, 19 Jan 2015 18:40:05 +0100 Subject: [PATCH 08/10] Return back gray color! --- node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.js b/node.js index 8708e0bc..1d7a9f19 100644 --- a/node.js +++ b/node.js @@ -94,7 +94,7 @@ function formatArgs() { var c = this.color; args[0] = ' \u001b[9' + c + 'm' + name + ' ' - + '\u001b[0m' + + '\u001b[90m' + args[0] + '\u001b[3' + c + 'm' + ' +' + exports.humanize(this.diff) + '\u001b[0m'; } else { From 06de32f3841ff4daa3d609706e8bdd19c67b0a84 Mon Sep 17 00:00:00 2001 From: Martin Cizek Date: Tue, 20 Jan 2015 15:46:04 +0100 Subject: [PATCH 09/10] util.log like timestamp --- node.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/node.js b/node.js index 1d7a9f19..63099eb2 100644 --- a/node.js +++ b/node.js @@ -79,6 +79,21 @@ exports.formatters.o = function(v) { .replace(/\s*\n\s*/g, ' '); }; +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + /** * Adds ANSI color escape codes if enabled. * @@ -98,7 +113,7 @@ function formatArgs() { + args[0] + '\u001b[3' + c + 'm' + ' +' + exports.humanize(this.diff) + '\u001b[0m'; } else { - args[0] = new Date().toUTCString() + args[0] = timestamp() + ' ' + name + ' ' + args[0]; } return args; From ff287fab13b9d185deba827470a8752ad584c322 Mon Sep 17 00:00:00 2001 From: Martin Cizek Date: Wed, 21 Jan 2015 13:37:17 +0100 Subject: [PATCH 10/10] Rename for local npm --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d38a04e8..3f787215 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "debug", + "name": "@sbks/debug", "version": "2.1.1", "repository": { "type": "git", - "url": "git://github.com/visionmedia/debug.git" + "url": "git://github.com/wision/debug.git" }, "description": "small debugging utility", "keywords": [