/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/plugins/launchpad/lp_api.py

  • Committer: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
22
22
 
23
23
 
24
24
import os
25
 
import re
26
25
 
27
26
from bzrlib import (
28
 
    branch,
29
27
    config,
30
28
    errors,
31
29
    osutils,
32
 
    trace,
33
 
    transport,
34
30
    )
35
31
from bzrlib.plugins.launchpad.lp_registration import (
36
32
    InvalidLaunchpadInstance,
116
112
    return launchpad
117
113
 
118
114
 
119
 
class LaunchpadBranch(object):
120
 
    """Provide bzr and lp API access to a Launchpad branch."""
121
 
 
122
 
    def __init__(self, lp_branch, bzr_url, bzr_branch=None, check_update=True):
123
 
        """Constructor.
124
 
 
125
 
        :param lp_branch: The Launchpad branch.
126
 
        :param bzr_url: The URL of the Bazaar branch.
127
 
        :param bzr_branch: An instance of the Bazaar branch.
128
 
        """
129
 
        self.bzr_url = bzr_url
130
 
        self._bzr = bzr_branch
131
 
        self._push_bzr = None
132
 
        self._check_update = check_update
133
 
        self.lp = lp_branch
134
 
 
135
 
    @property
136
 
    def bzr(self):
137
 
        """Return the bzr branch for this branch."""
138
 
        if self._bzr is None:
139
 
            self._bzr = branch.Branch.open(self.bzr_url)
140
 
        return self._bzr
141
 
 
142
 
    @property
143
 
    def push_bzr(self):
144
 
        """Return the push branch for this branch."""
145
 
        if self._push_bzr is None:
146
 
            self._push_bzr = branch.Branch.open(self.lp.bzr_identity)
147
 
        return self._push_bzr
148
 
 
149
 
    @staticmethod
150
 
    def plausible_launchpad_url(url):
151
 
        """Is 'url' something that could conceivably be pushed to LP?
152
 
 
153
 
        :param url: A URL that may refer to a Launchpad branch.
154
 
        :return: A boolean.
155
 
        """
156
 
        if url is None:
157
 
            return False
158
 
        if url.startswith('lp:'):
159
 
            return True
160
 
        regex = re.compile('([a-z]*\+)*(bzr\+ssh|http)'
161
 
                           '://bazaar.*.launchpad.net')
162
 
        return bool(regex.match(url))
163
 
 
164
 
    @staticmethod
165
 
    def candidate_urls(bzr_branch):
166
 
        """Iterate through related URLs that might be Launchpad URLs.
167
 
 
168
 
        :param bzr_branch: A Bazaar branch to find URLs from.
169
 
        :return: a generator of URL strings.
170
 
        """
171
 
        url = bzr_branch.get_public_branch()
172
 
        if url is not None:
173
 
            yield url
174
 
        url = bzr_branch.get_push_location()
175
 
        if url is not None:
176
 
            yield url
177
 
        yield bzr_branch.base
178
 
 
179
 
    @staticmethod
180
 
    def tweak_url(url, launchpad):
181
 
        """Adjust a URL to work with staging, if needed."""
182
 
        if str(launchpad._root_uri) != STAGING_SERVICE_ROOT:
183
 
            return url
184
 
        if url is None:
185
 
            return None
186
 
        return url.replace('bazaar.launchpad.net',
187
 
                           'bazaar.staging.launchpad.net')
188
 
 
189
 
    @classmethod
190
 
    def from_bzr(cls, launchpad, bzr_branch):
191
 
        """Find a Launchpad branch from a bzr branch."""
192
 
        check_update = True
193
 
        for url in cls.candidate_urls(bzr_branch):
194
 
            url = cls.tweak_url(url, launchpad)
195
 
            if not cls.plausible_launchpad_url(url):
196
 
                continue
197
 
            lp_branch = launchpad.branches.getByUrl(url=url)
198
 
            if lp_branch is not None:
199
 
                break
200
 
        else:
201
 
            lp_branch = cls.create_now(launchpad, bzr_branch)
202
 
            check_update = False
203
 
        return cls(lp_branch, bzr_branch.base, bzr_branch, check_update)
204
 
 
205
 
    @classmethod
206
 
    def create_now(cls, launchpad, bzr_branch):
207
 
        """Create a Bazaar branch on Launchpad for the supplied branch."""
208
 
        url = cls.tweak_url(bzr_branch.get_push_location(), launchpad)
209
 
        if not cls.plausible_launchpad_url(url):
210
 
            raise errors.BzrError('%s is not registered on Launchpad' %
211
 
                                  bzr_branch.base)
212
 
        bzr_branch.create_clone_on_transport(transport.get_transport(url))
213
 
        lp_branch = launchpad.branches.getByUrl(url=url)
214
 
        if lp_branch is None:
215
 
            raise errors.BzrError('%s is not registered on Launchpad' % url)
216
 
        return lp_branch
217
 
 
218
 
    def get_dev_focus(self):
219
 
        """Return the 'LaunchpadBranch' for the dev focus of this one."""
220
 
        lp_branch = self.lp
221
 
        if lp_branch.project is None:
222
 
            raise errors.BzrError('%s has no product.' %
223
 
                                  lp_branch.bzr_identity)
224
 
        dev_focus = lp_branch.project.development_focus.branch
225
 
        if dev_focus is None:
226
 
            raise errors.BzrError('%s has no development focus.' %
227
 
                                  lp_branch.bzr_identity)
228
 
        return LaunchpadBranch(dev_focus, dev_focus.bzr_identity)
229
 
 
230
 
    def update_lp(self):
231
 
        """Update the Launchpad copy of this branch."""
232
 
        if not self._check_update:
233
 
            return
234
 
        self.bzr.lock_read()
235
 
        try:
236
 
            if self.lp.last_scanned_id is not None:
237
 
                if self.bzr.last_revision() == self.lp.last_scanned_id:
238
 
                    trace.note('%s is already up-to-date.' %
239
 
                               self.lp.bzr_identity)
240
 
                    return
241
 
                graph = self.bzr.repository.get_graph()
242
 
                if not graph.is_ancestor(self.lp.last_scanned_id,
243
 
                                         self.bzr.last_revision()):
244
 
                    raise errors.DivergedBranches(self.bzr, self.push_bzr)
245
 
                trace.note('Pushing to %s' % self.lp.bzr_identity)
246
 
            self.bzr.push(self.push_bzr)
247
 
        finally:
248
 
            self.bzr.unlock()
249
 
 
250
 
    def find_lca_tree(self, other):
251
 
        """Find the revision tree for the LCA of this branch and other.
252
 
 
253
 
        :param other: Another LaunchpadBranch
254
 
        :return: The RevisionTree of the LCA of this branch and other.
255
 
        """
256
 
        graph = self.bzr.repository.get_graph(other.bzr.repository)
257
 
        lca = graph.find_unique_lca(self.bzr.last_revision(),
258
 
                                    other.bzr.last_revision())
259
 
        return self.bzr.repository.revision_tree(lca)
260
 
 
261
 
 
262
115
def load_branch(launchpad, branch):
263
116
    """Return the launchpadlib Branch object corresponding to 'branch'.
264
117