Warn when used with experimental version of mappings. (#117198), use lazy imports...
[jelmer/subvertpy.git] / __init__.py
1 # Copyright (C) 2005-2007 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 Subversion branches
19 """
20 from bzrlib.bzrdir import BzrDirFormat
21 from bzrlib.commands import Command, register_command, display_command, Option
22 from bzrlib.lazy_import import lazy_import
23 from bzrlib.trace import warning, mutter
24 from bzrlib.transport import register_lazy_transport, register_transport_proto
25 from bzrlib.repository import InterRepository
26
27 lazy_import(globals(), """
28 import commit
29 import fetch 
30 import format
31 import workingtree
32 """)
33
34 __version__ = '0.4.0exp'
35 COMPATIBLE_BZR_VERSIONS = [(0, 18)]
36
37 def check_bzrlib_version(desired):
38     """Check that bzrlib is compatible.
39
40     If version is < all compatible version, assume incompatible.
41     If version is compatible version + 1, assume compatible, with deprecations
42     Otherwise, assume incompatible.
43     """
44     import bzrlib
45     bzrlib_version = bzrlib.version_info[:2]
46     if (bzrlib_version in desired or 
47         ((bzrlib_version[0], bzrlib_version[1]-1) in desired and 
48          bzrlib.version_info[3] == 'dev')):
49         return
50     if bzrlib_version < desired[0]:
51         warning('Installed bzr version %s is too old to be used with bzr-svn'
52                 ' %s.' % (bzrlib.__version__, __version__))
53         # Not using BzrNewError, because it may not exist.
54         raise Exception, ('Version mismatch', desired)
55     else:
56         warning('bzr-svn is not up to date with installed bzr version %s.'
57                 ' \nThere should be a newer version of bzr-svn available.' 
58                 % (bzrlib.__version__))
59         if not (bzrlib_version[0], bzrlib_version[1]-1) in desired:
60             raise Exception, 'Version mismatch'
61
62 def check_bzrsvn_version():
63     """Warn about use of experimental mappings."""
64     if __version__.endswith("exp"):
65         warning('version of bzr-svn is experimental; output may change between revisions')
66
67 def check_subversion_version():
68     """Check that Subversion is compatible.
69
70     """
71     import svn.delta
72     if not hasattr(svn.delta, 'svn_delta_invoke_txdelta_window_handler'):
73         warning('Installed Subversion version does not have updated Python '
74                 'bindings. See the bzr-svn README for details.')
75         raise bzrlib.errors.BzrError("incompatible python subversion bindings")
76
77 def check_versions():
78     check_bzrlib_version(COMPATIBLE_BZR_VERSIONS)
79     check_subversion_version()
80     check_bzrsvn_version()
81
82 check_versions()
83
84 register_transport_proto('svn://', help="Access using the Subversion smart server.")
85 register_transport_proto('svn+ssh://', 
86     help="Access using the Subversion smart server tunneled over SSH.")
87 register_transport_proto('svn+file://', 
88     help="Access of local Subversion repositories.")
89 register_transport_proto('svn+http://',
90     help="Access of Subversion smart servers over HTTP.")
91 register_transport_proto('svn+https://',
92     help="Access of Subversion smart servers over secure HTTP.")
93 register_lazy_transport('svn://', 'bzrlib.plugins.svn.transport', 'SvnRaTransport')
94 register_lazy_transport('svn+', 'bzrlib.plugins.svn.transport', 'SvnRaTransport')
95
96 BzrDirFormat.register_control_format(format.SvnFormat)
97 BzrDirFormat.register_control_format(workingtree.SvnWorkingTreeDirFormat)
98
99 InterRepository.register_optimiser(fetch.InterFromSvnRepository)
100 InterRepository.register_optimiser(commit.InterToSvnRepository)
101
102
103 def get_scheme(schemename):
104     """Parse scheme identifier and return a branching scheme."""
105     from scheme import BranchingScheme
106     from bzrlib.errors import BzrCommandError
107     
108     ret = BranchingScheme.find_scheme(schemename)
109     if ret is None:
110         raise BzrCommandError('No such branching scheme %r' % schemename)
111     return ret
112
113
114 class cmd_svn_import(Command):
115     """Convert a Subversion repository to a Bazaar repository.
116     
117     """
118     takes_args = ['from_location', 'to_location?']
119     takes_options = [Option('trees', help='Create working trees'),
120                      Option('standalone', help='Create standalone branches'),
121                      Option('all', 
122                          help='Convert all revisions, even those not in '
123                               'current branch history (forbids --standalone)'),
124                      Option('scheme', type=get_scheme,
125                          help='Branching scheme (none, trunk, ...)')]
126
127     @display_command
128     def run(self, from_location, to_location=None, trees=False, 
129             standalone=False, scheme=None, all=False):
130         from bzrlib.repository import Repository
131         from convert import convert_repository
132         import os
133         from scheme import TrunkBranchingScheme
134
135         if to_location is None:
136             to_location = os.path.basename(from_location.rstrip("/\\"))
137
138         if all:
139             standalone = False
140
141         if os.path.isfile(from_location):
142             from convert import load_dumpfile
143             import tempfile
144             tmp_repos = tempfile.mkdtemp(prefix='bzr-svn-dump-')
145             mutter('loading dumpfile %r to %r' % (from_location, tmp_repos))
146             load_dumpfile(from_location, tmp_repos)
147             from_location = tmp_repos
148         else:
149             tmp_repos = None
150
151         from_repos = Repository.open(from_location)
152
153         convert_repository(from_repos, to_location, scheme, not standalone, 
154                 trees, all)
155
156         if tmp_repos is not None:
157             from bzrlib import osutils
158             osutils.rmtree(tmp_repos)
159
160
161 register_command(cmd_svn_import)
162
163 class cmd_svn_upgrade(Command):
164     """Upgrade revisions mapped from Subversion in a Bazaar branch.
165     
166     This will change the revision ids of revisions whose parents 
167     were mapped from svn revisions.
168     """
169     takes_args = ['svn_repository?']
170     takes_options = ['verbose']
171
172     @display_command
173     def run(self, svn_repository=None, verbose=False):
174         from upgrade import upgrade_branch
175         from bzrlib.branch import Branch
176         from bzrlib.errors import NoWorkingTree, BzrCommandError
177         from bzrlib.repository import Repository
178         from bzrlib.workingtree import WorkingTree
179         try:
180             wt_to = WorkingTree.open(".")
181             branch_to = wt_to.branch
182         except NoWorkingTree:
183             wt_to = None
184             branch_to = Branch.open(".")
185
186         stored_loc = branch_to.get_parent()
187         if svn_repository is None:
188             if stored_loc is None:
189                 raise BzrCommandError("No pull location known or"
190                                              " specified.")
191             else:
192                 import bzrlib.urlutils as urlutils
193                 display_url = urlutils.unescape_for_display(stored_loc,
194                         self.outf.encoding)
195                 self.outf.write("Using saved location: %s\n" % display_url)
196                 svn_repository = Branch.open(stored_loc).repository
197         else:
198             svn_repository = Repository.open(svn_repository)
199
200         upgrade_branch(branch_to, svn_repository, allow_changes=True, 
201                        verbose=verbose)
202
203         if wt_to is not None:
204             wt_to.set_last_revision(branch_to.last_revision())
205
206 register_command(cmd_svn_upgrade)
207
208
209 def test_suite():
210     from unittest import TestSuite
211     import tests
212     suite = TestSuite()
213     suite.addTest(tests.test_suite())
214     return suite
215
216 if __name__ == '__main__':
217     print ("This is a Bazaar plugin. Copy this directory to ~/.bazaar/plugins "
218           "to use it.\n")
219 elif __name__ != 'bzrlib.plugins.svn':
220     raise ImportError('The Subversion plugin must be installed as'
221                       ' bzrlib.plugins.svn not %s' % __name__)
222 else:
223     import os, sys
224     sys.path.append(os.path.dirname(os.path.abspath(__file__)))