February 21, 2012

Colorized Maven Output on Mac OSX

Overview

Unlike many other open source build tools (for example, git) Maven does not provide any type of colorized output. Maven's excessive amount of output can be hard to read and you tend to get lost in the sea of text. My current client I've been given a Mac to use and quickly found out that the existing Linux scripts did not work with iTerm. My solution, take the existing Linux scripts and modify for the Mac OSX.

Approach

Since Maven does not have colorized output, the only option is to use "sed" (stream editor) that takes the output of maven, matches strings with regex and then adds in color codes. The terminal does not escape ansi colors during the stream editing phase. The solution is to use the "tput" command along with setab and setaf for the background and foreground respectively.

Example of ANSI colors

echo -e "\033[1;34RED TEXT\[0m"

Example of TPUT colors

echo -e "${`tput setaf 1`}RED TEXT${`tput sgr0`}"

The Script

#!/bin/sh

# Written by Mike Ensor (mike@ensor.cc)
# Copywrite 2012
# Use as needed, modify, have fun!
# This is intended to be used for Maven3 + Mac OSX
#
# To use:
# in your ".bashrc" or ".bash_profile" add the following line:
# source ~//colorize-maven.sh
#

#Predefine all variables
c_black=
c_cyan=
c_magenta=
c_red=
c_white=
c_green=
c_yellow=
c_blue=
c_bg_black=
c_bg_cyan=
c_bg_magenta=
c_bg_red=
c_bg_white=
c_bg_green=
c_bg_yellow=
c_bg_blue=
c_end=
c_bold=

xterm_color() {
 # 0 Black
 # 1 Red
 # 2 Green
 # 3 Yellow
 # 4 Blue
 # 5 Magenta
 # 6 Cyan
 # 7 White

    # Yes, this could be a map
    c_bold=`tput setaf 0`
    c_bg_bold=`tput setab 0`
    c_black=`tput setab 0`
    c_bg_black=`tput setab 0`
    c_cyan=`tput setaf 6`
    c_bg_cyan=`tput setab 6`
    c_magenta=`tput setaf 5`
    c_bg_magenta=`tput setab 5`
    c_red=`tput setaf 1`
    c_bg_red=`tput setab 1`
    c_white=`tput setaf 7`
    c_bg_white=`tput setab 7`
    c_green=`tput setaf 2`
    c_bg_green=`tput setab 2`
    c_yellow=`tput setaf 3`
    c_bg_yellow=`tput setab 3`
    c_blue=`tput setaf 4`
    c_bg_blue=`tput setab 4`
    c_end=`tput sgr0`
}

#This is not used (yet)
ansi_color() {
    c_bold=   '[1m'
    c_blue=   '[1;34m'
    c_black=  '[1;30m'
    c_green=  '[1;32m'
    c_magenta='[1;35m'
    c_red=    '[1;31m'
    c_cyan=   '[1;36m'
    c_end=    '[0m'
}

color_maven() {

    # pick color type
    if [ $TERM = 'xterm-color' ]
    then
        xterm_color
#    elif [ $TERM = 'ansi' ]
#    then
#     ansi_color
 else
     echo "${c_red}WARNING:::Terminal '${TERM}' is not supported at this time. Colorized output will not happen for Maven${c_end}"
 fi

 error=${c_bold}${c_red}
 info=${c_white}
 warn=${c_yellow}
 success=${c_green}
 projectname=${c_bold}${c_cyan}
 skipped=${c_white}
 downloading=${c_magenta}

 $MAVEN_HOME/bin/mvn $* | sed -e "s/(\[INFO\]) Building( .*)/ ${info}\1${projectname}\2 ${c_end}/g" \
  -e "s/(Time elapsed: )([0-9]+[.]*[0-9]*.sec)/${c_cyan}\1${c_white}\2${c_end}/g" \
  -e "s/(Downloading: .*)/${downloading}\1${c_end}/g" \
  -e "s/BUILD FAILURE/${error}BUILD FAILURE${c_end}/g" \
  -e "s/WARNING: ([a-zA-Z0-9.-/\\ :]+)/${warn}WARNING: \1${c_end}/g" \
  -e "s/SEVERE: (.+)/${c_white}${c_bg_red}SEVERE: \1${c_end}/g" \
  -e "s/Caused by: (.+)/${c_white}${c_bg_green}Caused by: \1${c_end}/g" \
  -e "s/Running (.+)/${c_green}Running \1${c_end}/g" \
  -e "s/FAILURE (\[[0-9]+.[:0-9]+s\])/${error}FAILURE \1${c_end}/g" \
  -e "s/SUCCESS (\[[0-9]+.[:0-9]+s\])/${success}SUCCESS \1${c_end}/g" \
  -e "s/(\[INFO.*)/${info}\1${c_end}/g" \
  -e "s/INFO: (.+)/${c_white}INFO: \1${c_end}/g" \
     -e "s/(\[WARN.*)/${warn}\1${c_end}/g" \
     -e "s/(\[ERROR.*)/${error}\1${c_end}/g" \
     -e "s/(<<< FAILURE!)/${error}\1${c_end}/g" \
     -e "s/Tests run: ([0-9]*), Failures: ([0-9]*), Errors: ([0-9]*), Skipped: ([0-9]*)/${c_green}Tests run: \1 ${c_end}, Failures: ${warn}\2 ${c_end}, Errors: ${error}\3 ${c_end}, Skipped:  ${skipped}\4 ${c_end}/g"
}

alias mvn=color_maven

NOTE: This script is intended to be used with Green text on Black background. Adjust the colors as you want to come up with something more personal

Download script from Github

Click here to view Gist on Github

How to install/use

In your ".bashrc" or ".bash_profile" add the following line:

source ~/<path to script>/colorize-maven.sh

10 comments:

Dan Richelson said...

Thanks for posting this, but it doesn't work for me:
I get this error:
sed: 1: "s/(\[INFO\]) Building( ...": \1 not defined in the RE

maven 3.0.4 Mac OS 10.7.3

Dan Richelson said...
This comment has been removed by the author.
Mike! said...

Hey Dan,

I'll need a little more info, what terminal are you using? I'm not a master on the mac, most of my experience is in Linux. The differences I've experienced between linux and mac's terminals are around escaping the special characters like "[".

With a little more info I'll see if I can help narrow it down for you.

Mike!

Dan Richelson said...

I'm using iterm2: Build 1.0.0.20120203
I just tried it in Terminal.app, and I get the same result.
Also running zsh, but it does the same thing in bash.

what shell/app are you using?
thanks

Mike! said...

Hey Dan,

I'm using the Terminal.app and xterm-color as my terminal. I too use bash.

Mike!

Dan Richelson said...

http://stackoverflow.com/a/7913838

escaping all the ( and ) chars with \( and \) in the quoted sed commands seems to help.

Mike! said...

Great post! Maybe you have the GNU based sed, when I escape the characters I get errors which is why I made this post after I figured out how to do it :) ...I'll investigate how to put in a check for the differences (escape or not), create a good abstraction and re-post!

Thanks for pointing this out, I appreciate it!

Mike!

Marek Potociar said...

Same issue as Dan. Does not work for me (same setup). Escaping '(' and ')' did not help either.

Using standard MacOS X Terminal app.

Martin said...

same issue here. doesn't work in native terminal for mac os x

Anonymous said...

I was using the 256 color terminal, so this change was needed as well. Double check what you're using under Preferences > Settings > Advanced > "Declare terminal as"

$TERM = 'xterm-256color'