jenkins-bot has submitted this change and it was merged.
Change subject: [FEAT] Diff: Use PatchManager for showDiff ......................................................................
[FEAT] Diff: Use PatchManager for showDiff
This uses PatchManager for pywikibot.showDiff and also includes now a header.
It also fixes the missing space in front of a line if it was added or removed. This makes it consistent with lines where only parts of it were changed which use difflib.ndiff. And it fixes a crash if both texts are equal and not empty.
Also a minor change that the state which stores if it ends with the default color is now represented as a boolean.
Change-Id: Ic59df944b4c64b8536a5178e1aabc0b1adfeab47 --- M pywikibot/__init__.py M pywikibot/diff.py 2 files changed, 18 insertions(+), 65 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index d70dc86..fc1a708 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -9,7 +9,6 @@ __version__ = '$Id$'
import datetime -import difflib import math import re import sys @@ -49,6 +48,7 @@ from pywikibot.tools import UnicodeMixin, redirect_func from pywikibot.i18n import translate from pywikibot.data.api import UploadWarning +from pywikibot.diff import PatchManager import pywikibot.textlib as textlib import pywikibot.tools
@@ -602,60 +602,7 @@ The differences are highlighted (only on compatible systems) to show which changes were made. """ - # This is probably not portable to non-terminal interfaces.... - # For information on difflib, see http://pydoc.org/2.1/difflib.html - color = { - '+': 'lightgreen', - '-': 'lightred', - } - diff = u'' - colors = [] - # This will store the last line beginning with + or -. - lastline = None - # For testing purposes only: show original, uncolored diff - # for line in difflib.ndiff(oldtext.splitlines(), newtext.splitlines()): - # print line - for line in difflib.ndiff(oldtext.splitlines(), newtext.splitlines()): - if line.startswith('?'): - # initialize color vector with None, which means default color - lastcolors = [None for c in lastline] - # colorize the + or - sign - lastcolors[0] = color[lastline[0]] - # colorize changed parts in red or green - for i in range(min(len(line), len(lastline))): - if line[i] != ' ': - lastcolors[i] = color[lastline[0]] - diff += lastline + '\n' - # append one None (default color) for the newline character - colors += lastcolors + [None] - elif lastline: - diff += lastline + '\n' - # colorize the + or - sign only - lastcolors = [None for c in lastline] - lastcolors[0] = color[lastline[0]] - colors += lastcolors + [None] - lastline = None - if line[0] in ('+', '-'): - lastline = line - # there might be one + or - line left that wasn't followed by a ? line. - if lastline: - diff += lastline + '\n' - # colorize the + or - sign only - lastcolors = [None for c in lastline] - lastcolors[0] = color[lastline[0]] - colors += lastcolors + [None] - - result = u'' - lastcolor = None - for i in range(len(diff)): - if colors[i] != lastcolor: - if lastcolor is None: - result += '\03{%s}' % colors[i] - else: - result += '\03{default}' - lastcolor = colors[i] - result += diff[i] - output(result) + PatchManager(oldtext, newtext).print_hunks()
# Throttle and thread handling diff --git a/pywikibot/diff.py b/pywikibot/diff.py index 7ac30dc..e118770 100644 --- a/pywikibot/diff.py +++ b/pywikibot/diff.py @@ -77,15 +77,17 @@ return l
for tag, i1, i2, j1, j2 in self.group: + # equal/delete/insert add additional space after the sign as it's + # what difflib.ndiff does do too. if tag == 'equal': for line in self.a[i1:i2]: - yield ' ' + check_line(line) + yield ' ' + check_line(line) if tag in ('delete'): for line in self.a[i1:i2]: - yield '-' + check_line(line) + yield '- ' + check_line(line) if tag in ('insert'): for line in self.b[j1:j2]: - yield '+' + check_line(line) + yield '+ ' + check_line(line) if tag in ('replace'): for line in difflib.ndiff(self.a[i1:i2], self.b[j1:j2]): yield check_line(line) @@ -132,20 +134,20 @@ return line
colored_line = u'' - state = 'Close' + color_closed = True for char, char_ref in zip_longest(line, line_ref.strip(), fillvalue=' '): char_tagged = char - if state == 'Close': + if color_closed: if char_ref != ' ': char_tagged = '\03{%s}%s' % (self.colors[color], char) - state = 'Open' - elif state == 'Open': + color_closed = False + else: if char_ref == ' ': char_tagged = '\03{default}%s' % char - state = 'Close' + color_closed = True colored_line += char_tagged
- if state == 'Open': + if not color_closed: colored_line += '\03{default}'
return colored_line @@ -228,11 +230,15 @@
# there is a section of unchanged text at the end of a, b. if i2 < len(self.a): - rng = (-1, (last[2], len(self.a)), (-1, -1)) + rng = (-1, (i2, len(self.a)), (-1, -1)) blocks.append(rng)
return blocks
+ def print_hunks(self): + for hunk in self.hunks: + pywikibot.output(hunk.header + hunk.diff_text) + def review_hunks(self): "Review hunks."
pywikibot-commits@lists.wikimedia.org