~gagern/bzr-svn/bug242321

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Copyright (C) 2006-2008 Jelmer Vernooij <jelmer@samba.org>

# 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 3 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""Subversion BzrDir formats."""

from bzrlib.bzrdir import BzrDirFormat, BzrDir, format_registry
from bzrlib.errors import UninitializableFormat
from bzrlib.lazy_import import lazy_import
from bzrlib.lockable_files import TransportLock

import os

lazy_import(globals(), """
import errors
import remote

from bzrlib import errors as bzr_errors
""")

def get_rich_root_format():
    format = BzrDirFormat.get_default_format()
    if format.repository_format.rich_root_data:
        return format
    # Default format does not support rich root data, 
    # fall back to rich-root
    format = format_registry.make_bzrdir('rich-root-pack')
    assert format.repository_format.rich_root_data
    return format


class SvnRemoteFormat(BzrDirFormat):
    """Format for the Subversion smart server."""
    _lock_class = TransportLock

    def __init__(self):
        super(SvnRemoteFormat, self).__init__()
        from repository import SvnRepositoryFormat
        self.repository_format = SvnRepositoryFormat()

    @classmethod
    def probe_transport(klass, transport):
        from transport import get_svn_ra_transport
        import svn.core
        format = klass()

        try:
            transport = get_svn_ra_transport(transport)
        except svn.core.SubversionException, (_, num):
            if num in (svn.core.SVN_ERR_RA_ILLEGAL_URL, \
                       svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, \
                       svn.core.SVN_ERR_BAD_URL):
                raise bzr_errors.NotBranchError(path=transport.base)

        return format

    def _open(self, transport):
        import svn.core
        try: 
            return remote.SvnRemoteAccess(transport, self)
        except svn.core.SubversionException, (_, num):
            if num == svn.core.SVN_ERR_RA_DAV_REQUEST_FAILED:
                raise bzr_errors.NotBranchError(transport.base)
            raise

    def get_format_string(self):
        return 'Subversion Smart Server'

    def get_format_description(self):
        return 'Subversion Smart Server'

    def initialize_on_transport(self, transport):
        """See BzrDir.initialize_on_transport()."""
        from transport import get_svn_ra_transport
        from bzrlib.transport.local import LocalTransport
        import svn.repos

        if not isinstance(transport, LocalTransport):
            raise NotImplementedError(self.initialize, 
                "Can't create Subversion Repositories/branches on "
                "non-local transports")

        local_path = transport._local_base.rstrip("/")
        svn.repos.create(local_path, '', '', None, None)
        # All revision property changes
        revprop_hook = os.path.join(local_path, "hooks", "pre-revprop-change")
        open(revprop_hook, 'w').write("#!/bin/sh")
        os.chmod(revprop_hook, os.stat(revprop_hook).st_mode | 0111)
        return self.open(get_svn_ra_transport(transport), _found=True)

    def is_supported(self):
        """See BzrDir.is_supported()."""
        return True


class SvnWorkingTreeDirFormat(BzrDirFormat):
    """Working Tree implementation that uses Subversion working copies."""
    _lock_class = TransportLock

    def __init__(self):
        super(SvnWorkingTreeDirFormat, self).__init__()
        from repository import SvnRepositoryFormat
        self.repository_format = SvnRepositoryFormat()

    @classmethod
    def probe_transport(klass, transport):
        import svn
        from bzrlib.transport.local import LocalTransport
        format = klass()

        if isinstance(transport, LocalTransport) and \
            transport.has(svn.wc.get_adm_dir()):
            return format

        raise bzr_errors.NotBranchError(path=transport.base)

    def _open(self, transport):
        import svn.core
        from workingtree import SvnCheckout
        subr_version = svn.core.svn_subr_version()
        if subr_version.major == 1 and subr_version.minor < 4:
            raise errors.NoCheckoutSupport()
        try:
            return SvnCheckout(transport, self)
        except svn.core.SubversionException, (_, num):
            if num in (svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED,):
                raise errors.NoSvnRepositoryPresent(transport.base)
            raise

    def get_format_string(self):
        return 'Subversion Local Checkout'

    def get_format_description(self):
        return 'Subversion Local Checkout'

    def initialize_on_transport(self, transport):
        raise UninitializableFormat(self)

    def get_converter(self, format=None):
        """See BzrDirFormat.get_converter()."""
        if format is None:
            format = get_rich_root_format()
        raise NotImplementedError(self.get_converter)