/** * Module dependencies. */ var tty = require('tty'); var util = require('util'); /** * This is the Node.js implementation of `debug()`. * * Expose `debug()` as the module. */ exports = module.exports = require('./debug'); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; /** * Colors. */ exports.colors = [6, 2, 3, 4, 5, 1]; /** * The file descriptor to write the `debug()` calls to. * Set the `DEBUG_FD` env variable to override with another value. i.e.: * * $ DEBUG_FD=3 node script.js 3>debug.log */ var fd = parseInt(process.env.DEBUG_FD, 10) || 2; var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); /** * Is stdout a TTY? Colored output is enabled when `true`. */ function useColors() { var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase(); if (0 === debugColors.length) { return tty.isatty(fd); } else { return '0' !== debugColors && 'no' !== debugColors && 'false' !== debugColors && 'disabled' !== debugColors; } } /** * Map %o to `util.inspect()`, since Node doesn't do that out of the box. */ var inspect = (4 === util.inspect.length ? // node <= 0.8.x function (v, colors) { return util.inspect(v, void 0, void 0, colors); } : // node > 0.8.x function (v, colors) { return util.inspect(v, { colors: colors }); } ); exports.formatters.o = function(v) { return inspect(v, this.useColors) .replace(/\s*\n\s*/g, ' '); }; /** * Adds ANSI color escape codes if enabled. * * @api public */ function formatArgs() { var args = arguments; var useColors = this.useColors; var name = this.namespace; if (useColors) { var c = this.color; args[0] = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m' + args[0] + '\u001b[3' + c + 'm' + ' +' + exports.humanize(this.diff) + '\u001b[0m'; } else { args[0] = new Date().toUTCString() + ' ' + name + ' ' + args[0]; } return args; } /** * Invokes `console.error()` with the specified arguments. */ function log() { return stream.write(util.format.apply(this, arguments) + '\n'); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { 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. delete process.env.DEBUG; } else { process.env.DEBUG = namespaces; } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { return process.env.DEBUG; } /** * Copied from `node/src/node.js`. * * XXX: It's lame that node doesn't expose this API out-of-the-box. It also * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. */ function createWritableStdioStream (fd) { var stream; var tty_wrap = process.binding('tty_wrap'); // Note stream._type is used for test-module-load-list.js switch (tty_wrap.guessHandleType(fd)) { case 'TTY': stream = new tty.WriteStream(fd); stream._type = 'tty'; // Hack to have stream not keep the event loop alive. // See https://github.com/joyent/node/issues/1726 if (stream._handle && stream._handle.unref) { stream._handle.unref(); } break; case 'FILE': var fs = require('fs'); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': var net = require('net'); stream = new net.Socket({ fd: fd, readable: false, writable: true }); // FIXME Should probably have an option in net.Socket to create a // stream from an existing fd which is writable only. But for now // we'll just add this hack and set the `readable` member to false. // Test: ./node test/fixtures/echo.js < /etc/passwd stream.readable = false; stream.read = null; stream._type = 'pipe'; // FIXME Hack to have stream not keep the event loop alive. // See https://github.com/joyent/node/issues/1726 if (stream._handle && stream._handle.unref) { stream._handle.unref(); } break; default: // Probably an error on in uv_guess_handle() throw new Error('Implement me. Unknown stream file type!'); } // For supporting legacy API we put the FD here. stream.fd = fd; stream._isStdio = true; return stream; } /** * Enable namespaces listed in `process.env.DEBUG` initially. */ exports.enable(load());