/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
3193.5.1 by Tim Penhey
Mostly working, just need to update the tests for lp://dev
61
        self.lp_instance = urlsplit(base)[1]
62
        if self.lp_instance == '':
63
            self.lp_instance = None
64
        elif self.lp_instance not in LaunchpadService.LAUNCHPAD_INSTANCE:
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
65
            raise errors.InvalidURL(path=base)
66
3031.2.4 by jml at canonical
Only split the URL once.
67
    def _requires_launchpad_login(self, scheme, netloc, path, query,
68
                                  fragment):
69
        """Does the URL require a Launchpad login in order to be reached?
70
71
        The URL is specified by its parsed components, as returned from
72
        urlsplit.
73
        """
3031.2.3 by jml at canonical
Make the test pass -- don't include sftp URLs if there's no lp login.
74
        return (scheme in ('bzr+ssh', 'sftp')
75
                and (netloc.endswith('launchpad.net')
76
                     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.
77
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
78
    def _resolve(self, abspath,
79
                 _request_factory=ResolveLaunchpadPathRequest,
80
                 _lp_login=None):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
81
        """Resolve the base URL for this transport."""
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
82
        path = urlsplit(abspath)[2].lstrip('/')
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
83
        # Perform an XMLRPC request to resolve the path
84
        resolve = _request_factory(path)
3193.5.1 by Tim Penhey
Mostly working, just need to update the tests for lp://dev
85
        service = LaunchpadService(lp_instance=self.lp_instance)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
86
        try:
87
            result = resolve.submit(service)
88
        except xmlrpclib.Fault, fault:
89
            raise errors.InvalidURL(
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
90
                path=abspath, extra=fault.faultString)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
91
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
92
        if 'launchpad' in debug.debug_flags:
93
            trace.mutter("resolve_lp_path(%r) == %r", path, result)
94
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
95
        if _lp_login is None:
96
            _lp_login = get_lp_login()
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
97
        for url in result['urls']:
98
            scheme, netloc, path, query, fragment = urlsplit(url)
3031.2.4 by jml at canonical
Only split the URL once.
99
            if self._requires_launchpad_login(scheme, netloc, path, query,
100
                                              fragment):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
101
                # Only accept launchpad.net bzr+ssh URLs if we know
102
                # the user's Launchpad login:
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
103
                if _lp_login is None:
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
104
                    continue
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
105
                url = urlunsplit((scheme, '%s@%s' % (_lp_login, netloc),
106
                                  path, query, fragment))
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
107
                break
2898.4.15 by James Henstridge
Use get_transport() to decide whether Bazaar supports a given URL.
108
            else:
109
                # Use the URL if we can create a transport for it.
110
                try:
111
                    get_transport(url)
112
                except (errors.PathError, errors.TransportError):
113
                    pass
114
                else:
115
                    break
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
116
        else:
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
117
            raise errors.InvalidURL(path=abspath,
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
118
                                    extra='no supported schemes')
119
        return url
120
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
121
    def _request_redirect(self, relpath):
122
        source = urlutils.join(self.base, relpath)
123
        # Split the source location into the branch location, and the
124
        # extra path components.
125
        pos = source.find('/.bzr/')
126
        if pos >= 0:
127
            branchpath = source[:pos]
128
            extra = source[pos:]
129
        else:
130
            branchpath = source
131
            extra = ''
132
        target = self._resolve(branchpath) + extra
133
        raise errors.RedirectRequested(
134
            source=source,
135
            target=target)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
136
137
    def get(self, relpath):
138
        """See Transport.get()."""
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
139
        self._request_redirect(relpath)
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
140
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
141
    def mkdir(self, relpath, mode=None):
142
        """See Transport.mkdir()."""
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
143
        self._request_redirect(relpath)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
144
2245.8.3 by Martin Pool
Start adding indirection transport
145
146
def get_test_permutations():
147
    # Since this transport doesn't do anything once opened, it's not subjected
148
    # to the usual transport tests.
149
    return []