PgDiff, schemadiff.py: Add function filter. Add --body parameter to diff function source.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pgtoolkit/colordiff.py Thu Jan 31 13:24:57 2013 +0100
@@ -0,0 +1,12 @@
+from subprocess import Popen, PIPE
+
+
+def colordiff(diff):
+ """Colorize diff output using external program colordiff"""
+ try:
+ p = Popen(["colordiff"], stdin=PIPE, stdout=PIPE, close_fds=True)
+ outs, _errs = p.communicate(diff.encode('utf8'))
+ return outs.decode('utf8')
+ except OSError:
+ return diff
+
--- a/pgtoolkit/pgdiff.py Thu Jan 31 11:02:04 2013 +0100
+++ b/pgtoolkit/pgdiff.py Thu Jan 31 13:24:57 2013 +0100
@@ -26,6 +26,10 @@
from pgtoolkit.highlight import *
+from pgtoolkit.colordiff import colordiff
+
+import re
+import difflib
class PgDiffError(Exception):
@@ -134,7 +138,7 @@
class DiffFunction(DiffBase):
- def __init__(self, change, schema, function):
+ def __init__(self, change, schema, function, show_body_diff=False):
DiffBase.__init__(self)
self.level = 1
self.type = 'function'
@@ -142,18 +146,28 @@
self.schema = schema
self.function = function
self.name = function
+ self.show_body_diff = show_body_diff
def _formatchanges(self):
res = []
for x in self.changes:
type, a, b = x
if type == 'source':
- s = 'Changed source.'
+ if self.show_body_diff:
+ lines = ['Source differs:\n']
+ for line in difflib.unified_diff(a, b, lineterm=''):
+ if line[:3] in ('---', '+++'):
+ continue
+ lines.append(line + '\n')
+ diff = ''.join(lines)
+ diff = colordiff(diff)
+ res.append(diff)
+ else:
+ res.append('Source differs.')
else:
- s = ''.join(['Changed ', type, ' from ',
+ res.append(''.join(['Changed ', type, ' from ',
highlight(1,15), a, highlight(0), ' to ',
- highlight(1,15), b, highlight(0), '.'])
- res.append(s)
+ highlight(1,15), b, highlight(0), '.']))
return ' '.join(res)
@@ -249,6 +263,8 @@
self.exclude_schemas = set() # exclude these schemas from diff
self.include_tables = set()
self.exclude_tables = set()
+ self.function_regex = re.compile(r"")
+ self.function_body_diff = False
def _test_schema(self, schema):
if self.include_schemas and schema not in self.include_schemas:
@@ -264,6 +280,9 @@
return False
return True
+ def _test_function(self, function):
+ return bool(self.function_regex.match(function))
+
def _diff_names(self, src, dst):
for x in src:
if x in dst:
@@ -296,8 +315,12 @@
diff = []
if a.result != b.result:
diff.append(('result', a.result, b.result))
- if a.source != b.source:
- diff.append(('source', a.source, b.source))
+ # function source may differ in newlines (\n vs \r\n)
+ # split lines before comparison, so that these differencies are ignored
+ a_source = a.source.splitlines()
+ b_source = b.source.splitlines()
+ if a_source != b_source:
+ diff.append(('source', a_source, b_source))
return diff
def _compare_arguments(self, a, b):
@@ -387,7 +410,9 @@
def _diff_functions(self, schema, src_functions, dst_functions):
for nd in self._diff_names(src_functions, dst_functions):
- fdo = DiffFunction(change=nd[0], schema=schema, function=nd[1])
+ if not self._test_function(nd[1]):
+ continue
+ fdo = DiffFunction(change=nd[0], schema=schema, function=nd[1], show_body_diff=self.function_body_diff)
if nd[0] == '*':
# compare function body and result
a = src_functions[nd[1]]
@@ -492,13 +517,14 @@
self.exclude_schemas.clear()
self.exclude_schemas.update(exclude)
-
def filter_tables(self, include=[], exclude=[]):
self.include_tables.clear()
self.include_tables.update(include)
self.exclude_tables.clear()
self.exclude_tables.update(exclude)
+ def filter_functions(self, regex=''):
+ self.function_regex = re.compile(regex)
def _check_schema_exist(self, schema):
if not schema in self.src.schemas:
--- a/schemadiff.py Thu Jan 31 11:02:04 2013 +0100
+++ b/schemadiff.py Thu Jan 31 13:24:57 2013 +0100
@@ -15,7 +15,9 @@
self.parser.add_argument('-s', dest='schema', nargs='*', help='Schema filter')
self.parser.add_argument('-t', dest='table', nargs='*', help='Table filter')
+ self.parser.add_argument('-f', dest='function', type=str, help='Function filter (regex)')
self.parser.add_argument('--sql', action='store_true', help='Output is SQL script.')
+ self.parser.add_argument('--body', action='store_true', help='Output diff for function bodies.')
self.init()
@@ -28,9 +30,12 @@
try:
if self.args.schema:
pgd.filter_schemas(include=self.args.schema)
-
if self.args.table:
pgd.filter_tables(include=self.args.table)
+ if self.args.function:
+ pgd.filter_functions(self.args.function)
+ if self.args.body:
+ pgd.function_body_diff = True
if self.args.sql:
pgd.print_patch()