thewoolleyman/process_helper

Support color in terminals

Closed this issue · 6 comments

When using the ruby system method to shell out, it sets the correct options to preserve color in the output. For example system(rspec --color). ProcessHelper should do the same.

Looking at the RSpec code, it uses the #tty? method to determine if color is supported, which is usually IO#tty? on $stdout.

In this specific instance, RSpec can be forced to use color by adding the --tty option in addition to --color; since ProcessHelper is intended for use on any command, it's best to support color output rather than figure out one-off overrides for every command.

Do you have any idea what the fix should be to support color output?

I believe this bug is specific to Rspec, because it attempts to detect if it is running in a tty, and if not it will not output color.

Basic printing of color works fine, and I've added some tests to prove it in the latest commit.

I might be able to add an option to use a Pseudo TTY, but I'm not sure if this would work in all cases, since capturing output doesn't behave like a TTY in all aspects, and also not sure if it's compatible with Open3#popen2e, which is the crux of how ProcessHelper works.

As you said this rspec issue describes this situation exactly, and you can force rspec to color even on non-tty by adding --tty.

So, I'm not sure why Kernel#system reports as a tty while Open3#popen2e does not, or if it is overrideable by a Pseudo TTY or other means.

I think the crux of the issue is making processes think they're in a TTY. This is how they detect whether or not to use color in their output. Primary examples of losing color are the bosh and cf CLIs.

You might look at https://github.com/stripe/subprocess. I tried the following and it outputs color:

$ gem install subproccess
$ ruby -rsubprocess -e "Subprocess.check_call(['cf', 'apps'])"
# ...(it fails because I'm not authenticated to CF)...
$ echo $?
1

It also works for the BOSH CLI: ruby -rsubprocess -e "Subprocess.check_call(['bosh', 'status'])".

As of 9cadff1, color now works if you invoke the command in a pseudo terminal via the pseudo_terminal: true (pty: true) option.