* viewvc.py
(DiffDescription): Add support for property diffs. (diff_side_item): Store properties hash in the side items. (view_diff): Generate property diffs. * diff_display.ezt (headers): Indicate the property being diffed, if applicable. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/property-diff@2624 8cb11bc2-c004-0410-86c3-e597b4017df7remotes/property-diff
parent
4fe882972a
commit
90a1d6cae2
|
@ -3281,6 +3281,10 @@ def diff_side_item(request, path_comp, rev, sym):
|
|||
i_content.annotate_href = fvi.annotate_href
|
||||
i_content.revision_href = fvi.revision_href
|
||||
i_content.prefer_markup = fvi.prefer_markup
|
||||
|
||||
# Property diff item has properties hash, naturally. Content item doesn't.
|
||||
i_content.properties = None
|
||||
i_prop.properties = request.repos.itemprops(path_comp, rev)
|
||||
return i_content, i_prop
|
||||
|
||||
|
||||
|
@ -3362,6 +3366,31 @@ class DiffDescription:
|
|||
self._get_diff(left, right, self._content_lines, self._content_fp,
|
||||
options, None)
|
||||
|
||||
def get_prop_diff(self, left, right):
|
||||
options = {}
|
||||
if self.context != -1:
|
||||
options['context'] = self.context
|
||||
if self.human_readable:
|
||||
cfg = self.request.cfg
|
||||
self.diff_options['ignore_white'] = cfg.options.hr_ignore_white
|
||||
for name in self._uniq(left.properties.keys() + right.properties.keys()):
|
||||
# Skip non-utf8 property names
|
||||
if is_undisplayable(name):
|
||||
continue
|
||||
val_left = left.properties.get(name, '')
|
||||
val_right = right.properties.get(name, '')
|
||||
# Skip non-changed properties
|
||||
if val_left == val_right:
|
||||
continue
|
||||
# Check for binary properties
|
||||
if is_undisplayable(val_left) or is_undisplayable(val_right):
|
||||
self.changes.append(_item(left=left, right=right,
|
||||
display_as=self.display_as,
|
||||
changes=[ _item(type=_RCSDIFF_IS_BINARY) ],
|
||||
propname=name))
|
||||
continue
|
||||
self._get_diff(left, right, self._prop_lines, self._prop_fp, options, name)
|
||||
|
||||
def _get_diff(self, left, right, get_lines, get_fp, options, propname):
|
||||
if self.fp_differ is not None:
|
||||
fp = get_fp(left, right, propname, options)
|
||||
|
@ -3381,7 +3410,9 @@ class DiffDescription:
|
|||
|
||||
def _fp_vclib_hr(self, left, right, fp, propname):
|
||||
date1, date2, flag, headers = diff_parse_headers(fp, self.diff_type,
|
||||
left.path, right.path, left.rev, right.rev, left.tag, right.tag)
|
||||
self._property_path(left, propname),
|
||||
self._property_path(right, propname),
|
||||
left.rev, right.rev, left.tag, right.tag)
|
||||
if flag is not None:
|
||||
return [ _item(type=flag) ]
|
||||
else:
|
||||
|
@ -3389,7 +3420,9 @@ class DiffDescription:
|
|||
|
||||
def _fp_vclib_raw(self, left, right, fp, propname):
|
||||
date1, date2, flag, headers = diff_parse_headers(fp, self.diff_type,
|
||||
left.path, right.path, left.rev, right.rev, left.tag, right.tag)
|
||||
self._property_path(left, propname),
|
||||
self._property_path(right, propname),
|
||||
left.rev, right.rev, left.tag, right.tag)
|
||||
if flag is not None:
|
||||
return _item(type=flag)
|
||||
else:
|
||||
|
@ -3407,6 +3440,42 @@ class DiffDescription:
|
|||
return self.request.repos.rawdiff(left.path_comp, left.rev,
|
||||
right.path_comp, right.rev, self.diff_type, options)
|
||||
|
||||
def _prop_lines(self, side, propname):
|
||||
val = side.properties.get(propname, '')
|
||||
return val.splitlines()
|
||||
|
||||
def _prop_fp(self, left, right, propname, options):
|
||||
fn_left = self._temp_file(left.properties.get(propname))
|
||||
fn_right = self._temp_file(right.properties.get(propname))
|
||||
diff_args = vclib._diff_args(self.diff_type, options)
|
||||
info_left = self._property_path(left, propname), left.log_entry.date, left.rev
|
||||
info_right = self._property_path(right, propname), right.log_entry.date, right.rev
|
||||
return vclib._diff_fp(fn_left, fn_right, info_left, info_right,
|
||||
self.request.cfg.utilities.diff or 'diff', diff_args)
|
||||
|
||||
def _temp_file(self, val):
|
||||
'''Create a temporary file with content from val'''
|
||||
fn = tempfile.mktemp()
|
||||
fp = open(fn, "wb")
|
||||
if val:
|
||||
fp.write(val)
|
||||
fp.close()
|
||||
return fn
|
||||
|
||||
def _uniq(self, lst):
|
||||
'''Determine unique set of list elements'''
|
||||
h = {}
|
||||
for e in lst:
|
||||
h[e] = 1
|
||||
return sorted(h.keys())
|
||||
|
||||
def _property_path(self, side, propname):
|
||||
'''Return path to be displayed in raw diff - possibly augmented with property name'''
|
||||
if propname is None:
|
||||
return side.path
|
||||
else:
|
||||
return "%s:property(%s)" % (side.path, propname)
|
||||
|
||||
|
||||
def view_diff(request):
|
||||
if 'diff' not in request.cfg.options.allowed_views:
|
||||
|
@ -3430,6 +3499,9 @@ def view_diff(request):
|
|||
# Get file content diff
|
||||
desc.get_content_diff(left_side_content, right_side_content)
|
||||
|
||||
# Get property list and diff each property
|
||||
desc.get_prop_diff(left_side_prop, right_side_prop)
|
||||
|
||||
except vclib.InvalidRevision:
|
||||
raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
|
||||
'to diff', '400 Bad Request')
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
[define right_view_href][if-any diff.right.prefer_markup][diff.right.view_href][else][if-any diff.right.download_href][diff.right.download_href][end][end][end]
|
||||
|
||||
[define left_header][is diff.left.path diff.right.path][else][diff.left.path]<br/>[end]
|
||||
[if-any diff.propname]Property: <em>[diff.propname]</em><br/>[end]
|
||||
Revision [if-any left_view_href]<a href="[left_view_href]">[end][diff.left.rev][if-any left_view_href]</a>[end][if-any diff.left.author] by <em>[diff.left.author]</em>[end],
|
||||
[diff.left.date]
|
||||
[if-any diff.left.tag]<br/>Tag: [diff.left.tag][end][end]
|
||||
|
||||
[define right_header][is diff.right.path diff.left.path][else][diff.right.path]<br/>[end]
|
||||
[if-any diff.propname]Property: <em>[diff.propname]</em><br/>[end]
|
||||
Revision [if-any right_view_href]<a href="[right_view_href]">[end][diff.right.rev][if-any right_view_href]</a>[end][if-any diff.right.author] by <em>[diff.right.author]</em>[end],
|
||||
[diff.right.date]
|
||||
[if-any diff.right.tag]<br/>Tag: [diff.right.tag][end][end]
|
||||
|
|
Loading…
Reference in New Issue