parent
9155e4ffe0
commit
f1eb008cc7
|
@ -11,6 +11,7 @@ manifests:
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
hb-diff \
|
hb-diff \
|
||||||
|
hb-diff-colorize \
|
||||||
hb-diff-filter-failures \
|
hb-diff-filter-failures \
|
||||||
hb-manifest-read \
|
hb-manifest-read \
|
||||||
hb-manifest-update \
|
hb-manifest-update \
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
from hb_test_tools import *
|
from hb_test_tools import *
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
if len (sys.argv) < 3:
|
if len (sys.argv) < 2:
|
||||||
print "usage: %s file1 file2..." % sys.argv[0]
|
print "usage: %s FILES..." % sys.argv[0]
|
||||||
sys.exit (1)
|
sys.exit (1)
|
||||||
|
|
||||||
ZipDiffer.diff_files (FileHelpers.open_file_or_stdin (f) for f in sys.argv[1:])
|
ZipDiffer.diff_files (FileHelpers.open_file_or_stdin (f) for f in sys.argv[1:])
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from hb_test_tools import *
|
||||||
|
|
||||||
|
formatter = ColorFormatter.Auto (sys.argv)
|
||||||
|
colorizer = DiffColorizer (formatter=formatter)
|
||||||
|
UtilMains.process_multiple_files (FilterHelpers.filter_printer_function_no_newline (colorizer.colorize_diff))
|
|
@ -1,65 +1,81 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import sys, os, re, difflib, unicodedata, errno
|
import sys, os, re, difflib, unicodedata, errno, cgi
|
||||||
from itertools import *
|
from itertools import *
|
||||||
|
|
||||||
diff_symbols = "-+=*&^%$#@!~/"
|
diff_symbols = "-+=*&^%$#@!~/"
|
||||||
diff_colors = ['red', 'green', 'blue']
|
diff_colors = ['red', 'green', 'blue']
|
||||||
|
|
||||||
class Colors:
|
class ColorFormatter:
|
||||||
|
|
||||||
class Null:
|
class Null:
|
||||||
red = ''
|
@staticmethod
|
||||||
green = ''
|
def start_color (c): return ''
|
||||||
end = ''
|
@staticmethod
|
||||||
|
def end_color (): return ''
|
||||||
|
@staticmethod
|
||||||
|
def escape (s): return s
|
||||||
|
@staticmethod
|
||||||
|
def newline (): return '\n'
|
||||||
|
|
||||||
class ANSI:
|
class ANSI:
|
||||||
red = '\033[41;37;1m'
|
@staticmethod
|
||||||
green = '\033[42;37;1m'
|
def start_color (c):
|
||||||
end = '\033[m'
|
return {
|
||||||
|
'red': '\033[41;37;1m',
|
||||||
|
'green': '\033[42;37;1m',
|
||||||
|
'blue': '\033[44;37;1m',
|
||||||
|
}[c]
|
||||||
|
@staticmethod
|
||||||
|
def end_color ():
|
||||||
|
return '\033[m'
|
||||||
|
@staticmethod
|
||||||
|
def escape (s): return s
|
||||||
|
@staticmethod
|
||||||
|
def newline (): return '\n'
|
||||||
|
|
||||||
class HTML:
|
class HTML:
|
||||||
red = '<span style="color:red">'
|
@staticmethod
|
||||||
green = '<span style="color:green">'
|
def start_color (c):
|
||||||
end = '</span>'
|
return '<span style="background:%s">' % c
|
||||||
|
@staticmethod
|
||||||
|
def end_color ():
|
||||||
|
return '</span>'
|
||||||
|
@staticmethod
|
||||||
|
def escape (s): return cgi.escape (s)
|
||||||
|
@staticmethod
|
||||||
|
def newline (): return '<br/>\n'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Auto (argv = [], out = sys.stdout):
|
def Auto (argv = [], out = sys.stdout):
|
||||||
if os.isatty (out.fileno ()):
|
format = ColorFormatter.ANSI
|
||||||
color = Colors.ANSI
|
if "--format" in argv:
|
||||||
else:
|
argv.remove ("--format")
|
||||||
color = Colors.Null
|
format = ColorFormatter.ANSI
|
||||||
if "--color" in argv:
|
if "--format=ansi" in argv:
|
||||||
argv.remove ("--color")
|
argv.remove ("--format=ansi")
|
||||||
color = Colors.ANSI
|
format = ColorFormatter.ANSI
|
||||||
if "--color=ansi" in argv:
|
if "--format=html" in argv:
|
||||||
argv.remove ("--color=ansi")
|
argv.remove ("--format=html")
|
||||||
color = Colors.ANSI
|
format = ColorFormatter.HTML
|
||||||
if "--color=html" in argv:
|
if "--no-format" in argv:
|
||||||
argv.remove ("--color=html")
|
argv.remove ("--no-format")
|
||||||
color = Colors.HTML
|
format = ColorFormatter.Null
|
||||||
if "--no-color" in argv:
|
return format
|
||||||
argv.remove ("--no-color")
|
|
||||||
color = Colors.Null
|
|
||||||
return color
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
class DiffColorizer:
|
||||||
def Default (argv = []):
|
|
||||||
return Colors.ANSI
|
|
||||||
|
|
||||||
|
|
||||||
class FancyDiffer:
|
|
||||||
|
|
||||||
diff_regex = re.compile ('([a-za-z0-9_]*)([^a-za-z0-9_]?)')
|
diff_regex = re.compile ('([a-za-z0-9_]*)([^a-za-z0-9_]?)')
|
||||||
|
|
||||||
@staticmethod
|
def __init__ (self, formatter, colors=diff_colors, symbols=diff_symbols):
|
||||||
def diff_lines (l1, l2, colors=Colors.Null):
|
self.formatter = formatter
|
||||||
|
self.colors = colors
|
||||||
|
self.symbols = symbols
|
||||||
|
|
||||||
# Easy without colors
|
def colorize_lines (self, lines):
|
||||||
if colors == Colors.Null:
|
lines = (l if l else '' for l in lines)
|
||||||
if l1 == l2:
|
ss = [self.diff_regex.sub (r'\1\n\2\n', l).splitlines (True) for l in lines]
|
||||||
return [' ', l1]
|
|
||||||
return ['-', l1, '+', l2]
|
|
||||||
|
|
||||||
ss = [FancyDiffer.diff_regex.sub (r'\1\n\2\n', l).splitlines (True) for l in (l1, l2)]
|
|
||||||
oo = ["",""]
|
oo = ["",""]
|
||||||
st = [False, False]
|
st = [False, False]
|
||||||
for l in difflib.Differ().compare (*ss):
|
for l in difflib.Differ().compare (*ss):
|
||||||
|
@ -68,29 +84,47 @@ class FancyDiffer:
|
||||||
if l[0] == ' ':
|
if l[0] == ' ':
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
if st[i]:
|
if st[i]:
|
||||||
oo[i] += colors.end
|
oo[i] += self.formatter.end_color ()
|
||||||
st[i] = False
|
st[i] = False
|
||||||
oo = [o + l[2:] for o in oo]
|
oo = [o + self.formatter.escape (l[2:]) for o in oo]
|
||||||
continue
|
continue
|
||||||
if l[0] == '-':
|
if l[0] in self.symbols:
|
||||||
if not st[0]:
|
i = self.symbols.index (l[0])
|
||||||
oo[0] += colors.red
|
if not st[i]:
|
||||||
st[0] = True
|
oo[i] += self.formatter.start_color (self.colors[i])
|
||||||
oo[0] += l[2:]
|
st[i] = True
|
||||||
|
oo[i] += self.formatter.escape (l[2:])
|
||||||
continue
|
continue
|
||||||
if l[0] == '+':
|
|
||||||
if not st[1]:
|
|
||||||
oo[1] += colors.green
|
|
||||||
st[1] = True
|
|
||||||
oo[1] += l[2:]
|
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
if st[i]:
|
if st[i]:
|
||||||
oo[i] += colors.end
|
oo[i] += self.formatter.end_color ()
|
||||||
st[i] = 0
|
st[i] = False
|
||||||
oo = [o.replace ('\n', '') for o in oo]
|
oo = [o.replace ('\n', '') for o in oo]
|
||||||
if oo[0] == oo[1]:
|
return [s1+s2+self.formatter.newline () for (s1,s2) in zip (self.symbols, oo) if s2]
|
||||||
return [' ', oo[0], '\n']
|
|
||||||
return ['-', oo[0], '\n', '+', oo[1], '\n']
|
def colorize_diff (self, f):
|
||||||
|
lines = [None, None]
|
||||||
|
for l in f:
|
||||||
|
if l[0] not in self.symbols:
|
||||||
|
yield self.formatter.escape (l).replace ('\n', self.formatter.newline ())
|
||||||
|
continue
|
||||||
|
i = self.symbols.index (l[0])
|
||||||
|
if lines[i]:
|
||||||
|
# Flush
|
||||||
|
for line in self.colorize_lines (lines):
|
||||||
|
yield line
|
||||||
|
lines = [None, None]
|
||||||
|
lines[i] = l[1:]
|
||||||
|
if (all (lines)):
|
||||||
|
# Flush
|
||||||
|
for line in self.colorize_lines (lines):
|
||||||
|
yield line
|
||||||
|
lines = [None, None]
|
||||||
|
if (any (lines)):
|
||||||
|
# Flush
|
||||||
|
for line in self.colorize_lines (lines):
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
class ZipDiffer:
|
class ZipDiffer:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue