1<?php 2/* 3 * $Id: f4e92d98e6607c40a11d6f7f7b71ee81c5c6b995 $ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information please see 19 * <http://phing.info>. 20 */ 21 22require_once 'phing/listener/DefaultLogger.php'; 23include_once 'phing/system/util/Properties.php'; 24 25/** 26 * Uses ANSI Color Code Sequences to colorize messages 27 * sent to the console. 28 * 29 * If used with the -logfile option, the output file 30 * will contain all the necessary escape codes to 31 * display the text in colorized mode when displayed 32 * in the console using applications like cat, more, 33 * etc. 34 * 35 * This is designed to work on terminals that support ANSI 36 * color codes. It works on XTerm, ETerm, Mindterm, etc. 37 * It also works on Win9x (with ANSI.SYS loaded.) 38 * 39 * NOTE: 40 * It doesn't work on WinNT's COMMAND.COM even with 41 * ANSI.SYS loaded. 42 * 43 * The default colors used for differentiating 44 * the message levels can be changed by editing the 45 * phing/listener/defaults.properties file. 46 * 47 * This file contains 5 key/value pairs: 48 * AnsiColorLogger.ERROR_COLOR=2;31 49 * AnsiColorLogger.WARNING_COLOR=2;35 50 * AnsiColorLogger.INFO_COLOR=2;36 51 * AnsiColorLogger.VERBOSE_COLOR=2;32 52 * AnsiColorLogger.DEBUG_COLOR=2;34 53 * 54 * Another option is to pass a system variable named 55 * ant.logger.defaults, with value set to the path of 56 * the file that contains user defined Ansi Color 57 * Codes, to the <B>java</B> command using -D option. 58 * 59 * To change these colors use the following chart: 60 * 61 * <B>ANSI COLOR LOGGER CONFIGURATION</B> 62 * 63 * Format for AnsiColorLogger.*= 64 * Attribute;Foreground;Background 65 * 66 * Attribute is one of the following: 67 * 0 -> Reset All Attributes (return to normal mode) 68 * 1 -> Bright (Usually turns on BOLD) 69 * 2 -> Dim 70 * 3 -> Underline 71 * 5 -> link 72 * 7 -> Reverse 73 * 8 -> Hidden 74 * 75 * Foreground is one of the following: 76 * 30 -> Black 77 * 31 -> Red 78 * 32 -> Green 79 * 33 -> Yellow 80 * 34 -> Blue 81 * 35 -> Magenta 82 * 36 -> Cyan 83 * 37 -> White 84 * 85 * Background is one of the following: 86 * 40 -> Black 87 * 41 -> Red 88 * 42 -> Green 89 * 43 -> Yellow 90 * 44 -> Blue 91 * 45 -> Magenta 92 * 46 -> Cyan 93 * 47 -> White 94 * 95 * @author Hans Lellelid <hans@xmpl.org> (Phing) 96 * @author Magesh Umasankar (Ant) 97 * @package phing.listener 98 * @version $Id: f4e92d98e6607c40a11d6f7f7b71ee81c5c6b995 $ 99 */ 100class AnsiColorLogger extends DefaultLogger { 101 102 const ATTR_NORMAL = 0; 103 const ATTR_BRIGHT = 1; 104 const ATTR_DIM = 2; 105 const ATTR_UNDERLINE = 3; 106 const ATTR_BLINK = 5; 107 const ATTR_REVERSE = 7; 108 const ATTR_HIDDEN = 8; 109 110 const FG_BLACK = 30; 111 const FG_RED = 31; 112 const FG_GREEN = 32; 113 const FG_YELLOW = 33; 114 const FG_BLUE = 34; 115 const FG_MAGENTA = 35; 116 const FG_CYAN = 36; 117 const FG_WHITE = 37; 118 119 const BG_BLACK = 40; 120 const BG_RED = 41; 121 const BG_GREEN = 42; 122 const BG_YELLOW = 44; 123 const BG_BLUE = 44; 124 const BG_MAGENTA = 45; 125 const BG_CYAN = 46; 126 const BG_WHITE = 47; 127 128 const PREFIX = "\x1b["; 129 const SUFFIX = "m"; 130 const SEPARATOR = ';'; 131 const END_COLOR = "\x1b[0m"; // self::PREFIX . self::SUFFIX; 132 133 private $errColor; 134 private $warnColor; 135 private $infoColor; 136 private $verboseColor; 137 private $debugColor; 138 139 private $colorsSet = false; 140 141 /** 142 * Construct new AnsiColorLogger 143 * Perform initializations that cannot be done in var declarations. 144 */ 145 public function __construct() { 146 parent::__construct(); 147 $this->errColor = self::PREFIX . self::ATTR_NORMAL . self::SEPARATOR . self::FG_RED . self::SUFFIX; 148 $this->warnColor = self::PREFIX . self::ATTR_NORMAL . self::SEPARATOR . self::FG_MAGENTA . self::SUFFIX; 149 $this->infoColor = self::PREFIX . self::ATTR_NORMAL . self::SEPARATOR . self::FG_CYAN . self::SUFFIX; 150 $this->verboseColor = self::PREFIX . self::ATTR_NORMAL . self::SEPARATOR . self::FG_GREEN . self::SUFFIX; 151 $this->debugColor = self::PREFIX . self::ATTR_NORMAL . self::SEPARATOR . self::FG_BLUE . self::SUFFIX; 152 } 153 154 /** 155 * Set the colors to use from a property file specified by the 156 * special ant property ant.logger.defaults 157 */ 158 private final function setColors() { 159 160 $userColorFile = Phing::getProperty("phing.logger.defaults"); 161 $systemColorFile = new PhingFile(Phing::getResourcePath("phing/listener/defaults.properties")); 162 163 $in = null; 164 165 try { 166 $prop = new Properties(); 167 168 if ($userColorFile !== null) { 169 $prop->load($userColorFile); 170 } else { 171 $prop->load($systemColorFile); 172 } 173 174 $err = $prop->getProperty("AnsiColorLogger.ERROR_COLOR"); 175 $warn = $prop->getProperty("AnsiColorLogger.WARNING_COLOR"); 176 $info = $prop->getProperty("AnsiColorLogger.INFO_COLOR"); 177 $verbose = $prop->getProperty("AnsiColorLogger.VERBOSE_COLOR"); 178 $debug = $prop->getProperty("AnsiColorLogger.DEBUG_COLOR"); 179 if ($err !== null) { 180 $this->errColor = self::PREFIX . $err . self::SUFFIX; 181 } 182 if ($warn !== null) { 183 $this->warnColor = self::PREFIX . $warn . self::SUFFIX; 184 } 185 if ($info !== null) { 186 $this->infoColor = self::PREFIX . $info . self::SUFFIX; 187 } 188 if ($verbose !== null) { 189 $this->verboseColor = self::PREFIX . $verbose . self::SUFFIX; 190 } 191 if ($debug !== null) { 192 $this->debugColor = self::PREFIX . $debug . self::SUFFIX; 193 } 194 } catch (IOException $ioe) { 195 //Ignore exception - we will use the defaults. 196 } 197 } 198 199 /** 200 * @see DefaultLogger#printMessage 201 * @param string $message 202 * @param OutputStream $stream 203 * @param int $priority 204 */ 205 protected final function printMessage($message, OutputStream $stream, $priority) { 206 if ($message !== null) { 207 208 if (!$this->colorsSet) { 209 $this->setColors(); 210 $this->colorsSet = true; 211 } 212 213 switch ($priority) { 214 case Project::MSG_ERR: 215 $message = $this->errColor . $message . self::END_COLOR; 216 break; 217 case Project::MSG_WARN: 218 $message = $this->warnColor . $message . self::END_COLOR; 219 break; 220 case Project::MSG_INFO: 221 $message = $this->infoColor . $message . self::END_COLOR; 222 break; 223 case Project::MSG_VERBOSE: 224 $message = $this->verboseColor . $message . self::END_COLOR; 225 break; 226 case Project::MSG_DEBUG: 227 $message = $this->debugColor . $message . self::END_COLOR; 228 break; 229 } 230 231 $stream->write($message . PHP_EOL); 232 } 233 } 234} 235