How to force symfony colors on windows with PuttyCyg?

Those of you who’re developing with symfony under windows will have noticed that, when running tasks in the command prompt, no colors are used. This is because the windows command prompt isn’t compatible with the color notation.
Most of you also have cygwin installed (shame on you if you didn’t :p). But even if you run the tasks through “PuttyCyg”, which is fully compatible with the color notation, you will not benefit from the colors.

Why?

The problem resides in the symfony class “sfAnsiColorFormatter” in the method “supportsColors($stream)”:

/**
   * Returns true if the stream supports colorization.
   *
   * Colorization is disabled if not supported by the stream:
   *
   *  -  windows
   *  -  non tty consoles
   *
   * @param mixed $stream A stream
   *
   * @return Boolean true if the stream supports colorization, false otherwise
   */
  public function supportsColors($stream)
  {
    return DIRECTORY_SEPARATOR != '\\' && function_exists('posix_isatty') && @posix_isatty($stream);
  }

The method supportsColors($stream) decides whether or not colors are supported. And as you can see, one of the checks is the directory separator which in our case will always return false because we are on a windows operating system. So even if you run tasks through puttycyg the directory separator will remain the same.

Possibility 1

If you always work through the puttycyg you could simply set the method to always return true, but in a command prompt it will look like this:

[Dos Command Output][3]
Dos Command Output

Possibility 2

Detect if cygwin is used. This way when you use the dos command the output will work and when cygwin is used you’ll have the colors :).

I checked the $_SERVER array to find something that could help me to distinguish the cygwin prompt with the dos prompt, and I found that the ‘PWD’ key is only available on *nix shells. And when I print the value of $_SERVER[‘PWD’] in the cygwin prompt it gives me “/cygdrive/f/sandbox/adlogix/branch-3.2/frontend”.

Knowing that, here is how we can change the supportsColors method:

/**
   * Returns true if the stream supports colorization.
   *
   * Colorization is disabled if not supported by the stream:
   *
   *  -  windows
   *  -  non tty consoles
   *
   * @param mixed $stream A stream
   *
   * @return Boolean true if the stream supports colorization, false otherwise
   */
  public function supportsColors($stream)
  {
    $supported = DIRECTORY_SEPARATOR != '\\' && function_exists('posix_isatty') && @posix_isatty($stream);
    
    return $supported ? true : !is_bool(strpos(@$_SERVER['PWD'], "/cygdrive"));
  }

What I did, is still using the check symfony used, but when it returns false I do a second check to see if the $_SERVER[‘PWD’] exists and that it contains the String “/cygdrive”.

Now when I run the taks through cygwin I get the colors and when I run it in dos it displays correctly.

[PuttyCyg versus Dos][4]
PuttyCyg versus Dos

I only tested it on my machine, so if you have troubles or a better way to do it, please let me know :).

Update: This is only tested with symfony 1.2 and as from sf 1.3 there will be an option –color to force the colors.

Update: For some reason it does not work in the cygwin bash shell. When I set the message manually (echo -e “\033[31mHello World\033[0m”) in the command the colors appear, but through symfony not. I suspect that the cygwin bash shell miss interprets the returns of php, but I have no idea why it does work on puttyCyg (which only launches the cygwin shell) … probably some startup configuration of the bash ?!

By the way, if you found a typo, please fork and edit this post. Thank you so much! This post is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Comments

Fork me on GitHub