Return to Snippet

Revision: 24160
at February 24, 2010 16:58 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

tabsize = 4

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
    else:
        return line

def escape(s):
    s = s.replace('$', r'\$')
    s = s.replace('"', r'\"')
    s = s.replace('`', r'\`')
    return s

passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)

if __name__ == "__main__":
    cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    cancelled = False
    for line in output.stdout:
        line = line.expandtabs(tabsize)
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(line)
        try:
            sys.stdout.write(line)
        except:
            sys.exit(1)

Revision: 24159
at February 24, 2010 16:51 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Near-complete rewrite:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

tabsize = 4

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
    else:
        return line

passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)

if __name__ == "__main__":
    cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        line = line.expandtabs(tabsize)
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(line)
        sys.stdout.write(line)

Revision: 24158
at February 24, 2010 16:49 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

tabsize = 4

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
    else:
        return line

passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)

if __name__ == "__main__":
    cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        line = line.expandtabs(tabsize)
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(line)
        sys.stdout.write(line)

Revision: 24157
at February 24, 2010 16:47 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

tabsize = 4

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
    else:
        return line

passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)

if __name__ == "__main__":
    cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(line)
        sys.stdout.write(line)

Revision: 24156
at February 22, 2010 14:57 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

tabsize = 4

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
    else:
        return line

def escape(s):
    s = s.rstrip()
    s = s.expandtabs(tabsize)
    s = s.replace('$', r'\$')
    s = s.replace('"', r'\"')
    s = s.replace('`', r'\`')
    return s

passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)

if __name__ == "__main__":
    cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(escape(line))
        else:
            line = escape(line)
        p = subprocess.Popen("echo \"%s\"" % line, shell=True, stdin=subprocess.PIPE)
        p.wait()
        if(p.returncode):
            sys.exit(1)

Revision: 24155
at February 22, 2010 12:48 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import os, sys, re, subprocess

