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