Rev 4233: Integrated EOL conversion support (Ian Clatworthy) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Apr 2 06:32:34 BST 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4233
revision-id: pqm at pqm.ubuntu.com-20090402053229-w8oy2wc2dpahfph9
parent: pqm at pqm.ubuntu.com-20090401151438-hqulqoazddtacbls
parent: ian.clatworthy at canonical.com-20090402041211-jl6u7r4r5inw9p2h
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-04-02 06:32:29 +0100
message:
  Integrated EOL conversion support (Ian Clatworthy)
added:
  bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
  bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
  bzrlib/tests/test_eol_filters.py test_eol_filters.py-20090327060429-todzdjmqt3bpv5r8-2
  bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
    ------------------------------------------------------------
    revno: 4232.1.1
    revision-id: ian.clatworthy at canonical.com-20090402041211-jl6u7r4r5inw9p2h
    parent: pqm at pqm.ubuntu.com-20090401151438-hqulqoazddtacbls
    parent: ian.clatworthy at canonical.com-20090402022228-eez3xvn4gvs3xbva
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Thu 2009-04-02 14:12:11 +1000
    message:
      Integrated EOL conversion support (Ian Clatworthy)
    added:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/test_eol_filters.py test_eol_filters.py-20090327060429-todzdjmqt3bpv5r8-2
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
    ------------------------------------------------------------
    revno: 4208.4.8
    revision-id: ian.clatworthy at canonical.com-20090402022228-eez3xvn4gvs3xbva
    parent: ian.clatworthy at canonical.com-20090401045146-vh1wo8t27o1o4lzp
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Thu 2009-04-02 12:22:28 +1000
    message:
      more help tweaks
    modified:
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
    ------------------------------------------------------------
    revno: 4208.4.7
    revision-id: ian.clatworthy at canonical.com-20090401045146-vh1wo8t27o1o4lzp
    parent: ian.clatworthy at canonical.com-20090401023815-772ygk8xx8ml4e31
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Wed 2009-04-01 14:51:46 +1000
    message:
      tweak eol names based on mailing list discussion
    modified:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    ------------------------------------------------------------
    revno: 4208.4.6
    revision-id: ian.clatworthy at canonical.com-20090401023815-772ygk8xx8ml4e31
    parent: ian.clatworthy at canonical.com-20090329010922-5cf8sgtz2cvs8k0m
    parent: pqm at pqm.ubuntu.com-20090401021937-weq1st849rreuonn
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Wed 2009-04-01 12:38:15 +1000
    message:
      merge bzr.dev r4225
    modified:
      .bzrignore                     bzrignore-20050311232317-81f7b71efa2db11a
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/filters/__init__.py     __init__.py-20080416080515-mkxl29amuwrf6uir-2
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
      bzrlib/tests/blackbox/test_filtered_view_ops.py test_filtered_view_o-20081110012645-5t7ogtola0l33lkg-1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/test_commit.py    test_commit.py-20050914060732-279f057f8c295434
      bzrlib/tests/test_diff.py      testdiff.py-20050727164403-d1a3496ebb12e339
      bzrlib/tests/test_filters.py   test_filters.py-20080417120614-tc3zok0vvvprsc99-1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_upgrade.py   test_upgrade.py-20051004040251-555fe1d2bae1bc71
      bzrlib/tests/workingtree_implementations/test_commit.py test_commit.py-20060421013633-1610ec2331c8190f
      bzrlib/upgrade.py              history2weaves.py-20050818063535-e7d319791c19a8b2
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      doc/en/user-guide/browsing_history.txt browsing_history.txt-20071121073725-0corxykv5irjal00-2
    ------------------------------------------------------------
    revno: 4208.4.5
    revision-id: ian.clatworthy at canonical.com-20090329010922-5cf8sgtz2cvs8k0m
    parent: ian.clatworthy at canonical.com-20090328142427-xgi03v1s0sm1o0cd
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Sun 2009-03-29 11:09:22 +1000
    message:
      add lf-always and crlf-always
    modified:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    ------------------------------------------------------------
    revno: 4208.4.4
    revision-id: ian.clatworthy at canonical.com-20090328142427-xgi03v1s0sm1o0cd
    parent: ian.clatworthy at canonical.com-20090328080911-fwbaaay1qldnvc3f
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Sun 2009-03-29 00:24:27 +1000
    message:
      unix/window -> cr/crlf based on mailing list feedback
    modified:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    ------------------------------------------------------------
    revno: 4208.4.3
    revision-id: ian.clatworthy at canonical.com-20090328080911-fwbaaay1qldnvc3f
    parent: ian.clatworthy at canonical.com-20090327142926-ue4pibsolzsd847l
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Sat 2009-03-28 18:09:11 +1000
    message:
      rename dos to windows
    modified:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    ------------------------------------------------------------
    revno: 4208.4.2
    revision-id: ian.clatworthy at canonical.com-20090327142926-ue4pibsolzsd847l
    parent: ian.clatworthy at canonical.com-20090327142225-0pvkc1n021nw8301
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Sat 2009-03-28 00:29:26 +1000
    message:
      tweak help
    modified:
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
    ------------------------------------------------------------
    revno: 4208.4.1
    revision-id: ian.clatworthy at canonical.com-20090327142225-0pvkc1n021nw8301
    parent: pqm at pqm.ubuntu.com-20090326131816-4nzmlssnd4huc5cu
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.eol
    timestamp: Sat 2009-03-28 00:22:25 +1000
    message:
      eol conversion support
    added:
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/tests/test_eol_filters.py test_eol_filters.py-20090327060429-todzdjmqt3bpv5r8-2
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
=== modified file 'NEWS'
--- a/NEWS	2009-04-01 10:22:33 +0000
+++ b/NEWS	2009-04-02 04:12:11 +0000
@@ -59,6 +59,10 @@
   trees). See ``bzr help content-filters`` for further details.
   (Ian Clatworthy, Alexander Belchenko)
 
