diff --git a/index.js b/index.js index 313f5dcb..3343a15a 100644 --- a/index.js +++ b/index.js @@ -219,13 +219,19 @@ morgan.format('dev', function developmentFormatLine (tokens, req, res) { : status >= 200 ? 32 // green : 0 // no color + // respect NO_COLOR environment variable (https://no-color.org/) + var noColor = Boolean(process.env.NO_COLOR) + // get colored function - var fn = developmentFormatLine[color] + var key = noColor ? 'plain' : color + var fn = developmentFormatLine[key] if (!fn) { // compile - fn = developmentFormatLine[color] = compile('\x1b[0m:method :url \x1b[' + - color + 'm:status\x1b[0m :response-time ms - :res[content-length]\x1b[0m') + fn = developmentFormatLine[key] = noColor + ? compile(':method :url :status :response-time ms - :res[content-length]') + : compile('\x1b[0m:method :url \x1b[' + + color + 'm:status\x1b[0m :response-time ms - :res[content-length]\x1b[0m') } return fn(tokens, req, res) diff --git a/test/morgan.js b/test/morgan.js index 85d3b9a7..32255a4b 100644 --- a/test/morgan.js +++ b/test/morgan.js @@ -1333,6 +1333,20 @@ describe('morgan()', function () { }) describe('dev', function () { + var noColor = process.env.NO_COLOR + + beforeEach(function () { + delete process.env.NO_COLOR + }) + + afterEach(function () { + if (noColor === undefined) { + delete process.env.NO_COLOR + } else { + process.env.NO_COLOR = noColor + } + }) + it('should not color 1xx', function (done) { var cb = after(2, function (err, res, line) { if (err) return done(err) @@ -1474,6 +1488,71 @@ describe('morgan()', function () { .expect(200, cb) }) }) + + describe('with NO_COLOR environment variable', function () { + it('should omit ANSI color codes when NO_COLOR is set', function (done) { + process.env.NO_COLOR = '1' + + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line.indexOf('\x1b['), -1, 'expected no ANSI codes') + done() + }) + + var stream = createLineStream(function (line) { + cb(null, null, line) + }) + + var server = createServer('dev', { stream: stream }) + + request(server) + .get('/') + .expect(200, cb) + }) + + it('should omit ANSI color codes for 5xx when NO_COLOR is set', function (done) { + process.env.NO_COLOR = '1' + + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line.indexOf('\x1b['), -1, 'expected no ANSI codes') + done() + }) + + var stream = createLineStream(function (line) { + cb(null, null, line) + }) + + var server = createServer('dev', { stream: stream }, function (req, res, next) { + res.statusCode = 500 + next() + }) + + request(server) + .get('/') + .expect(500, cb) + }) + + it('should preserve color when NO_COLOR is empty', function (done) { + process.env.NO_COLOR = '' + + var cb = after(2, function (err, res, line) { + if (err) return done(err) + assert.strictEqual(line.substr(0, 37), '_color_0_GET / _color_32_200_color_0_') + done() + }) + + var stream = createColorLineStream(function onLine (line) { + cb(null, null, line) + }) + + var server = createServer('dev', { stream: stream }) + + request(server) + .get('/') + .expect(200, cb) + }) + }) }) describe('short', function () {