@@ -47,9 +47,11 @@
import argparse
import collections
+import datetime
import difflib
import distutils.version as version
import errno
+import itertools
import json
import multiprocessing
import os
@@ -68,6 +70,18 @@
import uuid
import xml.dom.minidom as minidom
+_unified_diff = difflib.unified_diff
+if PYTHON3:
+ import functools
+ _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
+
+try:
+ from mercurial import mdiff, patch
+ _diff = mdiff.new_diff
+except Exception:
+ print("Falling back to unified_diff")
+ _diff = _unified_diff
+
try:
import Queue as queue
except ImportError:
@@ -598,15 +612,10 @@
except OSError:
pass
-_unified_diff = difflib.unified_diff
-if PYTHON3:
- import functools
- _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
-
def getdiff(expected, output, ref, err):
servefail = False
lines = []
- for line in _unified_diff(expected, output, ref, err):
+ for line in _diff(expected, output, ref, err):
if line.startswith(b'+++') or line.startswith(b'---'):
line = line.replace(b'\\', b'/')
if line.endswith(b' \n'):
@@ -7,6 +7,8 @@
from __future__ import absolute_import
+import datetime
+import itertools
import re
import struct
import zlib
@@ -525,3 +527,33 @@
def replacediffheader(oldlen, newlen):
return struct.pack(">lll", 0, oldlen, newlen)
+
+def prepare_mdiff(expected, output):
+ """Prepare the inputs for the mdiff.unidiff function"""
+ date1 = datetime.datetime.now().strftime("%a %b %d %y %H:%M:%S %Y %z")
+ date2 = date1
+ # join all the different elements into a single string
+ # to regenerate that file
+ exp = "".join(expected)
+ out = "".join(output)
+ opts = diffopts(noprefix=True)
+ return exp, date1, out, date2, opts
+
+def process_mdiff(uheaders, hunks):
+ """Process the output of mdiff into a list of lines,
+ to be used by getdiff"""
+ # the hunklines are in the hunks generator
+ # get the hunklines from the (hunkrange,hunklines) tuple
+ hunklines = [x[1] for x in hunks]
+ # extract and insert the headers at the beginnng of the hunklines list
+ headers = [uheaders[0].split("\t")[0]+"\n", uheaders[1].split("\t")[0]+"\n"]
+ hunklines.insert(0, headers)
+ difflines = itertools.chain.from_iterable(hunklines)
+ return difflines
+
+def new_diff(expected, output, ref, err):
+ exp, date1, out, date2, opts = prepare_mdiff(expected, output)
+ uheaders, hunks = unidiff(exp, date1, out, date2,
+ ref, err, binary=False, opts=opts)
+ difflines = process_mdiff(uheaders, hunks)
+ return difflines