+* End-of-line conversion is now supported for formats supporting
+  content filtering. See ``bzr help eol`` for details.
+  (Ian Clatworthy)
+
 Improvements
 ************
 

=== added file 'bzrlib/filters/eol.py'
--- a/bzrlib/filters/eol.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/filters/eol.py	2009-04-01 04:51:46 +0000
@@ -0,0 +1,67 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""End of Line Conversion filters.
+
+See bzr help eol for details.
+"""
+
+
+import re, sys
+
+from bzrlib import filters
+
+
+# Real Linux/Unix/OSX newline - \n without \r before it
+_LINUX_NL_RE = re.compile(r'(?<!\r)\n')
+
+
+def _to_lf_converter(chunks, context=None):
+    """A content file that converts crlf to lf."""
+    content = ''.join(chunks)
+    if '\x00' in content:
+        return [content]
+    else:
+        return [content.replace('\r\n', '\n')]
+
+
+def _to_crlf_converter(chunks, context=None):
+    """A content file that converts lf to crlf."""
+    content = ''.join(chunks)
+    if '\x00' in content:
+        return [content]
+    else:
+        return [_LINUX_NL_RE.sub('\r\n', content)]
+
+
+# Define and register the EOL filter stacks
+if sys.platform == 'win32':
+    _native_output = _to_crlf_converter
+else:
+    _native_output = _to_lf_converter
+_eol_filter_stack_map = {
+    'exact': [],
+    'native': [filters.ContentFilter(_to_lf_converter, _native_output)],
+    'lf':     [filters.ContentFilter(_to_lf_converter, _to_lf_converter)],
+    'crlf':   [filters.ContentFilter(_to_lf_converter, _to_crlf_converter)],
+    'native-with-crlf-in-repo':
+        [filters.ContentFilter(_to_crlf_converter, _native_output)],
+    'lf-with-crlf-in-repo':
+        [filters.ContentFilter(_to_crlf_converter, _to_lf_converter)],
+    'crlf-with-crlf-in-repo':
+        [filters.ContentFilter(_to_crlf_converter, _to_crlf_converter)],
+    }
+filters.register_filter_stack_map('eol', _eol_filter_stack_map)

=== modified file 'bzrlib/help_topics/__init__.py'
--- a/bzrlib/help_topics/__init__.py	2009-03-28 01:27:54 +0000
+++ b/bzrlib/help_topics/__init__.py	2009-04-02 04:12:11 +0000
@@ -745,6 +745,9 @@
 topic_registry.register('content-filters', _load_from_file,
                         'Conversion of content into/from working trees',
                         SECT_CONCEPT)
+topic_registry.register('eol', _load_from_file,
+                        'Information on end-of-line handling',
+                        SECT_CONCEPT)
 topic_registry.register('formats', _storage_formats,
                         'Information on choosing a storage format',
                         SECT_CONCEPT)

=== added file 'bzrlib/help_topics/en/eol.txt'
--- a/bzrlib/help_topics/en/eol.txt	1970-01-01 00:00:00 +0000
+++ b/bzrlib/help_topics/en/eol.txt	2009-04-02 04:12:11 +0000
@@ -0,0 +1,114 @@
+End of Line Conversion
+======================
+
+EOL conversion is provided as a content filter where Bazaar internally
+stores a canonical format but outputs a convenience format. See
+``bzr help content-filters`` for general information about using these.
+
+Note: Content filtering is only supported in recently added formats,
+e.g. 1.14.
+
+EOL conversion needs to be enabled for selected branches and files using
+rules. See ``bzr help rules`` for general information on defining rules.
+
+To configure which files to filter, set ``eol`` to one of the values below.
+(If a value is not set, ``exact`` is the default.)
+
+ ============== ============================== ======================
+ Value          Checkout end-of-lines as       Commit end-of-lines as
+ ============== ============================== ======================
+ native         crlf on Windows, lf otherwise  lf
+ -------------- ------------------------------ ----------------------
+ lf             lf                             lf
+ -------------- ------------------------------ ----------------------
+ crlf           crlf                           lf
+ -------------- ------------------------------ ----------------------
+ exact          No conversion                  exactly as in file
+ ============== ============================== ======================
+
+Note: For safety reasons, no conversion is applied to any file where a null
+byte is detected in the file.
+
+For users working on a cross-platform project, here is a suggested rule
+to use as a starting point::
+
+  [name *]
+  eol = native
+
+If you have binary files that do not contain a null byte though, be
+sure to add ``eol = exact`` rules for those as well. You can do this
+by giving more explicit patterns earlier in the rules file. For example::
+
+  [name *.png]
+  eol = exact
+
+  [name *]
+  eol = native
+
+If your working tree is on a network drive shared by users on different
+operating systems, you typically want to force certain conventions for
+certain files. In that way, if a file is created with the wrong line
+endings or line endings get mixed during editing, it gets committed
+correctly and gets checked out correctly. For example::
+
+  [name *.bat]
+  eol = crlf
+
+  [name *.sh]
+  eol = lf
+
+  [name *]
+  eol = native
+
+If you take the care to create files with their required endings, you can
+achieve *almost* the same thing by using ``eol = exact``. It is slightly
+safer to use ``lf`` and ``crlf`` though because edits accidentally
+introducing mixed line endings will be corrected during commit for files
+with those settings.
+
+If you have sample test data that deliberately has text files with mixed
+newline conventions, you can ask for those to be left alone like this::
+
+  [name test_data/]
+  eol = exact
+
+  [name *]
+  eol = native
+
+Note that ``exact`` does not imply the file is binary but it does mean
+that no conversion of end-of-lines will be done. (Bazaar currently relies
+of content analysis to detect binary files for commands like ``diff``.
+In the future, a ``binary = true`` rule may be added but it is not
+supported yet.)
+
+If you have an existing repository with text files already stored using
+Windows newline conventions (crlf), then you may want to keep using that
+convention in the repository. Forcing certain files to this convention
+may also help users who do not have rules configured. To do this, set
+``eol`` to one of the values below.
+
+ ========================= ============================== ======================
+ Value                     Checkout end-of-lines as       Commit end-of-lines as
+ ========================= ============================== ======================
+ native-with-crlf-in-repo  crlf on Windows, lf otherwise  crlf
+ ------------------------- ------------------------------ ----------------------
+ lf-with-crlf-in-repo      lf                             crlf
+ ------------------------- ------------------------------ ----------------------
+ crlf-with-crlf-in-repo    crlf                           crlf
+ ========================= ============================== ======================
+
+For users working on an existing project that uses Windows newline
+conventions in their Bazaar repository, this rule is suggested as a
+starting point::
+
+  [name *]
+  eol = native-with-crlf-in-repo
+
+For new projects, it is recommended that end-of-lines be stored as lf
+and that users stick to the basic settings, i.e. ``native``, ``lf``,
+``crlf`` and ``exact``.
+
+Note: Bazaar's EOL conversion will convert the content of files but
+never reject files because a given line ending or mixed line endings
+are found. A precommit hook should be used if you wish to validate
+(and not just convert) content before committing.

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-04-01 11:31:54 +0000
+++ b/bzrlib/tests/__init__.py	2009-04-02 04:12:11 +0000
@@ -3317,6 +3317,7 @@
                    'bzrlib.tests.test_directory_service',
                    'bzrlib.tests.test_dirstate',
                    'bzrlib.tests.test_email_message',
+                   'bzrlib.tests.test_eol_filters',
                    'bzrlib.tests.test_errors',
                    'bzrlib.tests.test_export',
                    'bzrlib.tests.test_extract',

=== added file 'bzrlib/tests/test_eol_filters.py'
--- a/bzrlib/tests/test_eol_filters.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_eol_filters.py	2009-04-02 04:12:11 +0000
@@ -0,0 +1,39 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for eol conversion."""
+
+
+from bzrlib.filters.eol import (
+    _to_crlf_converter,
+    _to_lf_converter,
+    )
+from bzrlib.tests import TestCase
+
+
+# Sample files
+_sample_file1 = """hello\nworld\r\n"""
+
+
+class TestEolFilters(TestCase):
+
+    def test_to_lf(self):
+        result = _to_lf_converter([_sample_file1])
+        self.assertEqual(["hello\nworld\n"], result)
+
+    def test_to_crlf(self):
+        result = _to_crlf_converter([_sample_file1])
+        self.assertEqual(["hello\r\nworld\r\n"], result)

