Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for --no-color flag in verbose and mini reporters #1198

Merged
merged 4 commits into from
Feb 8, 2017

Conversation

ThomasBem
Copy link
Contributor

Started working on fixing #843. So far I have managed to disable color output for both mini and verbose reporters by setting the --no-color flag.

Now I need to disable color output also if you try console.log with colors inside a test. What I am a little stuck on at the moment is this spawning of child processes. Thats a part of the code base I have yet to understand.

Any pointers on where to start digging? :)

@novemberborn
Copy link
Member

Now I need to disable color output also if you try console.log with colors inside a test

That seems unnecessary. If you want to log colors then go ahead. It's just that one should be able to disable AVA's color output.

lib/cli.js Outdated
@@ -124,9 +125,14 @@ exports.run = () => {
if (cli.flags.tap && !cli.flags.watch) {
reporter = tapReporter();
} else if (cli.flags.verbose || isCi) {
reporter = verboseReporter();
reporter = verboseReporter({
disableColors: cli.flags.color !== undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without looking into meow, I'm surprised this isn't a boolean. Does it become false if --no-color is set? Comparing against false seems better than comparing against undefined.

Copy link
Member

@sindresorhus sindresorhus Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@novemberborn By default, if the user doesn't specify either --color or --no-color, it's not set.

If we add the following, it will be true if not specified, but then we wouldn't know when it's not specified and should be auto-detected. So I wouldn't do this:

const cli = meow(``, {
	boolean: ['color'],
	default: {
		color: true
	}
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go with color instead of disableColors though. Double-negatives are not very good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will double check this. Was stuck on this point for a while trying out different things and reading up on meow and minimist. Got it working on undefined, but maybe I missed something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sindresorhus I tried to do what you suggested with default in in meow and that works for my code,
{ color: true }
but I dont understand whats going on with whats currently in default and how to make it work together with the change you recommended. Tried a few different things, but I keep getting a failing test in cli.js.

https://github.com/avajs/ava/blob/master/lib/cli.js#L75

@@ -28,6 +28,13 @@ function MiniReporter(options) {

this.options = Object.assign({}, options);

if (this.options.disableColors) {
chalk.enabled = false;
Object.keys(colors).forEach(function (key) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd personally prefer a for…of loop here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, go with for-of whenever possible.

@ThomasBem
Copy link
Contributor Author

@sindresorhus commented this in one of the PR`s that was working on this issue previously.

It also needs to pass the --no-color flag down to the forked process. If I add console.log(require('chalk').red('colorzzzz')); in a test file, it will still log colors even with $ ava --no-colors. I would expect that to prevent all colors.

#1104

@novemberborn
Copy link
Member

@ThomasBem I guess I disagree with @sindresorhus then 😄

@sindresorhus why do you think ava --no-color should disable colors not coming from AVA itself?

@sindresorhus
Copy link
Member

sindresorhus commented Jan 23, 2017

why do you think ava --no-color should disable colors not coming from AVA itself?

Because that's how it would work normally. That's how I designed Chalk. AVA is special since we spawn child processes, but the expected behavior should be preserved, by passing down the flag. --no-color should apply to everything.

@novemberborn
Copy link
Member

Ah, hadn't realized chalk takes a --no-color argument.

We've previously argued against forwarding command line arguments to the workers though.

@sindresorhus
Copy link
Member

We've previously argued against forwarding command line arguments to the workers though.

Yes, and we're not gonna start doing it with arbitrary flags, but I would say it's worth making an exception for this one as it matches expected outcome.

@ThomasBem
Copy link
Contributor Author

I have updated the PR with the suggested changes regarding the CLI flag and the for...of loops.

I need some help with keeping the existing "default: conf" in cli.js while also adding the new stuff @sindresorhus mentioned. I could not get it to work together with the new { color: true} so I just removed it for now and its causing a test to fail.

I don`t understand what this conf thing is and what its doing in default in the first place. It makes no sense to me :P

I can understand adding { color: true } saying that color should be true if nothing else is set. But just "conf" makes no sense to me.

I also need some support in where to start with passing the flag down to the child processes. That`s one of the things I have yet to understand with how Ava works :)

@novemberborn
Copy link
Member

I don`t understand what this conf thing is and what its doing in default in the first place. It makes no sense to me :P

This may be relevant: #1046 (comment)

I could not get it to work together with the new { color: true} so I just removed it for now and its causing a test to fail.

The test verifies that config in package.json overrides the default behavior. Currently the config is passed through the CLI parser (meow) using default, except that you removed that behavior 😉

If you do Object.assign({ color: true }, conf) instead you should get the behavior you want, and a passing test. I think this is another argument for my suggestion in #1046 (comment).

I also need some support in where to start with passing the flag down to the child processes. That`s one of the things I have yet to understand with how Ava works :)

See here:

const ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), [JSON.stringify(opts)], {

opts should already contain the colors value, you'll just have to translate it to the correct flag.

@ThomasBem
Copy link
Contributor Author

Thanks for the help @novemberborn :)

I did what you said for the default, and that worked fine. Think I sort of understand whats going on with that now.

I also made something that works for passing the color flag down to the forked process.

I am unsure of how / if I can test that small piece of code though. Any suggestions?

@@ -38,6 +38,7 @@ exports.run = () => {
--verbose, -v Enable verbose output
--no-cache Disable the transpiler cache
--no-power-assert Disable Power Assert
--no-color Disable color output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag should be added to readme.md (like -no-power-assert for example) in CLI paragraph

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Did not even think about that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be good now :)

readme.md Outdated
@@ -159,6 +159,7 @@ $ ava --help
--verbose, -v Enable verbose output
--no-cache Disable the transpiler cache
--no-power-assert Disable Power Assert
--no-color Disable color output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, fix indentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, ill take a look. It does not look that way for me in IDE or when looking at the readme in my branch. I see even Travis failed on some tests in node7 suddenly, when all i did was updated readme...

@ThomasBem
Copy link
Contributor Author

Looks better now? I used IntelliJ instead of VSCode to edit the markdown file.

@ThomasBem
Copy link
Contributor Author

Something going on with Travis? First time i edited the readme.md file, travis failed on node 7.

Now I fixed a small indentation mistake and travis fails on node 4? Even different tests failing.

@ThomasBem ThomasBem force-pushed the no-color-flag branch 2 times, most recently from a30f2dd to 12c8d9e Compare January 27, 2017 05:47
@ThomasBem
Copy link
Contributor Author

Seems like things are working much better today. So probably some hiccup with Travis yesterday.

@@ -671,3 +671,26 @@ test('results when hasExclusive is enabled, but there are multiple remaining tes
t.end();
});

test('Result when no-color flag is set', function (t) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result => result

@@ -571,6 +571,31 @@ test('results when hasExclusive is enabled, but there are multiple remaining tes
t.end();
});

test('Result when no-color flag is set', function (t) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result => result

colors[key].enabled = true;
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we setting this both here and in the constructor? Wouldn't it make more sense to only set it in the constructor?

Something like this:

chalk.enabled = this.options.color;
for (const key of Object.keys(colors)) {
	colors[key].enabled = this.options.color;
}

@@ -28,6 +28,13 @@ function MiniReporter(options) {

this.options = Object.assign({}, options);

if (this.options.color === false) {
chalk.enabled = false;
for (let key of Object.keys(colors)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let => const

colors[key].enabled = true;
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Qix- This is needed because we assign shortcuts to the colors in lib/colors.js (context #1104 (comment)) Any way we could make the above loop not nessecary? Maybe if we made .enabled property on the prototype?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean adding a MiniReporter.prototype.enabled = function () {} that would enable all the colors?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThomasBem Ignore this ;) Unrelated to this PR, but rather to chalk.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, oki :) I will commit with updates based on your review, but without doing anything regarding the loop.

I did a quick try where I changed how we create mini and verbose reporters in their test setup. Making sure to include {colors: true} as an options. That way we can use your suggestion:

chalk.enabled = this.options.color;
for (const key of Object.keys(colors)) {
	colors[key].enabled = this.options.color;
}

It works for the mini and verbose tests themselves, but it caused this test to fail because chalk and colors did not seem to work as intended, https://github.com/avajs/ava/blob/master/test/cli.js#L73

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it caused this test to fail because chalk and colors did not seem to work as intended, https://github.com/avajs/ava/blob/master/test/cli.js#L73

I think that's as expected as we used to force Chalk in child processes and we no longer do. I guess we can just remove the colors.error() call from that test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little lost, could you explain a bit more?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nvm, Sindre explained it to me. See chalk/chalk#142.

@sindresorhus
Copy link
Member

@ThomasBem When you push new changes, can you push them as additional commits instead of squashing? Makes it easier to see what changed. We squash on merge anyways.

@ThomasBem
Copy link
Contributor Author

ThomasBem commented Jan 29, 2017

Sure, I can do that :)

Changes this time was all your small suggestions, let => const, Result => result.

lib/fork.js Outdated
@@ -36,7 +36,9 @@ module.exports = (file, opts, execArgv) => {
} : false
}, opts);

const ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), [JSON.stringify(opts)], {
var args = [JSON.stringify(opts), opts.color ? '--color' : '--no-color'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use const.

(@sindresorhus is this something xo should enforce?)

Copy link
Member

@sindresorhus sindresorhus Jan 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add the esnext: true option, which enforces const, when #1154 lands (hopefully in the next few days), as it's the last piece of non-ES2015ified code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, C# habbit :p

message += ' Unexpected Babel configuration for AVA. ';
message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.';
message += 'See https://github.com/avajs/ava#es2015-support for allowed values.';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? (I must admit I didn't read all of the back and forth earlier though… forgive me if I overlooked the answer)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sindresorhus you suggested to remove the color comparison from the test, but this removes it from the actual AVA code.

Why do the changes in this PR require colors to be removed elsewhere? Should we then also remove colors from https://github.com/avajs/ava/blob/master/lib/cli.js#L100:L108?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it from the actual output, since we removed it from test. But if the problem only exits when running tests, not real Ava. Then we can put it back in the implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some testing and it seems like this is only a problem in test? Is this because execCli spawns a new process and the chalk.enabled and colors.enabled stuff is not passed on?

As far as I can tell none of the changes I did changed anything related to that behaviour? So why this did work before?

Since it seems to actually work when running Ava properly, we can always just remove the color from expected in the test? At least we catch that the error is thrown with the correct text. Even though colors and underline will be missing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't notice this removes it from the actual code. In #1198 (comment), I was talking about removing the chalk call from the test, not elsewhere.

Is this because execCli spawns a new process and the chalk.enabled and colors.enabled stuff is not passed on?

Not exactly. Colors used to be forced "on", now it's auto-detected and colors are automatically off when spawned.

return new VerboseReporter(options);
}

this.options = Object.assign({}, options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assigning this.options seems unnecessary since the constructor didn't receive options before. Nothing else is using this.options.

@novemberborn novemberborn changed the title [WIP] Added support for --no-color flag in verbose and mini reporters Added support for --no-color flag in verbose and mini reporters Jan 29, 2017
@Qix-
Copy link
Contributor

Qix- commented Jan 30, 2017

The github mobile site doesn't allow inline comments, so apologies for this being out of line.

For the child workers, why don't we just utilize support-color's new FORCE_COLOR environment variable instead of pushing down arbitrary flags?

@sindresorhus
Copy link
Member

@Qix- FORCE_COLOR is for users that can't pass flags. We control the child process, so we can pass flags. I don't really see the problem with that or any benefit in using FORCE_COLOR?

@Qix-
Copy link
Contributor

Qix- commented Jan 31, 2017

The parent AVA process is passed --colors, etc. Then it sets the environment variable FORCE_COLOR for child processes to force them to match whatever color level the main (parent) process is running at.

No need to do any messy flag juggling or whatever. No need to determine which flags to pass down. No need to update flags in AVA in the future if supports-color changes how it handles flags. This is the perfect use case.

Also, this is exactly what the environment was made for. 🕺

@novemberborn
Copy link
Member

@Qix- I think your explanation makes sense, but I'll defer to @sindresorhus who I'm sure has got a better understanding of this area than me.

@sindresorhus
Copy link
Member

sindresorhus commented Feb 1, 2017

The parent AVA process is passed --colors, etc. Then it sets the environment variable FORCE_COLOR for child processes to force them to match whatever color level the main (parent) process is running at.

I still don't see how that's any easier. It's the same amount of work to pass down --color/--no-color based on those flags being set for AVA, as it's passing FORCE_COLOR=0/FORCE_COLOR=1 based on AVA receiving --color/--no-color. The benefit of passing the flags is that we still respect FORCE_COLOR being passed to AVA by the user.

No need to update flags in AVA in the future if supports-color changes how it handles flags. This is the perfect use case.

I don't do what-ifs. We work with how it works now. In the future, the environment variable might be renamed, who knows.

@novemberborn
Copy link
Member

The benefit of passing the flags is that we still respect FORCE_COLOR being passed to AVA by the user.

👍

@ThomasBem
Copy link
Contributor Author

So I have reverted back to babel-config.js change I made, and instead passed down an additional --color flag in execCli where needed.

Tok me quite a while to get my work in after @vadimdemedes big Magic Assert PR. But I think I managed to get everything up-to-date. But please take a look :)

@sindresorhus sindresorhus merged commit 5c4c270 into avajs:master Feb 8, 2017
@sindresorhus
Copy link
Member

Great work @ThomasBem! Another high-quality pull request :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants