115
class LaunchpadBranch(object):
117
def __init__(self, lp_branch, bzr_url, bzr_branch=None, check_update=True):
118
self.bzr_url = bzr_url
119
self._bzr = bzr_branch
120
self._push_bzr = None
121
self._check_update = False
126
if self._bzr is None:
127
self._bzr = branch.Branch.open(self.bzr_url)
132
if self._push_bzr is None:
133
self._push_bzr = branch.Branch.open(self.lp.bzr_identity)
134
return self._push_bzr
137
def plausible_launchpad_url(url):
138
"""Is 'url' something that could conceivably be pushed to LP?"""
141
if url.startswith('lp:'):
143
regex = re.compile('([a-z]*\+)*(bzr\+ssh|http)'
144
'://bazaar.*.launchpad.net')
145
return bool(regex.match(url))
148
def candidate_urls(bzr_branch):
149
url = bzr_branch.get_public_branch()
152
url = bzr_branch.get_push_location()
155
yield bzr_branch.base
158
def tweak_url(url, launchpad):
159
if str(launchpad._root_uri) != STAGING_SERVICE_ROOT:
163
return url.replace('bazaar.launchpad.net',
164
'bazaar.staging.launchpad.net')
167
def from_bzr(cls, launchpad, bzr_branch):
169
for url in cls.candidate_urls(bzr_branch):
170
url = cls.tweak_url(url, launchpad)
171
if not cls.plausible_launchpad_url(url):
173
lp_branch = launchpad.branches.getByUrl(url=url)
174
if lp_branch is not None:
177
lp_branch = cls.create_now(launchpad, bzr_branch)
179
return cls(lp_branch, bzr_branch.base, bzr_branch, check_update)
182
def create_now(cls, launchpad, bzr_branch):
183
url = cls.tweak_url(bzr_branch.get_push_location(), launchpad)
184
if not cls.plausible_launchpad_url(url):
185
raise errors.BzrError('%s is not registered on Launchpad' %
187
bzr_branch.create_clone_on_transport(transport.get_transport(url))
188
lp_branch = launchpad.branches.getByUrl(url=url)
189
if lp_branch is None:
190
raise errors.BzrError('%s is not registered on Launchpad' % url)
193
def get_dev_focus(self):
194
"""Return the 'LaunchpadBranch' for the dev focus of this one."""
196
if lp_branch.project is None:
197
raise errors.BzrError('%s has no product.' %
198
lp_branch.bzr_identity)
199
dev_focus = lp_branch.project.development_focus.branch
200
if dev_focus is None:
201
raise errors.BzrError('%s has no development focus.' %
202
lp_branch.bzr_identity)
203
return LaunchpadBranch(dev_focus, dev_focus.bzr_identity)
206
if not self._check_update:
210
if self.lp.last_scanned_id is not None:
211
if self.bzr.last_revision() == self.lp.last_scanned_id:
212
trace.note('%s is already up-to-date.' %
213
self.lp.bzr_identity)
215
graph = self.bzr.repository.get_graph()
216
if not graph.is_ancestor(self.bzr.last_revision(),
217
self.lp.last_scanned_id):
218
raise errors.DivergedBranches(self.bzr, self.push_bzr)
219
trace.note('Pushing to %s' % self.lp.bzr_identity)
220
self.bzr.push(self.push_bzr)
224
def find_lca_tree(self, other):
225
graph = self.bzr.repository.get_graph(other.bzr.repository)
226
lca = graph.find_unique_lca(self.bzr.last_revision(),
227
other.bzr.last_revision())
228
return self.bzr.repository.revision_tree(lca)
231
115
def load_branch(launchpad, branch):
232
116
"""Return the launchpadlib Branch object corresponding to 'branch'.