Handle text transformations more strictly.
[cvs2svn.git] / cvs2svn_lib / abstract_rcs_revision_manager.py
blobdc7ef561dab70e38881fa2137b62df1749a7d34f
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2010 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """Base class for RCSRevisionReader and CVSRevisionReader."""
20 from cvs2svn_lib.common import canonicalize_eol
21 from cvs2svn_lib.process import get_command_output
22 from cvs2svn_lib.context import Ctx
23 from cvs2svn_lib.revision_manager import RevisionReader
24 from cvs2svn_lib.keyword_expander import expand_keywords
25 from cvs2svn_lib.keyword_expander import collapse_keywords
26 from cvs2svn_lib.apple_single_filter import get_maybe_apple_single
29 class AbstractRCSRevisionReader(RevisionReader):
30 """A base class for RCSRevisionReader and CVSRevisionReader."""
32 # A map from (eol_fix, keyword_handling) to ('-k' option needed for
33 # RCS/CVS, explicit_keyword_handling). The preference is to allow
34 # CVS/RCS to handle keyword expansion itself whenever possible. But
35 # it is not possible in combination with eol_fix==False, because the
36 # only option that CVS/RCS has that leaves the EOLs alone is '-kb'
37 # mode, which leaves the keywords untouched. Therefore, whenever
38 # eol_fix is False, we need to use '-kb' mode and then (if
39 # necessary) expand or collapse the keywords ourselves.
40 _text_options = {
41 (False, 'collapsed') : (['-kb'], 'collapsed'),
42 (False, 'expanded') : (['-kb'], 'expanded'),
43 (False, 'untouched') : (['-kb'], None),
45 (True, 'collapsed') : (['-kk'], None),
46 (True, 'expanded') : (['-kkv'], None),
47 (True, 'untouched') : (['-ko'], None),
50 def get_pipe_command(self, cvs_rev, k_option):
51 """Return the command that is needed to get the contents for CVS_REV.
53 K_OPTION is a list containing the '-k' option that is needed, if
54 any."""
56 raise NotImplementedError()
58 def get_content(self, cvs_rev):
59 # Is EOL fixing requested?
60 eol_fix = cvs_rev.get_property('_eol_fix') or None
62 # How do we want keywords to be handled?
63 keyword_handling = cvs_rev.get_property('_keyword_handling') or None
65 try:
66 (k_option, explicit_keyword_handling) = self._text_options[
67 bool(eol_fix), keyword_handling
69 except KeyError:
70 raise FatalError(
71 'Undefined _keyword_handling property (%r) for %s'
72 % (keyword_handling, cvs_rev,)
75 data = get_command_output(self.get_pipe_command(cvs_rev, k_option))
77 if Ctx().decode_apple_single:
78 # Insert a filter to decode any files that are in AppleSingle
79 # format:
80 data = get_maybe_apple_single(data)
82 if explicit_keyword_handling == 'expanded':
83 data = expand_keywords(data, cvs_rev)
84 elif explicit_keyword_handling == 'collapsed':
85 data = collapse_keywords(data)
87 if eol_fix:
88 data = canonicalize_eol(data, eol_fix)
90 return data