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.
- Perhaps relevant: rails/spring@95bca40
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.