UNPKG

fh-fhc

Version:

A Command Line Interface for FeedHenry

166 lines (153 loc) 3.6 kB
/* globals i18n */ // centralized stdout writer. // TODO Refactor really old/stale code that can be replaced by color and console modules. exports.doColor = doColor; exports.write = write; var fhc = require("../fhc.js"); var streams = {}; var net = require("net"); var util = require("util"); var tty = require("tty"); function doColor(stream) { var conf = fhc.config.get("color"); if (!conf) { return false; } if (conf === "always") { return true; } return isatty(stream); } function isatty(stream) { if (!tty.isatty) { return true; } if (!stream) { return false; } if (stream.isTTY) { return true; } if (stream && (typeof stream.fd === "number")) { stream.isTTY = tty.isatty(stream.fd); } return stream.isTTY; } function write(args, stream, lf, cb) { if (typeof cb !== "function" && typeof lf === "function") { cb = lf; lf = null; } if (typeof cb !== "function" && typeof stream === "function") { cb = stream; stream = fhc.config.get("outfd"); } stream = getStream(stream); if (!lf) { lf = isatty(stream); } if (!stream) { if (cb) { cb(); } return false; } var isArray = Array.isArray(args); if (!isArray) { args = [args]; } var msg = "" , colored = doColor(stream) , sep = isArray ? ',\n' : ' '; msg = args.map(function(arg) { if (typeof arg !== "string") { if (fhc.config.get('usesysinspect')) { return util.inspect(arg, false, 5, colored) + "\n"; } return JSON.stringify(arg, null, fhc.config.get('jsondepth')); } if (!colored) { arg = arg.replace(/\033\[[0-9;]*m/g, ''); } return arg; }).join(sep); if (isArray) { msg = "[" + msg + "]"; } // listen to the "output" event to cancel/modify/redirect fhc.output = {stream:stream, message:msg}; fhc.emit("output", fhc.output); if (!fhc.output) { return cb && cb(), false; // cancelled } stream = fhc.output.stream; msg = fhc.output.message; // use the \r\n in case we're in raw mode. msg = msg.split(/\r?\n/).concat("").join(lf ? "\r\n" : "\n"); // output to stderr should be synchronous if (stream === process.stderr ||stream.fd === 2) { process.stderr.write(msg); if (cb) { cb(); } return true; } var flushed = stream.write(msg); if (flushed && cb) { process.nextTick(cb); } else { stream.on("drain", cb); } return flushed; } var hadError = false; function getStream(fd) { if (hadError) { return; } var stream; if (!fd && fd !== 0) { return process.stderr; } if (typeof fd === "string") { fd = +fd; } if (fd && typeof fd === "object") { stream = fd; fd = fd.fd; } else if (streams[fd]) { stream = streams[fd]; } else { switch (fd) { case 1: stream = process.stdout; stream.fd = fd; stream.writable = true; break; case 2: stream = process.stderr; stream.fd = fd; stream.writable = true; break; default: try { stream = new net.Stream(fd); if (!stream || !stream.writable) { throw new Error(i18n._("Stream not writable")); } } catch (ex) { // if this fails, then regular logging is most likely broken. var er = new Error("cannot output to fd "+fd + ": "+ (ex.stack || ex.message).substr(7) + "\n"); console.error(er.stack); hadError = true; process.exit(1); } } } if (!stream || !stream.writable) { return; } streams[fd] = stream; return stream; }