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

Preserve colors in output? #65

Closed
mhkeller opened this issue Oct 9, 2015 · 19 comments
Closed

Preserve colors in output? #65

mhkeller opened this issue Oct 9, 2015 · 19 comments

Comments

@mhkeller
Copy link

mhkeller commented Oct 9, 2015

I'm executing a node script with node index.js but gulp-shell doesn't preserve colors in stdout. It would be helpful to keep them in if possible.

@sun-zheng-an
Copy link
Owner

gulp-shell will never strip the colors for you.

For most commands, you can find a way to force it to colorize the output (e.g. mocha --colors for mocha).

@mhkeller
Copy link
Author

Hmm that's different from what I'm seeing. I have a simple script that uses chalk for output and it runs fine when I do node index.js. When I run the following, the output has no colors

var paths = {
  js: {
    index: 'index.js'
  }
}

gulp.task('run-index', function () {
  return gulp.src(paths.js.index, {read: false})
    .pipe(shell([
      'node <%= file.path %>'
    ]))
})

@sun-zheng-an
Copy link
Owner

I don't know why chalk choose to strip the colors, but you can force color in more than one way.

@Sayvai
Copy link

Sayvai commented Nov 1, 2015

Hi @sun-zheng-an, I agree with the request from @mhkeller for the preservation of colors in the output.

For example, my Karma config is configured with colors: true, and when i run, say, a karma command directly in my shell karma start karma.config, and there's errors in my unit test(s), i see clear red errors texts in the output. That's great!

But when i run this through gulp-shell module, it does not output the same expected colors, especially when configured through Karma config.

This should rule out the fact that Karma itself is stripping the colours because a direct shell command shows the colors fine, and is correctly configured in the Karma configuration file.

I believe child_process is stripping the colors. I see you are using the child process instance child_process.exec, which for whatever reason does not include the option stdio, thereby allowing such a value inherit to be passed (for example, stdio: 'inherit'), to then allow colors to be preserved!

However according to NodeJS docs the other child_process instances do provide that option such as child_process.spawn, child_process.spawnSync, child_process.execSync, thereby allowing the inheritance and preservation of colors to pass through to the output. That's just really unusual..

Any thoughts on a way around this? Want to consider using child_process instance of spawn rather than exec perhaps?

Preservation of colours would provide improved readability!

@mhkeller
Copy link
Author

mhkeller commented Nov 2, 2015

@Sayvai thanks for doing the extra research. Is this the only time it's used? Maybe a simple fork with that change could be interesting to test in case there are other effects.

@Sayvai
Copy link

Sayvai commented Nov 2, 2015

@mhkeller no worries. Given your link, yes, that looks to be the only line the exec method gets invoked.

Now, i no longer rely on gulp-shell (so no need to fork) for what I am doing (since yesterday). I am now just using the following code to run shell commands natively through node's own module, using the spawn method spawn off the child_process module, inside a Gulp task correctly, and this preserves color output! For me the process itself 'feels' slightly faster, and the project now requires one less module; gulp-shell. See code my below (note, i'm using the option stdio: 'inherit' to preserve colors, see NodeJS docs for additional options), and even take it and adjust it for yourself, if it suits your requirements:

var spawn = require('child_process').spawn;

gulp.task('test', function (callback) {
    var ls = spawn('karma', ['start', 'karma.conf.js'], {stdio: 'inherit'});

    ls.on('close', function (code) {
        console.log('child process exited with code ' + code);

        // Important to invoke the callback on close for Gulp to finish task correctly
        callback();
    });
});

@sun-zheng-an
Copy link
Owner

@Sayvai Have you try to force color like this?

@Sayvai
Copy link

Sayvai commented Nov 2, 2015

@sun-zheng-an unfortunately I don't use chalk, or any other module dependency specific to the task of colorising the output of the shell, as It's not necessary.

My requirement is simple, which is to output the same colors 'as-is', like when running the same command directly in a shell, but this time through a wrapper module like gulp-shell, etc. But gulp-shell is unable to satisfy such a requirement at the current moment in time unfortunately.

@sun-zheng-an
Copy link
Owner

@Sayvai
As I mentioned above, gulp-shell will never strip the colors for you. If you cannot see the colors, it must be your command chose not to.

@Sayvai
Copy link

Sayvai commented Nov 2, 2015

@sun-zheng-an sure, agreed.

As i mentioned in one of the other previous posts, it's really specifically the child_process.exec method which does not preserve the colors in comparison to running the same command directly in my shell / terminal, which does preserve the colors in output.

Given that information, gulp-shell is dependent and currently wrapping around the use of child_process.exec, which in turn doesn't give you the option to expose to the developers the option to preserve colors. So gulp-shell cannot really preserve colors unless there is a re-implementation around the use of child_process.

@sun-zheng-an
Copy link
Owner

@Sayvai Do you mean even if your command print out some colors, child_process.exec will strip it for you?

@Sayvai
Copy link

Sayvai commented Nov 2, 2015

@sun-zheng-an well, in practise, yes. the output appears not to preserve colors from the point of running shell commands against child_process.exec method, given the research so far.

However, the below listed child_process methods do expose the option {stdio:'inherit'}, which when used as an option in at least thespawn method, preserves the output colors:

  • child_process.spawn
  • child_process.spawnSync
  • child_process.execSync

Read up on the NodeJS docs for these methods, and play around. If you can find a way of preserving colors using child_process.exec method, great!

@sun-zheng-an
Copy link
Owner

@Sayvai

well, in practise, yes. the output appears not to preserve colors from the point of running shell commands against child_process.exec method, given the research so far.

IMHO, that's not the fact.

Please try (or something like ls --color=always):

var exec = require('child_process').exec
exec('echo "\033[0;31mRED\033[0m"', function (error, stdout) {
  console.log(stdout)
})

@cable729
Copy link

cable729 commented Feb 9, 2016

👍 I would love to have this

@Snugug
Copy link

Snugug commented Mar 14, 2016

@Sayvai is correct, spawn will always preserve colors, whereas exec may preserve colors but does not always. Would love to switch to spawn

@jeffschwartz
Copy link

+1

@jeffschwartz
Copy link

If anyone is interested, I've replaced gulp-shell with child_process. For my use case I am using its spawnSync because I need gulp to run my unit tests synchronously before it fires off the next task. Of course you can also use the other variants of spawn as well as of exec, whichever best matches your use case.

An actual example taken out of my gulpfile.js that uses chid_process follows (it spawns unit tests after the source has been compiled and bundled):

var spawn = require("child_process").spawnSync;

/**
 * run the sanity test
 */
gulp.task("test", ["bundle"], function () {
  spawn ("preamble", ["-s", "./test/sanitycheck.js"], {
    stdio: "inherit" // <== IMPORTANT: use this option to inherit the parent's environment
  });
});

As the following screenshot shows, when I run gulp test the spawned environment inherits its parent's environment so if the parent environment was configured to display color, the spawned environment will also:
screen shot 2016-05-07 at 1 13 42 pm

@michaelyali
Copy link

in params add:

env: { FORCE_COLOR: true }

@sun-zheng-an
Copy link
Owner

I just released 0.6.0 which switched from child_process.exec to child_process.spawn, it will preserve colors without forcing it.

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

No branches or pull requests

7 participants