=== modified file 'bzrlib/tests/workingtree_implementations/__init__.py'
--- a/bzrlib/tests/workingtree_implementations/__init__.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/workingtree_implementations/__init__.py	2009-03-27 14:22:25 +0000
@@ -79,6 +79,7 @@
         'bzrlib.tests.workingtree_implementations.test_changes_from',
         'bzrlib.tests.workingtree_implementations.test_content_filters',
         'bzrlib.tests.workingtree_implementations.test_commit',
+        'bzrlib.tests.workingtree_implementations.test_eol_conversion',
         'bzrlib.tests.workingtree_implementations.test_executable',
         'bzrlib.tests.workingtree_implementations.test_flush',
         'bzrlib.tests.workingtree_implementations.test_get_file_with_stat',

=== added file 'bzrlib/tests/workingtree_implementations/test_eol_conversion.py'
--- a/bzrlib/tests/workingtree_implementations/test_eol_conversion.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_eol_conversion.py	2009-04-02 04:12:11 +0000
@@ -0,0 +1,185 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for eol conversion."""
+
+import sys
+
+from bzrlib import rules
+from bzrlib.tests import TestSkipped
+from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
+from bzrlib.workingtree import WorkingTree
+
+
+# Sample files
+_sample_text         = """hello\nworld\r\n"""
+_sample_text_on_win  = """hello\r\nworld\r\n"""
+_sample_text_on_unix = """hello\nworld\n"""
+_sample_binary       = """hello\nworld\r\n\x00"""
+
+
+class TestEolConversion(TestCaseWithWorkingTree):
+
+    def setUp(self):
+        # formats that don't support content filtering can skip these tests
+        fmt = self.workingtree_format
+        f = getattr(fmt, 'supports_content_filtering')
+        if f is None:
+            raise TestSkipped("format %s doesn't declare whether it "
+                "supports content filtering, assuming not" % fmt)
+        if not f():
+            raise TestSkipped("format %s doesn't support content filtering"
+                % fmt)
+        TestCaseWithWorkingTree.setUp(self)
+
+    def patch_rules_searcher(self, eol):
+        """Patch in a custom rules searcher with a given eol setting."""
+        if eol is None:
+            WorkingTree._get_rules_searcher = self.real_rules_searcher
+        else:
+            def custom_eol_rules_searcher(tree, default_searcher):
+                return rules._IniBasedRulesSearcher([
+                    '[name *]\n',
+                    'eol=%s\n' % eol,
+                    ])
+            WorkingTree._get_rules_searcher = custom_eol_rules_searcher
+
+    def prepare_tree(self, content, eol=None):
+        """Prepare a working tree and commit some content."""
+        def restore_real_rules_searcher():
+            WorkingTree._get_rules_searcher = self.real_rules_searcher
+        self.real_rules_searcher = WorkingTree._get_rules_searcher
+        self.addCleanup(restore_real_rules_searcher)
+        self.patch_rules_searcher(eol)
+        t = self.make_branch_and_tree('tree1')
+        self.build_tree_contents([('tree1/file1', content)])
+        t.add('file1', 'file1-id')
+        t.commit("add file1")
+        basis = t.basis_tree()
+        basis.lock_read()
+        self.addCleanup(basis.unlock)
+        return t, basis
+
+    def assertNewContentForSetting(self, wt, eol, expected_unix,
+        expected_win=None):
+        """Clone a working tree and check the convenience content."""
+        if expected_win is None:
+            expected_win = expected_unix
+        self.patch_rules_searcher(eol)
+        wt2 = wt.bzrdir.sprout('tree-%s' % eol).open_workingtree()
+        # To see exactly what got written to disk, we need an unfiltered read
+        content = wt2.get_file('file1-id', filtered=False).read()
+        if sys.platform == 'win32':
+            self.assertEqual(expected_win, content)
+        else:
+            self.assertEqual(expected_unix, content)
+
+    def assertContent(self, wt, basis, expected_raw, expected_unix,
+        expected_win):
+        """Check the committed content and content in cloned trees."""
+        basis_content = basis.get_file('file1-id').read()
+        self.assertEqual(expected_raw, basis_content)
+        self.assertNewContentForSetting(wt, None, expected_raw)
+        self.assertNewContentForSetting(wt, 'native',
+            expected_unix, expected_win)
+        self.assertNewContentForSetting(wt, 'lf',
+            expected_unix, expected_unix)
+        self.assertNewContentForSetting(wt, 'crlf',
+            expected_win, expected_win)
+        self.assertNewContentForSetting(wt, 'native-with-crlf-in-repo',
+            expected_unix, expected_win)
+        self.assertNewContentForSetting(wt, 'lf-with-crlf-in-repo',
+            expected_unix, expected_unix)
+        self.assertNewContentForSetting(wt, 'crlf-with-crlf-in-repo',
+            expected_win, expected_win)
+        self.assertNewContentForSetting(wt, 'exact', expected_raw)
+
+    def test_eol_no_rules(self):
+        wt, basis = self.prepare_tree(_sample_text)
+        self.assertContent(wt, basis, _sample_text,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_native(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='native')
+        self.assertContent(wt, basis, _sample_text_on_unix,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_native_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='native')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_lf(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='lf')
+        self.assertContent(wt, basis, _sample_text_on_unix,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_lf_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='lf')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_crlf(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='crlf')
+        self.assertContent(wt, basis, _sample_text_on_unix,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_crlf_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='crlf')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_native_with_crlf_in_repo(self):
+        wt, basis = self.prepare_tree(_sample_text,
+            eol='native-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_text_on_win,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_native_with_crlf_in_repo_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary,
+            eol='native-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_lf_with_crlf_in_repo(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='lf-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_text_on_win,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_lf_with_crlf_in_repo_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='lf-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_crlf_with_crlf_in_repo(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='crlf-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_text_on_win,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_crlf_with_crlf_in_repo_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='crlf-with-crlf-in-repo')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)
+
+    def test_eol_exact(self):
+        wt, basis = self.prepare_tree(_sample_text, eol='exact')
+        self.assertContent(wt, basis, _sample_text,
+            _sample_text_on_unix, _sample_text_on_win)
+
+    def test_eol_exact_binary(self):
+        wt, basis = self.prepare_tree(_sample_binary, eol='exact')
+        self.assertContent(wt, basis, _sample_binary, _sample_binary,
+            _sample_binary)




More information about the bazaar-commits mailing list