1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2008 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 """Access the CVS repository via CVS's 'cvs' command."""
20 from cvs2svn_lib
.common
import FatalError
21 from cvs2svn_lib
.common
import canonicalize_eol
22 from cvs2svn_lib
.process
import check_command_runs
23 from cvs2svn_lib
.process
import get_command_output
24 from cvs2svn_lib
.process
import CommandFailedException
25 from cvs2svn_lib
.context
import Ctx
26 from cvs2svn_lib
.revision_manager
import RevisionReader
27 from cvs2svn_lib
.abstract_rcs_revision_manager
import AbstractRCSRevisionReader
28 from cvs2svn_lib
.apple_single_filter
import get_maybe_apple_single
31 class CVSRevisionReader(AbstractRCSRevisionReader
):
32 """A RevisionReader that reads the contents via CVS."""
34 # Different versions of CVS support different global options. Here
35 # are the global options that we try to use, in order of decreasing
37 _possible_global_options
= [
48 def __init__(self
, cvs_executable
, global_options
=None):
49 """Initialize a CVSRevisionReader.
51 CVS_EXECUTABLE is the CVS command (possibly including the full
52 path to the executable; otherwise it is sought in the $PATH).
53 GLOBAL_ARGUMENTS, if specified, should be a list of global options
54 that are passed to the CVS command before the subcommand. If
55 GLOBAL_ARGUMENTS is not specified, then each of the possibilities
56 listed in _possible_global_options is checked in order until one
57 is found that runs successfully and without any output to stderr."""
59 self
.cvs_executable
= cvs_executable
61 if global_options
is None:
62 for global_options
in self
._possible
_global
_options
:
64 self
._check
_cvs
_runs
(global_options
)
65 except CommandFailedException
, e
:
72 'Please check that cvs is installed and in your PATH.' % (e
,)
76 self
._check
_cvs
_runs
(global_options
)
77 except CommandFailedException
, e
:
80 'Please check that cvs is installed and in your PATH and that\n'
81 'the global options that you specified (%r) are correct.'
82 % (e
, global_options
,)
85 # The global options were OK; use them for all CVS invocations.
86 self
.global_options
= global_options
88 def _check_cvs_runs(self
, global_options
):
89 """Check that CVS can be started.
91 Try running 'cvs --version' with the current setting for
92 self.cvs_executable and the specified global_options. If not
93 successful, raise a CommandFailedException."""
96 [self
.cvs_executable
] + global_options
+ ['--version'],
100 def get_content(self
, cvs_rev
):
101 project
= cvs_rev
.cvs_file
.project
104 ] + self
.global_options
+ [
105 '-d', ':local:' + project
.cvs_repository_root
,
109 ] + self
.select_k_option(cvs_rev
) + [
110 project
.cvs_module
+ cvs_rev
.cvs_path
112 data
= get_command_output(pipe_cmd
)
114 if Ctx().decode_apple_single
:
115 # Insert a filter to decode any files that are in AppleSingle
117 data
= get_maybe_apple_single(data
)
119 eol_fix
= cvs_rev
.get_property('_eol_fix')
121 data
= canonicalize_eol(data
, eol_fix
)