/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2245.8.3 by Martin Pool
Start adding indirection transport
1
# Copyright (C) 2007 Canonical Ltd
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
"""Transport indirection that uses Launchpad as a directory lookup.
19
20
When the transport is opened, it immediately redirects to a url
21
on Launchpad, which can then either serve the branch itself or redirect
22
again.
23
"""
24
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
25
from urlparse import urlsplit, urlunsplit
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
26
import xmlrpclib
27
2245.8.4 by Martin Pool
lp:/// indirection works
28
from bzrlib import (
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
29
    debug,
2245.8.4 by Martin Pool
lp:/// indirection works
30
    errors,
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
31
    trace,
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
32
    urlutils,
2245.8.4 by Martin Pool
lp:/// indirection works
33
    )
34
from bzrlib.transport import (
35
    get_transport,
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
36
    register_urlparse_netloc_protocol,
2245.8.4 by Martin Pool
lp:/// indirection works
37
    Transport,
38
    )
39
2898.4.7 by James Henstridge
Fix up tests.
40
from bzrlib.plugins.launchpad.lp_registration import (
41
    LaunchpadService, ResolveLaunchpadPathRequest)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
42
from bzrlib.plugins.launchpad.account import get_lp_login
43
44
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
45
# As bzrlib.transport.remote may not be loaded yet, make sure bzr+ssh
46
# is counted as a netloc protocol.
47
register_urlparse_netloc_protocol('bzr+ssh')
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
48
register_urlparse_netloc_protocol('lp')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
49
50
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
51
class LaunchpadTransport(Transport):
52
    """lp:/// URL transport
53
54
    This transport redirects requests to the real branch location
55
    after resolving the URL via an XMLRPC request to Launchpad.
56
    """
57
58
    def __init__(self, base):
59
        super(LaunchpadTransport, self).__init__(base)
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
60
        # We only support URLs without a netloc
61
        netloc = urlsplit(base)[1]
62
        if netloc != '':
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
63
            raise errors.InvalidURL(path=base)
64
3031.2.1 by jml at canonical
Factor out the method that determines if a URL is a LP url.
65
    def _requires_launchpad_login(self, url):
66
        """Does the URL require a Launchpad login in order to be reached?"""
67
        scheme, netloc, path, query, fragment = urlsplit(url)
3031.2.3 by jml at canonical
Make the test pass -- don't include sftp URLs if there's no lp login.
68
        return (scheme in ('bzr+ssh', 'sftp')
69
                and (netloc.endswith('launchpad.net')
70
                     or netloc.endswith('launchpad.dev')))
3031.2.1 by jml at canonical
Factor out the method that determines if a URL is a LP url.
71
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
72
    def _resolve(self, abspath,
73
                 _request_factory=ResolveLaunchpadPathRequest,
74
                 _lp_login=None):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
75
        """Resolve the base URL for this transport."""
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
76
        path = urlsplit(abspath)[2].lstrip('/')
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
77
        # Perform an XMLRPC request to resolve the path
78
        resolve = _request_factory(path)
79
        service = LaunchpadService()
80
        try:
81
            result = resolve.submit(service)
82
        except xmlrpclib.Fault, fault:
83
            raise errors.InvalidURL(
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
84
                path=abspath, extra=fault.faultString)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
85
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
86
        if 'launchpad' in debug.debug_flags:
87
            trace.mutter("resolve_lp_path(%r) == %r", path, result)
88
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
89
        if _lp_login is None:
90
            _lp_login = get_lp_login()
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
91
        for url in result['urls']:
92
            scheme, netloc, path, query, fragment = urlsplit(url)
3031.2.1 by jml at canonical
Factor out the method that determines if a URL is a LP url.
93
            if self._requires_launchpad_login(url):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
94
                # Only accept launchpad.net bzr+ssh URLs if we know
95
                # the user's Launchpad login:
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
96
                if _lp_login is None:
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
97
                    continue
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
98
                url = urlunsplit((scheme, '%s@%s' % (_lp_login, netloc),
99
                                  path, query, fragment))
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
100
                break
2898.4.15 by James Henstridge
Use get_transport() to decide whether Bazaar supports a given URL.
101
            else:
102
                # Use the URL if we can create a transport for it.
103
                try:
104
                    get_transport(url)
105
                except (errors.PathError, errors.TransportError):
106
                    pass
107
                else:
108
                    break
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
109
        else:
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
110
            raise errors.InvalidURL(path=abspath,
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
111
                                    extra='no supported schemes')
112
        return url
113
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
114
    def _request_redirect(self, relpath):
115
        source = urlutils.join(self.base, relpath)
116
        # Split the source location into the branch location, and the
117
        # extra path components.
118
        pos = source.find('/.bzr/')
119
        if pos >= 0:
120
            branchpath = source[:pos]
121
            extra = source[pos:]
122
        else:
123
            branchpath = source
124
            extra = ''
125
        target = self._resolve(branchpath) + extra
126
        raise errors.RedirectRequested(
127
            source=source,
128
            target=target)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
129
130
    def get(self, relpath):
131
        """See Transport.get()."""
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
132
        self._request_redirect(relpath)
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
133
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
134
    def mkdir(self, relpath, mode=None):
135
        """See Transport.mkdir()."""
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
136
        self._request_redirect(relpath)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
137
2245.8.3 by Martin Pool
Start adding indirection transport
138
139
def get_test_permutations():
140
    # Since this transport doesn't do anything once opened, it's not subjected
141
    # to the usual transport tests.
142
    return []