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

Pipe-redirecting Grunt's output is broken #510

Closed
jakub-g opened this issue Nov 6, 2012 · 18 comments
Closed

Pipe-redirecting Grunt's output is broken #510

jakub-g opened this issue Nov 6, 2012 · 18 comments

Comments

@jakub-g
Copy link

jakub-g commented Nov 6, 2012

I'm not 100% sure the source of the problem is Grunt, but since Unix tools are rather thoroughly tested, I thought I'll start from reporting here. Can someone try to reproduce on their machines?

Version: 0.3.17
I do everything under WinXP/MINGW32 (Git 1.7.11) sh console.

Let's create a simple grunt file grunttest.js:

module.exports = function(grunt) {

  grunt.registerTask('t1', function(){
    console.log('t1 hello');
  });
  grunt.registerTask('t2', function(){
    console.log('t2 hello');
  });
  grunt.registerTask('default', 't1 t2'); 

};

Let's run it:

$ grunt --config ./grunttest.js
Running "t1" task
t1 hello

Running "t2" task
t2 hello

Prints fine, all-white (standard text color).

Let's redirect to a file:

$ grunt --config ./grunttest.js > out.txt

Open out.txt in Notepad++:

[4mRunning "t1" task[24m
t1 hello

[4mRunning "t2" task[24m
t2 hello

[32mDone, without errors.[39m

These are escape codes used to color the output. (Notepad++ additionally prints the ESC chars before the left-braces: char 27, or 0x1B, I deleted them since it was breaking the Markdown processor). cat out.txt actually produces a nice ASCII out of it, just like the first command, but colored.

The interesting starts now:

$ grunt --config ./grunttest.js | cat
Running "t1" task

When I want to pipe to cat or less, I only see the first line (in cyan). I don't see the other lines. The above yields the same BTW:

$ grunt --config ./grunttest.js 2>&1 | cat

I'm pretty sure it's not a feature ;) Can someone confirm my findings? Any guesses what the problem might be?

I've tried a simple Node.js code (a few console.logs) and it works fine on the contrary. So it seems that Grunt + colored output are the cause.

@shama
Copy link
Member

shama commented Nov 9, 2012

You can use the --no-color option to remove coloring.

@jakub-g
Copy link
Author

jakub-g commented Nov 9, 2012

@shama Thanks for the comment. However the problem remains -- no colors are output, but still I get only the first line while redirecting to cat / less / whatever:

$ grunt --no-color --config ./grunttest.js | cat
Running "t1" task

whereas when I redirect output to a file, it's fine:

$ grunt --no-color --config ./grunttest.js > out.txt

Open out.txt in Notepad++:

Running "t1" task
t1 hello

Running "t2" task
t2 hello

Done, without errors.

@shama
Copy link
Member

shama commented Nov 9, 2012

@jakub-g Strange. I'll try on my Windows machine when I get it up and running. Not seeing that issue with OSX and Ubuntu.

@jakub-g
Copy link
Author

jakub-g commented Nov 9, 2012

Some more findings after checking on my machines at home:
(using Grunt 0.3.17 & Node 0.8.14):

WinXP Professional SP3 32bit + Git 1.7.11 shell -- like above
WinXP Professional SP3 32bit + Git 1.8.0 shell -- like above
Win7 Professional SP1 32bit + Git 1.8.0 -- even worse; displaying or redirecting to file works fine, but when cat-ing I don't even see the first line. With or without --no-color

Perhaps it's a MINGW32 thing, but I've been using Git from command line for a couple of months without any issues for cating, diffing etc.

@dcherman
Copy link

It's a bug in node in Windows where stdout/stderr isn't flushed properly prior to exiting the process. See nodejs/node-v0.x-archive#3584 .

FWIW I work around this in the meantime by doing grunt.cmd --no-color > grunt.tmp & type grunt.tmp & del grunt.tmp
which works because the behavior of process.stdout becomes blocking when piped to a file - http://nodejs.org/api/process.html#process_process_stdout

@cowboy
Copy link
Member

cowboy commented Dec 31, 2012

Can you try grunt 0.4.0rc4? I'm pretty sure the problem is fixed there.

@benjamine
Copy link

I got it fixed by using the workaround @dcherman suggested (pipe to a file), is far from ideal, but it works

@eddiefletchernz
Copy link

the problem is still in grunt 0.4.0rc7. This is the output for a failing jshint task:

Running:
node v0.8.18
Windows 7 Professional x64

>grunt jshint --no-color | more
Running "jshint:src" (jshint) task

>

If i don't pipe to more, then I get the full output with all my jshint errors

@vladikoff
Copy link
Member

While working on grunt-devtools version for Windows (works fine in OS X), I also discovered this issue when trying to pipe output to devtools from grunt tasks. I didn't have time to debug this yet, but will let you guys know if I find anything.

@benjamine
Copy link

On windows I found that using powershell (instead of .bat) can solve this problem too. (and --no-color too)

@benjamine
Copy link

as @dcherman points out this is clearly not related to grunt, I have seen the same behavior when using npm and other node.js apps.

@jakub-g
Copy link
Author

jakub-g commented Mar 21, 2013

#708 contains detailed info on the problem and a workaround code for this.

@adamstallard
Copy link

I do remember seeing this problem in npm a while back, but it seems to have been fixed. Perhaps we should see how they fixed it and follow suit.

I know that apps that use process.exit to abort execution often suffer from this.

@andr2
Copy link

andr2 commented May 14, 2013

It seems that Grunt.js development is dead. Very annoying bug. Thanks for fix to Adam. But what about merge?

@adamstallard
Copy link

I think @andr2 is referring to #744 . I keep my fork up-to-date (i just merged a couple of trivial things), so you are welcome to use it.

@jeanlauliac
Copy link

Why grunt is not using process.stdout.isTYY and process.stderr.isTYY to disable colors automatically when out of a terminal? That's pretty much considered a standard behaviour for command line tools.

By running:

$ grunt sometask
$ grunt sometask | cat

The first should output colors, the second none, out-of-the-box. Then, it could provide a --color command to force it back.

@brandf
Copy link

brandf commented Aug 28, 2013

I'm using this workaround to remove color output while piping. Doesn't work for other ansi codes like BEEP though. Unfortunately node streams don't have a flush method, or else the same monkey patch could be used to shim synchronous writes:

if (!process.stdout.isTTY) {
    var stdOutWrite = process.stdout.write;
    process.stdout.write = function (chunk, encoding, callback) {
        stdOutWrite.call(process.stdout, grunt.log.uncolor(chunk.toString()), 'utf8', callback);
    };
}

edit: since I can't seem to make this approach work for the lack of flushing a simpler approach can be done just to remove color/beeps:

// work around a grunt bug where color output is written to non-tty output
if (!process.stdout.isTTY) {
    grunt.option("color", false);
}

@vladikoff
Copy link
Member

This issue should be fixed via #921
Let's continue discussion there.

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

No branches or pull requests