colorizedSubcommands = (
	'status',
	'add',
	'remove',
	'diff',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def colorize(line): 
    for color in statusColors:
        if re.match(color, line):
            return ''.join(("\033[", statusColors[color], "m", line, "\033[m"))
    else:
        return line

if __name__ == "__main__":
    output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            line = colorize(line.strip().replace('$', '\$'))
        
        p = subprocess.Popen("echo '%s'" % line, shell=True, stdin=subprocess.PIPE)
        p.wait()
        if(p.returncode):
            sys.exit(1)

Revision: 24154
at February 22, 2010 12:01 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

colorizedSubcommands = (
    'status',
    'add',
    'remove',
)

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def matchStatusColorAndPrint(line): 
    for color in statusColors:
        if re.match(color, line):
            echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
            subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
            break
    else:
        subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
    output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            matchStatusColorAndPrint(line.strip().replace('$', '\$'))
        else:
            subprocess.Popen("echo \"" + line + "\"", shell=True)

Revision: 24153
at February 22, 2010 11:52 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

colorizedSubcommands = [
    'status',
    'add',
    'remove',
]

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def matchStatusColorAndPrint(line): 
    for color in statusColors:
        if re.match(color, line):
            echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
            subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
            break
    else:
        subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
    output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            matchStatusColorAndPrint(line.strip().replace('$', '\$'))
        else:
            subprocess.Popen("echo \"" + line + "\"", shell=True)

Revision: 24152
at February 22, 2010 11:51 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

colorizedSubcommands = [
	'status',
	'add',
	'remove',
]

statusColors = {
    "M"     : "31",     # red 
    "\?"    : "37",     # grey
    "A"     : "32",     # green
    "X"     : "33",     # yellow
    "C"     : "30;41",  # black on red
    "-"     : "31",     # red
    "D"     : "31;1",   # bold red
    "\+"    : "32",     # green
}

def matchStatusColorAndPrint(line): 
    for color in statusColors:
        if re.match(color, line):
            echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
            subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
            break
    else:
        subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
    output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        if(sys.argv[1] in colorizedSubcommands):
            matchStatusColorAndPrint(line.strip().replace('$', '\$'))
        else:
            subprocess.Popen("echo \"" + line + "\"", shell=True)

Revision: 24151
at February 22, 2010 11:42 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

def matchStatusColorAndPrint(line): 
    statusColors = {
        "M"     : "31",     # red 
        "\?"    : "37",     # grey
        "A"     : "32",     # green
        "X"     : "33",     # yellow
        "C"     : "30;41",  # black on red
        "-"     : "31",     # red
        "D"     : "31;1",   # red
        "\+"    : "32",     # green
    }   
    
    for color in statusColors:
        if re.match(color, line):
            echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
            subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
            break
    else:
        subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
    output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
    for line in output.stdout:
        matchStatusColorAndPrint(line.strip().replace('$', '\$'))

Revision: 24150
at February 22, 2010 11:41 by philchristensen


Updated Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

def matchStatusColorAndPrint(line): 
	statusColors = {
		"M"     : "31",     # red 
		"\?"    : "37",     # grey
		"A"     : "32",     # green
		"X"     : "33",     # yellow
		"C"     : "30;41",  # black on red
		"-"     : "31",     # red
		"D"     : "31;1",   # red
		"\+"    : "32",     # green
	}	
	
	for color in statusColors:
		if re.match(color, line):
			echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
			subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
			break
	else:
		subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
	output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
	for line in output.stdout:
 		matchStatusColorAndPrint(line.strip().replace('$', '\$'))

Revision: 24149
at February 22, 2010 11:40 by philchristensen


Initial Code
#!/usr/bin/env python

"""
 Author: Saophalkun Ponlu (http://phalkunz.com)
 Contact: [email protected]
 Date: May 23, 2009
 Modified: June 15, 2009
 
 Additional modifications:
 Author: Phil Christensen (http://bubblehouse.org)
 Contact: [email protected]
 Date: February 22, 2010
"""

import sys, re, subprocess

def matchStatusColorAndPrint(line): 
	statusColors = {
		"M": "31",		# red 
		"\?": "37", 	# grey
		"A": "32", 		# green
		"X": "33", 		# yellow
		"C": "30;41",	# black on red
		"-": "31",		# red
		"D": "31;1",	# red
		"\+": "32",		# green
	}	
	
	for color in statusColors:
		if re.match(color, line):
			echo = ''.join(("echo '", "\033[", statusColors[color], "m", line, "\033[m'"))
			subprocess.Popen(echo, shell=True, stdin=subprocess.PIPE)
			break
	else:
		subprocess.Popen("echo \"" + line + "\"", shell=True)

if __name__ == "__main__":
	output = subprocess.Popen(' '.join(['svn']+sys.argv[1:]), shell=True, stdout=subprocess.PIPE)
	for line in output.stdout:
 		matchStatusColorAndPrint(line.strip().replace('$', '\$'))

Initial URL


Initial Description
First there was: [http://snipplr.com/view/15246/color-coded-svn-status](http://snipplr.com/view/15246/color-coded-svn-status)

Then there was: [http://snipplr.com/view/16540/color-coded-svn-status-v2](http://snipplr.com/view/16540/color-coded-svn-status-v2)

A few days ago, I found a handy script online that colorized the output of SVN status. It worked pretty well, but needed a little polish and a couple of tweaks to make it use more common Python idioms. As I continued to use it and fix bugs and inefficiencies, I ended up replacing nearly every line in the original, but it was still a great starting point.

Additional changes include ANSI word-wrapping, a configurable tab expansion feature (for better code alignment), the 'colorizedSubcommands' sequence so that only applicable commands get colorized, use of proper `subprocess` module calls so that piping through `less` will work (for example, try `svn-color diff | less -r` to see colorized diff output).

To use, stick it somewhere, make executable (`chmod 755`), and then add this to your .profile:

    alias svn=/usr/local/bin/svn-color.py

I hope you find my modifications useful. You can modify the colors used by looking up the ANSI color codes for your preferred color scheme and editing the 'statusColors' dictionary. Here's a useful reference for ANSI color values:

[http://www.ibm.com/developerworks/linux/library/l-tip-prompt/colortable.gif](http://www.ibm.com/developerworks/linux/library/l-tip-prompt/colortable.gif)

Requires Python 2.4 or greater.

Initial Title
Color-Coded `svn status` (v3)

Initial Tags
svn, Bash, python, color

Initial Language
Python