Rev 623: Merge sanitize commit message patch from John. in file:///data/jelmer/bzr-gtk/sanitize_commit_messages/
Jelmer Vernooij
jelmer at samba.org
Tue Nov 25 15:25:58 GMT 2008
At file:///data/jelmer/bzr-gtk/sanitize_commit_messages/
------------------------------------------------------------
revno: 623
revision-id: jelmer at samba.org-20081125152552-3m6l42ab2u676caj
parent: jelmer at samba.org-20081107161737-q29iraxmifhkzn2p
parent: john at arbash-meinel.com-20081113065541-o9a9ygeu0v1n2rsb
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: sanitize_commit_messages
timestamp: Tue 2008-11-25 16:25:52 +0100
message:
Merge sanitize commit message patch from John.
added:
tests/test_revisionview.py test_revisionview.py-20081113063733-yjzw3fm2tldbx44f-1
modified:
commit.py commit.py-20060721181724-0mfkrqwpsa09q1t3-3
revisionview.py logview.py-20051024072750-4d5c28cb73611027
tests/__init__.py __init__.py-20070201155018-mi2dl3spgj7fqdum-1
tests/test_commit.py test_commit.py-20070928204312-v6ffg8vz27644log-2
------------------------------------------------------------
revno: 622.1.2
revision-id: john at arbash-meinel.com-20081113065541-o9a9ygeu0v1n2rsb
parent: john at arbash-meinel.com-20081113054835-8s7xth55j7kcexl3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: sanitize_commit_messages
timestamp: Thu 2008-11-13 00:55:41 -0600
message:
Add tests of RevisionView that it can handle broken file-info properties.
added:
tests/test_revisionview.py test_revisionview.py-20081113063733-yjzw3fm2tldbx44f-1
modified:
revisionview.py logview.py-20051024072750-4d5c28cb73611027
tests/__init__.py __init__.py-20070201155018-mi2dl3spgj7fqdum-1
tests/test_commit.py test_commit.py-20070928204312-v6ffg8vz27644log-2
------------------------------------------------------------
revno: 622.1.1
revision-id: john at arbash-meinel.com-20081113054835-8s7xth55j7kcexl3
parent: jelmer at samba.org-20081107161737-q29iraxmifhkzn2p
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: sanitize_commit_messages
timestamp: Wed 2008-11-12 23:48:35 -0600
message:
Ensure that per-file commit messages and global commit messages get sanitized.
modified:
commit.py commit.py-20060721181724-0mfkrqwpsa09q1t3-3
tests/test_commit.py test_commit.py-20070928204312-v6ffg8vz27644log-2
=== modified file 'commit.py'
--- a/commit.py 2008-09-29 16:10:51 +0000
+++ b/commit.py 2008-11-13 05:48:35 +0000
@@ -97,6 +97,13 @@
return pm
+_newline_variants_re = re.compile(r'\r\n?')
+def _sanitize_and_decode_message(utf8_message):
+ """Turn a utf-8 message into a sanitized Unicode message."""
+ fixed_newline = _newline_variants_re.sub('\n', utf8_message)
+ return fixed_newline.decode('utf-8')
+
+
class CommitDialog(gtk.Dialog):
"""Implementation of Commit."""
@@ -631,10 +638,12 @@
if self._commit_all_changes or record[2]:# [2] checkbox
file_id = record[0] # [0] file_id
path = record[1] # [1] real path
- file_message = record[5] # [5] commit message
+ # [5] commit message
+ file_message = _sanitize_and_decode_message(record[5])
files.append(path.decode('UTF-8'))
if self._enable_per_file_commits and file_message:
# All of this needs to be utf-8 information
+ file_message = file_message.encode('UTF-8')
file_info.append({'path':path, 'file_id':file_id,
'message':file_message})
file_info.sort(key=lambda x:(x['path'], x['file_id']))
@@ -712,7 +721,8 @@
def _get_global_commit_message(self):
buf = self._global_message_text_view.get_buffer()
start, end = buf.get_bounds()
- return buf.get_text(start, end).decode('utf-8')
+ text = buf.get_text(start, end)
+ return _sanitize_and_decode_message(text)
def _set_global_commit_message(self, message):
"""Just a helper for the test suite."""
=== modified file 'revisionview.py'
--- a/revisionview.py 2008-07-11 15:46:32 +0000
+++ b/revisionview.py 2008-11-13 06:55:41 +0000
@@ -22,6 +22,7 @@
import gobject
import webbrowser
+from bzrlib import trace
from bzrlib.osutils import format_date
from bzrlib.util.bencode import bdecode
from bzrlib.testament import Testament
@@ -422,10 +423,15 @@
self._add_parents_or_children(revision.parent_ids,
self.parents_widgets,
self.parents_table)
-
+
file_info = revision.properties.get('file-info', None)
if file_info is not None:
- file_info = bdecode(file_info.encode('UTF-8'))
+ try:
+ file_info = bdecode(file_info.encode('UTF-8'))
+ except ValueError:
+ trace.note('Invalid per-file info for revision:%s, value: %r',
+ revision.revision_id, file_info)
+ file_info = None
if file_info:
if self._file_id is None:
=== modified file 'tests/__init__.py'
--- a/tests/__init__.py 2008-06-29 22:44:42 +0000
+++ b/tests/__init__.py 2008-11-13 06:55:41 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Jelmer Vernooij <jelmer at samba.org>
+# Copyright (C) 2007, 2008 Jelmer Vernooij <jelmer at samba.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -27,9 +27,10 @@
testmod_names = [
'test_commit',
'test_diff',
+ 'test_history',
'test_linegraph',
'test_preferences',
- 'test_history',
+ 'test_revisionview',
]
result.addTest(loader.loadTestsFromModuleNames(["%s.%s" % (__name__, i) for i in testmod_names]))
=== modified file 'tests/test_commit.py'
--- a/tests/test_commit.py 2008-09-29 16:10:51 +0000
+++ b/tests/test_commit.py 2008-11-13 06:55:41 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 John Arbash Meinel <john at arbash-meinel.com>
+# Copyright (C) 2007, 2008 John Arbash Meinel <john at arbash-meinel.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -644,6 +644,28 @@
'message':'message\nfor b_dir\n'},
]), dlg._get_specific_files())
+ def test_specific_files_sanitizes_messages(self):
+ tree = self.make_branch_and_tree('tree')
+ tree.branch.get_config().set_user_option('per_file_commits', 'true')
+ self.build_tree(['tree/a_file', 'tree/b_dir/'])
+ tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
+
+ dlg = commit.CommitDialog(tree)
+ dlg._commit_selected_radio.set_active(True)
+ self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
+
+ dlg._treeview_files.set_cursor((1,))
+ dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
+ dlg._treeview_files.set_cursor((2,))
+ dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
+
+ self.assertEqual((['a_file', 'b_dir'],
+ [{'path':'a_file', 'file_id':'1a-id',
+ 'message':'Test\nmessage\nfor a_file\n'},
+ {'path':'b_dir', 'file_id':'0b-id',
+ 'message':'message\nfor\nb_dir\n'},
+ ]), dlg._get_specific_files())
+
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
"""Tests on the actual 'commit' button being pushed."""
@@ -687,6 +709,21 @@
self.assertEqual(last_rev, dlg.committed_revision_id)
self.assertEqual(rev_id1, tree.branch.last_revision())
+ def test_commit_global_sanitizes_message(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/a'])
+ tree.add(['a'], ['a-id'])
+ rev_id1 = tree.commit('one')
+
+ self.build_tree(['tree/b'])
+ tree.add(['b'], ['b-id'])
+ dlg = commit.CommitDialog(tree)
+ # With the check box set, it should only effect the local branch
+ dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
+ dlg._do_commit()
+ rev = tree.branch.repository.get_revision(tree.last_revision())
+ self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
+
def test_bound_commit_both(self):
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/a'])
@@ -1030,3 +1067,22 @@
{'path':u'\u03a9', 'file_id':'omega-id',
'message':u'\u03a9 is the end of all things.\n'},
], file_info_decoded)
+
+
+class TestSanitizeMessage(tests.TestCase):
+
+ def assertSanitize(self, expected, original):
+ self.assertEqual(expected,
+ commit._sanitize_and_decode_message(original))
+
+ def test_untouched(self):
+ self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
+
+ def test_converts_cr_to_lf(self):
+ self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
+
+ def test_converts_crlf_to_lf(self):
+ self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
+
+ def test_converts_mixed_to_lf(self):
+ self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
=== added file 'tests/test_revisionview.py'
--- a/tests/test_revisionview.py 1970-01-01 00:00:00 +0000
+++ b/tests/test_revisionview.py 2008-11-13 06:55:41 +0000
@@ -0,0 +1,92 @@
+# Copyright (C) 2007, 2008 John Arbash Meinel <john at arbash-meinel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Test the RevisionView functionality."""
+
+import os
+
+import gtk
+
+from bzrlib import (
+ tests,
+ revision,
+ )
+from bzrlib.util import bencode
+
+from bzrlib.plugins.gtk import revisionview
+
+
+class TestPendingRevisions(tests.TestCaseWithMemoryTransport):
+
+ def assertBufferText(self, text, buffer):
+ """Check the text stored in the buffer."""
+ self.assertEqual(text, buffer.get_text(buffer.get_start_iter(),
+ buffer.get_end_iter()))
+
+ def test_create_view(self):
+ builder = self.make_branch_builder('test')
+ builder.build_snapshot('A', None,
+ [('add', ('', 'root-id', 'directory', None))])
+ b = builder.get_branch()
+
+ rv = revisionview.RevisionView(b)
+ rev = b.repository.get_revision('A')
+ rv.set_revision(rev)
+ self.assertEqual(rev.committer, rv.committer.get_text())
+ self.assertFalse(rv.author.get_property('visible'))
+ self.assertFalse(rv.author_label.get_property('visible'))
+ self.assertFalse(rv.file_info_box.get_property('visible'))
+
+ def test_create_view_with_file_info(self):
+ tree = self.make_branch_and_memory_tree('test')
+ file_info = bencode.bencode([{'file_id':'root-id', 'path':'',
+ 'message':'test-message\n'}])
+ tree.lock_write()
+ try:
+ tree.add([''], ['root-id'])
+ tree.commit('test', rev_id='A', revprops={'file-info': file_info})
+ finally:
+ tree.unlock()
+ b = tree.branch
+
+ rv = revisionview.RevisionView(b)
+ rev = b.repository.get_revision('A')
+ rv.set_revision(rev)
+
+ self.assertEqual(rev.committer, rv.committer.get_text())
+ self.assertTrue(rv.file_info_box.get_property('visible'))
+ self.assertBufferText('\ntest-message\n', rv.file_info_buffer)
+
+ def test_create_view_with_broken_file_info(self):
+ tree = self.make_branch_and_memory_tree('test')
+ # This should be 'message13:'
+ file_info = 'ld7:file_id7:root-id7:message11:test-message\n4:path0:ee'
+ tree.lock_write()
+ try:
+ tree.add([''], ['root-id'])
+ tree.commit('test', rev_id='A', revprops={'file-info': file_info})
+ finally:
+ tree.unlock()
+ b = tree.branch
+
+ rv = revisionview.RevisionView(b)
+ rev = b.repository.get_revision('A')
+ rv.set_revision(rev)
+
+ self.assertEqual(rev.committer, rv.committer.get_text())
+ self.assertFalse(rv.file_info_box.get_property('visible'))
+ log = self._get_log(True)
+ self.assertContainsRe(log, 'Invalid per-file info for revision:A')
More information about the bazaar-commits
mailing list