Ava: Correctly proxy TTY for stderr

Created on 24 Aug 2017  路  7Comments  路  Source: avajs/ava

See https://github.com/avajs/ava/issues/1494#issuecomment-325351227


Description

When using visionmedia's debug with AVA the colourized output is lost. I desire to turn on debug when running my tests to observe the code paths taken. I believe it is not working because the process.stderr.isTTY property is undefined when running under AVA. I'd like to make a feature request to support colorized output of the debug module by setting process.stderr.isTTY to true when the initiating ava process has process.stderr.isTTY set to true;

Test Source

// place this code in colorize-test.js

process.env.DEBUG='worker'
const debug = require('debug')('worker')

debug('doing lots of uninteresting work');

console.log(`stderr is tty? ${process.stderr.isTTY}`);

// if we are running in AVA create a test to avoid 'No tests found' exception
if (process.env.AVA_PATH) {
    const test = require('ava');
    test('exit', async (t) => t.is(true, true));
}

Command-Line Arguments

$ node colorize-test.js # has colored output as stderr is tty
  worker doing lots of uninteresting work +0ms
stderr is tty? true

$ ava colorize-test.js # does not have colored output as stderr is not a tty
2017-08-24T10:57:04.500Z worker doing lots of uninteresting work
stderr is tty? undefined

  1 passed

Relevant Links

The pull request that requires process.stderr.isTTY to be true in order to print colored output.

Environment

Node.js v8.4.0
Ubuntu 16.04.2 4.10.0-32-generic
AVA 0.22.0
bug help wanted test-environment

Most helpful comment

@unional from what I can tell, AVA distinguishes between TTY and non-TTY mode mainly to determine whether it should colorize its output. Same as debug.

It is common for most software that If TTY mode is detected, then most likely a human is looking at the output in a terminal, so output should be colorized. On the other hand, if TTY mode is false, then most likely the output is going to a file and should _not_ be colorized, in order to be more friendly to scripts (so they don't have to deal with ANSI styles when parsing the output).

I'm not sure if AVA does anything else based on TTY mode, but it looks like the problem is simply that the TTY information is not being properly forwarded to test workers. I'm pretty sure test workers are not directly connected to the terminal, meaning that TTY is never actually enabled for them, but the top level ava process collects their output and forwards it to the terminal, so it is kind of a fake TTY. Or, you could say, a TTY tunnel / proxy.

Looks like the TTY proxy is working correctly for process.stdout, but not for process.stderr.

I believe Jest uses worker processes as well, so it would presumably have to do the same thing unless it allows its workers to be directly connected to the terminal.

All 7 comments

This makes sense to me, but I don't fully understand how this TTY stuff works. @sindresorhus?

We're currently detecting TTY support based on process.stdout: https://github.com/avajs/ava/blob/dd9e8b2effe541f9f232ee622452343dac5895dd/lib/fork.js#L33:L36. This is then used to re-enable it in the test workers: https://github.com/avajs/ava/blob/dd9e8b2effe541f9f232ee622452343dac5895dd/lib/process-adapter.js#L34:L36

Give that we do it for process.stdout it seems like a bug that we don't for process.stderr.

Can process.stdout.isTTY be false while process.stderr.isTTY is true? Can they have different column and row values?

Give that we do it for process.stdout it seems like a bug that we don't for process.stderr.

Yeah, probably just an oversight.

Can process.stdout.isTTY be false while process.stderr.isTTY is true?

Yes, users could redirect individual streams. For example, to only redirect stderr to a file:

ava 2> file

Can they have different column and row values?

No, I don't think so.

Can they have different column and row values?

No, I don't think so.

Good to know. I suppose we could change the tty option so we always pass it, with separate flags for stdout and stderr.

I'm new to TTY and working on #1533 , what is the use case that TTY is false?

@unional I don't think I understand your question. The use-case doesn't matter. It's expected behavior of a process to handle non-TTY mode.

Just want to understand it a bit more, because I'm not aware that Jest distinguishes between TTY and non-TTY mode.

@unional from what I can tell, AVA distinguishes between TTY and non-TTY mode mainly to determine whether it should colorize its output. Same as debug.

It is common for most software that If TTY mode is detected, then most likely a human is looking at the output in a terminal, so output should be colorized. On the other hand, if TTY mode is false, then most likely the output is going to a file and should _not_ be colorized, in order to be more friendly to scripts (so they don't have to deal with ANSI styles when parsing the output).

I'm not sure if AVA does anything else based on TTY mode, but it looks like the problem is simply that the TTY information is not being properly forwarded to test workers. I'm pretty sure test workers are not directly connected to the terminal, meaning that TTY is never actually enabled for them, but the top level ava process collects their output and forwards it to the terminal, so it is kind of a fake TTY. Or, you could say, a TTY tunnel / proxy.

Looks like the TTY proxy is working correctly for process.stdout, but not for process.stderr.

I believe Jest uses worker processes as well, so it would presumably have to do the same thing unless it allows its workers to be directly connected to the terminal.

Was this page helpful?
0 / 5 - 0 ratings