fd496934f404d2625944b99fd010a636f762d72b
[jelmer/subvertpy.git] / __init__.py
1 # Copyright (C) 2005-2006 Jelmer Vernooij <jelmer@samba.org>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
7
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17 """
18 Support for foreign branches (Subversion)
19 """
20 import os
21 import sys
22 import unittest
23 import bzrlib
24
25 __version__ = '0.3.0'
26 required_bzr_version = (0,15)
27
28 def check_bzrlib_version(desired):
29     """Check that bzrlib is compatible.
30
31     If version is < desired version, assume incompatible.
32     If version == desired version, assume completely compatible
33     If version == desired version + 1, assume compatible, with deprecations
34     Otherwise, assume incompatible.
35     """
36     desired_plus = (desired[0], desired[1]+1)
37     bzrlib_version = bzrlib.version_info[:2]
38     if bzrlib_version == desired:
39         return
40     try:
41         from bzrlib.trace import warning
42     except ImportError:
43         # get the message out any way we can
44         from warnings import warn as warning
45     if bzrlib_version < desired:
46         warning('Installed bzr version %s is too old to be used with bzr-svn'
47                 ' %s.' % (bzrlib.__version__, __version__))
48         # Not using BzrNewError, because it may not exist.
49         raise Exception, ('Version mismatch', desired)
50     else:
51         warning('bzr-svn is not up to date with installed bzr version %s.'
52                 ' \nThere should be a newer version of bzr-svn available.' 
53                 % (bzrlib.__version__))
54         if bzrlib_version != desired_plus:
55             raise Exception, 'Version mismatch'
56
57 def check_subversion_version():
58     """Check that Subversion is compatible.
59
60     """
61     from bzrlib.trace import warning
62     try:
63         from svn.delta import svn_delta_invoke_txdelta_window_handler
64     except:
65         warning('Installed Subversion version does not have updated Python bindings. See the bzr-svn README for details.')
66         raise bzrlib.errors.BzrError("incompatible python subversion bindings")
67
68 def check_pysqlite_version():
69     """Check that sqlite library is compatible.
70
71     """
72     from bzrlib.trace import warning
73     try:
74         try:
75             import sqlite3
76         except ImportError:
77             from pysqlite2 import dbapi2 as sqlite3
78     except:
79         warning('Needs at least Python2.5 or Python2.4 with the pysqlite2 module')
80         raise bzrlib.errors.BzrError("missing sqlite library")
81
82     if (sqlite3.sqlite_version_info[0] < 3 or 
83             (sqlite3.sqlite_version_info[0] == 3 and 
84              sqlite3.sqlite_version_info[1] < 3)):
85         warning('Needs at least sqlite 3.3.x')
86         raise bzrlib.errors.BzrError("incompatible sqlite library")
87
88 check_bzrlib_version(required_bzr_version)
89 check_subversion_version()
90 check_pysqlite_version()
91
92 import branch
93 import convert
94 import format
95 import transport
96 import checkout
97
98 from bzrlib.transport import register_transport
99 register_transport('svn://', transport.SvnRaTransport)
100 register_transport('svn+', transport.SvnRaTransport)
101
102 from bzrlib.bzrdir import BzrDirFormat
103
104 from bzrlib.repository import InterRepository
105
106 from fetch import InterSvnRepository
107
108 BzrDirFormat.register_control_format(format.SvnFormat)
109
110 import svn.core
111 subr_version = svn.core.svn_subr_version()
112
113 if subr_version.major == 1 and subr_version.minor < 4:
114     from bzrlib.trace import warning
115     warning('Subversion version too old for working tree support.')
116 else:
117     BzrDirFormat.register_control_format(checkout.SvnWorkingTreeDirFormat)
118
119 InterRepository.register_optimiser(InterSvnRepository)
120
121 from bzrlib.branch import Branch
122 from bzrlib.commands import Command, register_command, display_command, Option
123 from bzrlib.errors import BzrCommandError
124 from bzrlib.repository import Repository
125 import bzrlib.urlutils as urlutils
126
127
128 def get_scheme(schemename):
129     """Parse scheme identifier and return a branching scheme."""
130     from scheme import BranchingScheme
131     
132     ret = BranchingScheme.find_scheme(schemename)
133     if ret is None:
134         raise BzrCommandError('No such branching scheme %r' % schemename)
135     return ret
136
137
138 class cmd_svn_import(Command):
139     """Convert a Subversion repository to a Bazaar repository.
140     
141     """
142     takes_args = ['from_location', 'to_location?']
143     takes_options = [Option('trees', help='Create working trees'),
144                      Option('shared', help='Create shared repository'),
145                      Option('all', help='Convert all revisions, even those not in current branch history (implies --shared)'),
146                      Option('scheme', type=get_scheme,
147                          help='Branching scheme (none, trunk, or trunk-INT)')]
148
149     @display_command
150     def run(self, from_location, to_location=None, trees=False, 
151             shared=False, scheme=None, all=False):
152         from convert import convert_repository
153         from scheme import TrunkBranchingScheme
154
155         if scheme is None:
156             scheme = TrunkBranchingScheme()
157
158         if to_location is None:
159             to_location = os.path.basename(from_location.rstrip("/\\"))
160
161         if all:
162             shared = True
163         convert_repository(from_location, to_location, scheme, shared, trees,
164                            all)
165
166
167 register_command(cmd_svn_import)
168
169 class cmd_svn_upgrade(Command):
170     """Upgrade the revisions mapped from Subversion in a Bazaar branch.
171     
172     This will change the revision ids of revisions whose parents 
173     were mapped from svn revisions.
174     """
175     takes_args = ['svn_repository?']
176     takes_options = [Option('allow-changes', help='Allow content changes')]
177
178     @display_command
179     def run(self, svn_repository=None, allow_changes=False):
180         from upgrade import upgrade_branch
181         
182         branch_to = Branch.open(".")
183
184         stored_loc = branch_to.get_parent()
185         if svn_repository is None:
186             if stored_loc is None:
187                 raise BzrCommandError("No pull location known or"
188                                              " specified.")
189             else:
190                 display_url = urlutils.unescape_for_display(stored_loc,
191                         self.outf.encoding)
192                 self.outf.write("Using saved location: %s\n" % display_url)
193                 svn_repository = stored_loc
194
195         upgrade_branch(branch_to, Repository.open(svn_repository), 
196                        allow_changes)
197
198 register_command(cmd_svn_upgrade)
199
200
201 def test_suite():
202     from unittest import TestSuite, TestLoader
203     import tests
204
205     suite = TestSuite()
206
207     suite.addTest(tests.test_suite())
208
209     return suite
210
211 if __name__ == '__main__':
212     print ("This is a Bazaar plugin. Copy this directory to ~/.bazaar/plugins "
213           "to use it.\n")
214 else:
215     sys.path.append(os.path.dirname(__file__))
216