[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] mailer.py : Use python difflib.unified_diff instead of *nix diff command

From: Noorul Islam K M <noorul_at_collab.net>
Date: Fri, 05 Nov 2010 21:45:36 +0530

The idea is from Kamesh. Attached is the patch which I think implements
the idea in a way but with an issue.

First, the patch:

Log

[[[

If diff command does not exist on the system then use
difflib.unified_diff() to generate diff contents.

* tools/hook-scripts/mailer/mailer.py: Fall back to
  difflib.unified_diff() if the script fails to execute native 'diff'
  command.

Patch by: Noorul Islam K M <noorul{_AT_}collab.net>
Suggested by: Kamesh Jayachandran <kamesh{_AT_}collab.net>

]]]

Now the issue:

difflib.unified_diff() produces a bit different output from that of
'diff' command. The attached python script can be used to generate diffs
using difflib. I did try different combinations of creating patches and
applying patches, all of them worked fine. I am not sure whether this
difference in output can be ignored.

Thanks and Regards
Noorul

Index: hook-scripts/mailer/mailer.py
===================================================================
--- hook-scripts/mailer/mailer.py (revision 1031409)
+++ hook-scripts/mailer/mailer.py (working copy)
@@ -866,12 +866,16 @@
           content = src_fname = dst_fname = None
         else:
           src_fname, dst_fname = diff.get_files()
- content = DiffContent(self.cfg.get_diff_cmd(self.group, {
- 'label_from' : label1,
- 'label_to' : label2,
- 'from' : src_fname,
- 'to' : dst_fname,
- }))
+ try:
+ content = DiffContent(self.cfg.get_diff_cmd(self.group, {
+ 'label_from' : label1,
+ 'label_to' : label2,
+ 'from' : src_fname,
+ 'to' : dst_fname,
+ }))
+ except OSError:
+ # diff command does not exist, try difflib.unified_diff()
+ content = DifflibDiffContent(label1, label2, src_fname, dst_fname)
 
       # return a data item for this diff
       return _data(
@@ -946,7 +950,57 @@
       type=ltype,
       )
 
+class DifflibDiffContent():
+ "This is a generator-like object returning annotated lines of a diff."
 
+ def __init__(self, label_from, label_to, from_file, to_file):
+ import difflib
+ self.seen_change = False
+ fromlines = open(from_file, 'U').readlines()
+ tolines = open(to_file, 'U').readlines()
+ self.diff = difflib.unified_diff(fromlines, tolines,
+ label_from, label_to)
+
+ def __nonzero__(self):
+ # we always have some items
+ return True
+
+ def __getitem__(self, idx):
+
+ try:
+ line = self.diff.next()
+ except StopIteration:
+ raise IndexError
+
+ # classify the type of line.
+ first = line[:1]
+ if first == '@':
+ self.seen_change = True
+ ltype = 'H'
+ elif first == '-':
+ if self.seen_change:
+ ltype = 'D'
+ else:
+ ltype = 'F'
+ elif first == '+':
+ if self.seen_change:
+ ltype = 'A'
+ else:
+ ltype = 'T'
+ elif first == ' ':
+ ltype = 'C'
+ else:
+ ltype = 'U'
+
+ if line[-2] == '\r':
+ line=line[0:-2] + '\n' # remove carriage return
+
+ return _data(
+ raw=line,
+ text=line[1:-1], # remove indicator and newline
+ type=ltype,
+ )
+
 class TextCommitRenderer:
   "This class will render the commit mail in plain text."
 

  • text/x-python attachment: stored
Received on 2010-11-05 17:16:36 CET

This is an archived mail posted to the Subversion Dev mailing list.