/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
1
# Copyright (C) 2010, 2011 Canonical Ltd
0.431.27 by Jelmer Vernooij
Catch 503 errors.
2
# Copyright (C) 2018 Breezy Developers
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
0.434.1 by Jelmer Vernooij
Use absolute_import.
18
"""Support for Launchpad."""
19
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
20
from __future__ import absolute_import
21
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
22
import re
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
23
import shutil
24
import tempfile
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
25
7408.3.1 by Jelmer Vernooij
Move propose module into core.
26
from ...propose import (
0.432.2 by Jelmer Vernooij
Publish command sort of works.
27
    Hoster,
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
28
    LabelsUnsupported,
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
29
    MergeProposal,
0.432.2 by Jelmer Vernooij
Publish command sort of works.
30
    MergeProposalBuilder,
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
31
    MergeProposalExists,
0.431.12 by Jelmer Vernooij
Fix Launchpad probing.
32
    UnsupportedHoster,
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
33
    )
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
34
35
from ... import (
0.432.2 by Jelmer Vernooij
Publish command sort of works.
36
    branch as _mod_branch,
37
    controldir,
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
38
    errors,
39
    hooks,
40
    urlutils,
41
    )
7408.2.1 by Jelmer Vernooij
Use standard functions for creating Git URLs.
42
from ...git.urls import git_url_to_bzr_url
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
43
from ...lazy_import import lazy_import
44
lazy_import(globals(), """
45
from breezy.plugins.launchpad import (
46
    lp_api,
7464.2.1 by Jelmer Vernooij
Fix finding merge proposals by URL.
47
    uris as lp_uris,
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
48
    )
7253 by Jelmer Vernooij
Fix default launchpadlib API URL.
49
50
from launchpadlib import uris
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
51
""")
0.432.2 by Jelmer Vernooij
Publish command sort of works.
52
from ...transport import get_transport
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
53
54
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
55
# TODO(jelmer): Make selection of launchpad staging a configuration option.
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
56
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
57
def status_to_lp_mp_statuses(status):
58
    statuses = []
59
    if status in ('open', 'all'):
60
        statuses.extend([
61
            'Work in progress',
62
            'Needs review',
63
            'Approved',
64
            'Code failed to merge',
65
            'Queued'])
66
    if status in ('closed', 'all'):
67
        statuses.extend(['Rejected', 'Superseded'])
68
    if status in ('merged', 'all'):
69
        statuses.append('Merged')
70
    return statuses
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
71
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
72
73
def plausible_launchpad_url(url):
74
    if url is None:
75
        return False
76
    if url.startswith('lp:'):
77
        return True
7322.2.1 by Martin
Fix invalid escape sequence warnings in regexps
78
    regex = re.compile(r'([a-z]*\+)*(bzr\+ssh|http|ssh|git|https)'
79
                       r'://(bazaar|git).*\.launchpad\.net')
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
80
    return bool(regex.match(url))
81
82
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
83
class WebserviceFailure(Exception):
84
85
    def __init__(self, message):
86
        self.message = message
87
88
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
89
def _call_webservice(call, *args, **kwargs):
90
    """Make a call to the webservice, wrapping failures.
91
92
    :param call: The call to make.
93
    :param *args: *args for the call.
94
    :param **kwargs: **kwargs for the call.
95
    :return: The result of calling call(*args, *kwargs).
96
    """
97
    from lazr.restfulclient import errors as restful_errors
98
    try:
99
        return call(*args, **kwargs)
100
    except restful_errors.HTTPError as e:
101
        error_lines = []
102
        for line in e.content.splitlines():
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
103
            if line.startswith(b'Traceback (most recent call last):'):
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
104
                break
105
            error_lines.append(line)
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
106
        raise WebserviceFailure(b''.join(error_lines))
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
107
108
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
109
class LaunchpadMergeProposal(MergeProposal):
110
111
    def __init__(self, mp):
112
        self._mp = mp
113
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
114
    def get_source_branch_url(self):
115
        if self._mp.source_branch:
116
            return self._mp.source_branch.bzr_identity
117
        else:
7408.2.1 by Jelmer Vernooij
Use standard functions for creating Git URLs.
118
            return git_url_to_bzr_url(
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
119
                self._mp.source_git_repository.git_identity,
7408.2.1 by Jelmer Vernooij
Use standard functions for creating Git URLs.
120
                ref=self._mp.source_git_path.encode('utf-8'))
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
121
122
    def get_target_branch_url(self):
123
        if self._mp.target_branch:
124
            return self._mp.target_branch.bzr_identity
125
        else:
7408.2.1 by Jelmer Vernooij
Use standard functions for creating Git URLs.
126
            return git_url_to_bzr_url(
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
127
                self._mp.target_git_repository.git_identity,
7408.2.1 by Jelmer Vernooij
Use standard functions for creating Git URLs.
128
                ref=self._mp.target_git_path.encode('utf-8'))
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
129
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
130
    @property
131
    def url(self):
132
        return lp_api.canonical_url(self._mp)
133
134
    def is_merged(self):
135
        return (self._mp.queue_status == 'Merged')
136
7381.5.1 by Jelmer Vernooij
Several more fixes for merge proposals. Add functions for reopening merge proposals.
137
    def is_closed(self):
138
        return (self._mp.queue_status in ('Rejected', 'Superseded'))
139
140
    def reopen(self):
141
        self._mp.setStatus(status='Needs review')
142
0.431.70 by Jelmer Vernooij
Implement get_description/set_description for LaunchpadMergeProposal.
143
    def get_description(self):
144
        return self._mp.description
145
146
    def set_description(self, description):
147
        self._mp.description = description
7290.5.1 by Jelmer Vernooij
Actually send API call to Launchpad when updating description.
148
        self._mp.lp_save()
0.431.70 by Jelmer Vernooij
Implement get_description/set_description for LaunchpadMergeProposal.
149
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
150
    def get_commit_message(self):
151
        return self._mp.commit_message
152
153
    def set_commit_message(self, commit_message):
154
        self._mp.commit_message = commit_message
155
        self._mp.lp_save()
156
7260.2.1 by Jelmer Vernooij
Implement .close on merge proposals.
157
    def close(self):
158
        self._mp.setStatus(status='Rejected')
159
7381.2.1 by Jelmer Vernooij
Implement LaunchpadMergeProposal.can_be_merged.
160
    def can_be_merged(self):
161
        if not self._mp.preview_diff:
162
            # Maybe?
163
            return True
164
        return not bool(self._mp.preview_diff.conflicts)
165
7414.4.1 by Jelmer Vernooij
Add a MergeProposal.get_merged_by method.
166
    def get_merged_by(self):
167
        merge_reporter = self._mp.merge_reporter
168
        if merge_reporter is None:
169
            return None
170
        return merge_reporter.name
171
7414.4.3 by Jelmer Vernooij
Add MergeProposal.get_merged_at.
172
    def get_merged_at(self):
173
        return self._mp.date_merged
174
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
175
    def merge(self, commit_message=None):
176
        target_branch = _mod_branch.Branch.open(
177
            self.get_target_branch_url())
178
        source_branch = _mod_branch.Branch.open(
179
            self.get_source_branch_url())
180
        # TODO(jelmer): Ideally this would use a memorytree, but merge doesn't
181
        # support that yet.
182
        # tree = target_branch.create_memorytree()
183
        tmpdir = tempfile.mkdtemp()
184
        try:
185
            tree = target_branch.create_checkout(
186
                to_location=tmpdir, lightweight=True)
187
            tree.merge_from_branch(source_branch)
188
            tree.commit(commit_message or self._mp.commit_message)
189
        finally:
190
            shutil.rmtree(tmpdir)
191
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
192
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
193
class Launchpad(Hoster):
194
    """The Launchpad hosting service."""
195
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
196
    name = 'launchpad'
197
0.431.29 by Jelmer Vernooij
Fix github branch name, add bug URL.
198
    # https://bugs.launchpad.net/launchpad/+bug/397676
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
199
    supports_merge_proposal_labels = False
200
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
201
    supports_merge_proposal_commit_message = True
202
7490.3.9 by Jelmer Vernooij
Add supports_allow_collaboration flag.
203
    supports_allow_collaboration = False
204
7445.1.1 by Jelmer Vernooij
Add Hoster.merge_proposal_description_format and common function for determining title.
205
    merge_proposal_description_format = 'plain'
206
7254.1.2 by Jelmer Vernooij
Fix propose Launchpad.
207
    def __init__(self, staging=False):
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
208
        self._staging = staging
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
209
        if staging:
7253 by Jelmer Vernooij
Fix default launchpadlib API URL.
210
            lp_base_url = uris.STAGING_SERVICE_ROOT
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
211
        else:
7253 by Jelmer Vernooij
Fix default launchpadlib API URL.
212
            lp_base_url = uris.LPNET_SERVICE_ROOT
7371.4.4 by Jelmer Vernooij
Pull in more fixes from janitor.
213
        self.launchpad = lp_api.connect_launchpad(lp_base_url, version='devel')
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
214
7260.1.1 by Jelmer Vernooij
Add .base_url property to Hoster.
215
    @property
216
    def base_url(self):
217
        return lp_api.uris.web_root_for_service_root(
218
            str(self.launchpad._root_uri))
219
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
220
    def __repr__(self):
221
        return "Launchpad(staging=%s)" % self._staging
222
223
    def hosts(self, branch):
224
        # TODO(jelmer): staging vs non-staging?
225
        return plausible_launchpad_url(branch.user_url)
226
0.432.2 by Jelmer Vernooij
Publish command sort of works.
227
    @classmethod
7296.10.1 by Jelmer Vernooij
Initial work making gitlab just directly use ReST.
228
    def probe_from_url(cls, url, possible_transports=None):
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
229
        if plausible_launchpad_url(url):
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
230
            return Launchpad()
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
231
        raise UnsupportedHoster(url)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
232
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
233
    def _get_lp_git_ref_from_branch(self, branch):
234
        url, params = urlutils.split_segment_parameters(branch.user_url)
235
        (scheme, user, password, host, port, path) = urlutils.parse_url(
236
            url)
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
237
        repo_lp = self.launchpad.git_repositories.getByPath(
238
            path=path.strip('/'))
0.431.26 by Jelmer Vernooij
Fix handling of proposals for Launchapd Git URLs.
239
        try:
240
            ref_path = params['ref']
241
        except KeyError:
242
            branch_name = params.get('branch', branch.name)
243
            if branch_name:
244
                ref_path = 'refs/heads/%s' % branch_name
245
            else:
246
                ref_path = repo_lp.default_branch
247
        ref_lp = repo_lp.getRefByPath(path=ref_path)
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
248
        return (repo_lp, ref_lp)
249
250
    def _get_lp_bzr_branch_from_branch(self, branch):
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
251
        return self.launchpad.branches.getByUrl(
252
            url=urlutils.unescape(branch.user_url))
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
253
0.431.23 by Jelmer Vernooij
Launchpad fixes.
254
    def _get_derived_git_path(self, base_path, owner, project):
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
255
        base_repo = self.launchpad.git_repositories.getByPath(path=base_path)
256
        if project is None:
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
257
            project = urlutils.parse_url(base_repo.git_ssh_url)[-1].strip('/')
258
        if project.startswith('~'):
259
            project = '/'.join(base_path.split('/')[1:])
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
260
        # TODO(jelmer): Surely there is a better way of creating one of these
261
        # URLs?
0.431.23 by Jelmer Vernooij
Launchpad fixes.
262
        return "~%s/%s" % (owner, project)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
263
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
264
    def _publish_git(self, local_branch, base_path, name, owner, project=None,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
265
                     revision_id=None, overwrite=False, allow_lossy=True,
266
                     tag_selector=None):
0.431.23 by Jelmer Vernooij
Launchpad fixes.
267
        to_path = self._get_derived_git_path(base_path, owner, project)
268
        to_transport = get_transport("git+ssh://git.launchpad.net/" + to_path)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
269
        try:
270
            dir_to = controldir.ControlDir.open_from_transport(to_transport)
271
        except errors.NotBranchError:
272
            # Didn't find anything
273
            dir_to = None
274
275
        if dir_to is None:
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
276
            try:
277
                br_to = local_branch.create_clone_on_transport(
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
278
                    to_transport, revision_id=revision_id, name=name,
279
                    tag_selector=tag_selector)
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
280
            except errors.NoRoundtrippingSupport:
281
                br_to = local_branch.create_clone_on_transport(
7211.13.7 by Jelmer Vernooij
Fix formatting.
282
                    to_transport, revision_id=revision_id, name=name,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
283
                    lossy=True, tag_selector=tag_selector)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
284
        else:
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
285
            try:
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
286
                dir_to = dir_to.push_branch(
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
287
                    local_branch, revision_id, overwrite=overwrite, name=name,
288
                    tag_selector=tag_selector)
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
289
            except errors.NoRoundtrippingSupport:
290
                if not allow_lossy:
291
                    raise
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
292
                dir_to = dir_to.push_branch(
293
                    local_branch, revision_id, overwrite=overwrite, name=name,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
294
                    lossy=True, tag_selector=tag_selector)
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
295
            br_to = dir_to.target_branch
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
296
        return br_to, (
297
            "https://git.launchpad.net/%s/+ref/%s" % (to_path, name))
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
298
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
299
    def _get_derived_bzr_path(self, base_branch, name, owner, project):
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
300
        if project is None:
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
301
            base_branch_lp = self._get_lp_bzr_branch_from_branch(base_branch)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
302
            project = '/'.join(base_branch_lp.unique_name.split('/')[1:-1])
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
303
        # TODO(jelmer): Surely there is a better way of creating one of these
304
        # URLs?
0.431.23 by Jelmer Vernooij
Launchpad fixes.
305
        return "~%s/%s/%s" % (owner, project, name)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
306
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
307
    def get_push_url(self, branch):
308
        (vcs, user, password, path, params) = self._split_url(branch.user_url)
309
        if vcs == 'bzr':
310
            branch_lp = self._get_lp_bzr_branch_from_branch(branch)
311
            return branch_lp.bzr_identity
312
        elif vcs == 'git':
313
            return urlutils.join_segment_parameters(
314
                "git+ssh://git.launchpad.net/" + path, params)
315
        else:
316
            raise AssertionError
317
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
318
    def _publish_bzr(self, local_branch, base_branch, name, owner,
319
                     project=None, revision_id=None, overwrite=False,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
320
                     allow_lossy=True, tag_selector=None):
0.431.25 by Jelmer Vernooij
Fix launchpad URL unescaping.
321
        to_path = self._get_derived_bzr_path(base_branch, name, owner, project)
0.431.23 by Jelmer Vernooij
Launchpad fixes.
322
        to_transport = get_transport("lp:" + to_path)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
323
        try:
324
            dir_to = controldir.ControlDir.open_from_transport(to_transport)
325
        except errors.NotBranchError:
326
            # Didn't find anything
327
            dir_to = None
328
329
        if dir_to is None:
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
330
            br_to = local_branch.create_clone_on_transport(
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
331
                to_transport, revision_id=revision_id, tag_selector=tag_selector)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
332
        else:
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
333
            br_to = dir_to.push_branch(
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
334
                local_branch, revision_id, overwrite=overwrite,
335
                tag_selector=tag_selector).target_branch
0.431.23 by Jelmer Vernooij
Launchpad fixes.
336
        return br_to, ("https://code.launchpad.net/" + to_path)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
337
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
338
    def _split_url(self, url):
339
        url, params = urlutils.split_segment_parameters(url)
340
        (scheme, user, password, host, port, path) = urlutils.parse_url(url)
341
        path = path.strip('/')
342
        if host.startswith('bazaar.'):
343
            vcs = 'bzr'
344
        elif host.startswith('git.'):
345
            vcs = 'git'
346
        else:
347
            raise ValueError("unknown host %s" % host)
348
        return (vcs, user, password, path, params)
349
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
350
    def publish_derived(self, local_branch, base_branch, name, project=None,
351
                        owner=None, revision_id=None, overwrite=False,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
352
                        allow_lossy=True, tag_selector=None):
0.432.2 by Jelmer Vernooij
Publish command sort of works.
353
        """Publish a branch to the site, derived from base_branch.
354
355
        :param base_branch: branch to derive the new branch from
356
        :param new_branch: branch to publish
357
        :param name: Name of the new branch on the remote host
358
        :param project: Optional project name
359
        :param owner: Optional owner
360
        :return: resulting branch
361
        """
362
        if owner is None:
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
363
            owner = self.launchpad.me.name
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
364
        (base_vcs, base_user, base_password, base_path,
365
            base_params) = self._split_url(base_branch.user_url)
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
366
        # TODO(jelmer): Prevent publishing to development focus
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
367
        if base_vcs == 'bzr':
7211.13.7 by Jelmer Vernooij
Fix formatting.
368
            return self._publish_bzr(
369
                local_branch, base_branch, name, project=project, owner=owner,
370
                revision_id=revision_id, overwrite=overwrite,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
371
                allow_lossy=allow_lossy, tag_selector=tag_selector)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
372
        elif base_vcs == 'git':
7211.13.7 by Jelmer Vernooij
Fix formatting.
373
            return self._publish_git(
374
                local_branch, base_path, name, project=project, owner=owner,
375
                revision_id=revision_id, overwrite=overwrite,
7489.4.2 by Jelmer Vernooij
Plumb through tag_selector.
376
                allow_lossy=allow_lossy, tag_selector=tag_selector)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
377
        else:
0.431.15 by Jelmer Vernooij
Initial work on support for git branches in launchpad.
378
            raise AssertionError('not a valid Launchpad URL')
0.432.2 by Jelmer Vernooij
Publish command sort of works.
379
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
380
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
381
        if owner is None:
382
            owner = self.launchpad.me.name
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
383
        (base_vcs, base_user, base_password, base_path,
384
            base_params) = self._split_url(base_branch.user_url)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
385
        if base_vcs == 'bzr':
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
386
            to_path = self._get_derived_bzr_path(
387
                base_branch, name, owner, project)
0.431.23 by Jelmer Vernooij
Launchpad fixes.
388
            return _mod_branch.Branch.open("lp:" + to_path)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
389
        elif base_vcs == 'git':
7211.13.7 by Jelmer Vernooij
Fix formatting.
390
            to_path = self._get_derived_git_path(
391
                base_path.strip('/'), owner, project)
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
392
            to_url = urlutils.join_segment_parameters(
7240.4.1 by Jelmer Vernooij
Merge lp:brz-propose.
393
                "git+ssh://git.launchpad.net/" + to_path,
394
                {'branch': name})
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
395
            return _mod_branch.Branch.open(to_url)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
396
        else:
397
            raise AssertionError('not a valid Launchpad URL')
398
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
399
    def iter_proposals(self, source_branch, target_branch, status='open'):
400
        (base_vcs, base_user, base_password, base_path,
401
            base_params) = self._split_url(target_branch.user_url)
402
        statuses = status_to_lp_mp_statuses(status)
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
403
        if base_vcs == 'bzr':
7211.13.7 by Jelmer Vernooij
Fix formatting.
404
            target_branch_lp = self.launchpad.branches.getByUrl(
405
                url=target_branch.user_url)
406
            source_branch_lp = self.launchpad.branches.getByUrl(
407
                url=source_branch.user_url)
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
408
            for mp in target_branch_lp.getMergeProposals(status=statuses):
409
                if mp.source_branch_link != source_branch_lp.self_link:
410
                    continue
411
                yield LaunchpadMergeProposal(mp)
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
412
        elif base_vcs == 'git':
7211.13.7 by Jelmer Vernooij
Fix formatting.
413
            (source_repo_lp, source_branch_lp) = (
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
414
                self._get_lp_git_ref_from_branch(source_branch))
7211.13.7 by Jelmer Vernooij
Fix formatting.
415
            (target_repo_lp, target_branch_lp) = (
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
416
                self._get_lp_git_ref_from_branch(target_branch))
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
417
            for mp in target_branch_lp.getMergeProposals(status=statuses):
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
418
                if (target_branch_lp.path != mp.target_git_path or
7211.13.7 by Jelmer Vernooij
Fix formatting.
419
                        target_repo_lp != mp.target_git_repository or
420
                        source_branch_lp.path != mp.source_git_path or
421
                        source_repo_lp != mp.source_git_repository):
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
422
                    continue
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
423
                yield LaunchpadMergeProposal(mp)
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
424
        else:
425
            raise AssertionError('not a valid Launchpad URL')
426
0.432.2 by Jelmer Vernooij
Publish command sort of works.
427
    def get_proposer(self, source_branch, target_branch):
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
428
        (base_vcs, base_user, base_password, base_path,
429
            base_params) = self._split_url(target_branch.user_url)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
430
        if base_vcs == 'bzr':
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
431
            return LaunchpadBazaarMergeProposalBuilder(
7211.13.7 by Jelmer Vernooij
Fix formatting.
432
                self, source_branch, target_branch)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
433
        elif base_vcs == 'git':
0.431.24 by Jelmer Vernooij
Support git merge proposals.
434
            return LaunchpadGitMergeProposalBuilder(
7211.13.7 by Jelmer Vernooij
Fix formatting.
435
                self, source_branch, target_branch)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
436
        else:
437
            raise AssertionError('not a valid Launchpad URL')
0.432.2 by Jelmer Vernooij
Publish command sort of works.
438
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
439
    @classmethod
440
    def iter_instances(cls):
441
        yield cls()
442
0.431.66 by Jelmer Vernooij
Add support for status argument.
443
    def iter_my_proposals(self, status='open'):
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
444
        statuses = status_to_lp_mp_statuses(status)
0.431.66 by Jelmer Vernooij
Add support for status argument.
445
        for mp in self.launchpad.me.getMergeProposals(status=statuses):
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
446
            yield LaunchpadMergeProposal(mp)
447
7414.5.2 by Jelmer Vernooij
Change iter_my_projects to iter_my_forks.
448
    def iter_my_forks(self):
449
        # Launchpad doesn't really have the concept of "forks"
7414.5.1 by Jelmer Vernooij
Add functions for managing projects.
450
        return iter([])
451
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
452
    def get_proposal_by_url(self, url):
453
        # Launchpad doesn't have a way to find a merge proposal by URL.
454
        (scheme, user, password, host, port, path) = urlutils.parse_url(
455
            url)
7296.9.2 by Jelmer Vernooij
Fix detection of launchpad hosts.
456
        LAUNCHPAD_CODE_DOMAINS = [
7464.2.1 by Jelmer Vernooij
Fix finding merge proposals by URL.
457
            ('code.%s' % domain) for domain in lp_uris.LAUNCHPAD_DOMAINS.values()]
7296.9.2 by Jelmer Vernooij
Fix detection of launchpad hosts.
458
        if host not in LAUNCHPAD_CODE_DOMAINS:
459
            raise UnsupportedHoster(url)
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
460
        # TODO(jelmer): Check if this is a launchpad URL. Otherwise, raise
461
        # UnsupportedHoster
462
        # See https://api.launchpad.net/devel/#branch_merge_proposal
463
        # the syntax is:
464
        # https://api.launchpad.net/devel/~<author.name>/<project.name>/<branch.name>/+merge/<id>
465
        api_url = str(self.launchpad._root_uri) + path
466
        mp = self.launchpad.load(api_url)
467
        return LaunchpadMergeProposal(mp)
468
0.432.2 by Jelmer Vernooij
Publish command sort of works.
469
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
470
class LaunchpadBazaarMergeProposalBuilder(MergeProposalBuilder):
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
471
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
472
    def __init__(self, lp_host, source_branch, target_branch,
0.432.2 by Jelmer Vernooij
Publish command sort of works.
473
                 staging=None, approve=None, fixes=None):
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
474
        """Constructor.
475
476
        :param source_branch: The branch to propose for merging.
477
        :param target_branch: The branch to merge into.
478
        :param staging: If True, propose the merge against staging instead of
479
            production.
480
        :param approve: If True, mark the new proposal as approved immediately.
481
            This is useful when a project permits some things to be approved
482
            by the submitter (e.g. merges between release and deployment
483
            branches).
484
        """
0.431.26 by Jelmer Vernooij
Fix handling of proposals for Launchapd Git URLs.
485
        self.lp_host = lp_host
486
        self.launchpad = lp_host.launchpad
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
487
        self.source_branch = source_branch
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
488
        self.source_branch_lp = self.launchpad.branches.getByUrl(
489
            url=source_branch.user_url)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
490
        if target_branch is None:
0.431.24 by Jelmer Vernooij
Support git merge proposals.
491
            self.target_branch_lp = self.source_branch_lp.get_target()
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
492
            self.target_branch = _mod_branch.Branch.open(
493
                self.target_branch_lp.bzr_identity)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
494
        else:
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
495
            self.target_branch = target_branch
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
496
            self.target_branch_lp = self.launchpad.branches.getByUrl(
497
                url=target_branch.user_url)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
498
        self.approve = approve
499
        self.fixes = fixes
500
501
    def get_infotext(self):
502
        """Determine the initial comment for the merge proposal."""
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
503
        info = ["Source: %s\n" % self.source_branch_lp.bzr_identity]
504
        info.append("Target: %s\n" % self.target_branch_lp.bzr_identity)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
505
        return ''.join(info)
506
507
    def get_initial_body(self):
508
        """Get a body for the proposal for the user to modify.
509
510
        :return: a str or None.
511
        """
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
512
        if not self.hooks['merge_proposal_body']:
513
            return None
514
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
515
        def list_modified_files():
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
516
            lca_tree = self.source_branch_lp.find_lca_tree(
517
                self.target_branch_lp)
518
            source_tree = self.source_branch.basis_tree()
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
519
            files = modified_files(lca_tree, source_tree)
520
            return list(files)
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
521
        with self.target_branch.lock_read(), \
522
                self.source_branch.lock_read():
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
523
            body = None
524
            for hook in self.hooks['merge_proposal_body']:
525
                body = hook({
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
526
                    'target_branch': self.target_branch_lp.bzr_identity,
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
527
                    'modified_files_callback': list_modified_files,
528
                    'old_body': body,
529
                })
530
            return body
531
532
    def check_proposal(self):
533
        """Check that the submission is sensible."""
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
534
        if self.source_branch_lp.self_link == self.target_branch_lp.self_link:
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
535
            raise errors.BzrCommandError(
536
                'Source and target branches must be different.')
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
537
        for mp in self.source_branch_lp.landing_targets:
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
538
            if mp.queue_status in ('Merged', 'Rejected'):
539
                continue
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
540
            if mp.target_branch.self_link == self.target_branch_lp.self_link:
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
541
                raise MergeProposalExists(lp_api.canonical_url(mp))
542
543
    def approve_proposal(self, mp):
0.431.11 by Jelmer Vernooij
Fix launchpad handling.
544
        with self.source_branch.lock_read():
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
545
            _call_webservice(
546
                mp.createComment,
547
                vote=u'Approve',
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
548
                subject='',  # Use the default subject.
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
549
                content=u"Rubberstamp! Proposer approves of own proposal.")
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
550
            _call_webservice(mp.setStatus, status=u'Approved',
551
                             revid=self.source_branch.last_revision())
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
552
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
553
    def create_proposal(self, description, reviewers=None, labels=None,
7467.3.1 by Jelmer Vernooij
Add a work_in_progress flag.
554
                        prerequisite_branch=None, commit_message=None,
7490.6.1 by Jelmer Vernooij
Add allow-collaboration flag.
555
                        work_in_progress=False, allow_collaboration=False):
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
556
        """Perform the submission."""
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
557
        if labels:
7295.2.1 by Jelmer Vernooij
Fix some issues reported by lgtm.com.
558
            raise LabelsUnsupported(self)
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
559
        if prerequisite_branch is not None:
560
            prereq = self.launchpad.branches.getByUrl(
561
                url=prerequisite_branch.user_url)
562
        else:
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
563
            prereq = None
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
564
        if reviewers is None:
7381.5.1 by Jelmer Vernooij
Several more fixes for merge proposals. Add functions for reopening merge proposals.
565
            reviewer_objs = []
566
        else:
567
            reviewer_objs = []
568
            for reviewer in reviewers:
569
                if '@' in reviewer:
570
                    reviewer_obj = self.launchpad.people.getByEmail(email=reviewer)
571
                else:
572
                    reviewer_obj = self.launchpad.people[reviewer]
573
                reviewer_objs.append(reviewer_obj)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
574
        try:
575
            mp = _call_webservice(
576
                self.source_branch_lp.createMergeProposal,
577
                target_branch=self.target_branch_lp,
578
                prerequisite_branch=prereq,
0.431.42 by Jelmer Vernooij
Remove unnecessary encode (breaks on Python 3).
579
                initial_comment=description.strip(),
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
580
                commit_message=commit_message,
7467.3.1 by Jelmer Vernooij
Add a work_in_progress flag.
581
                needs_review=(not work_in_progress),
7381.5.5 by Jelmer Vernooij
Review feedback.
582
                reviewers=[reviewer.self_link for reviewer in reviewer_objs],
583
                review_types=['' for reviewer in reviewer_objs])
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
584
        except WebserviceFailure as e:
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
585
            # Urgh.
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
586
            if (b'There is already a branch merge proposal '
7211.13.7 by Jelmer Vernooij
Fix formatting.
587
                    b'registered for branch ') in e.message:
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
588
                raise MergeProposalExists(self.source_branch.user_url)
589
            raise
590
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
591
        if self.approve:
592
            self.approve_proposal(mp)
593
        if self.fixes:
594
            if self.fixes.startswith('lp:'):
595
                self.fixes = self.fixes[3:]
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
596
            _call_webservice(
597
                mp.linkBug,
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
598
                bug=self.launchpad.bugs[int(self.fixes)])
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
599
        return LaunchpadMergeProposal(mp)
0.431.24 by Jelmer Vernooij
Support git merge proposals.
600
601
602
class LaunchpadGitMergeProposalBuilder(MergeProposalBuilder):
603
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
604
    def __init__(self, lp_host, source_branch, target_branch,
0.431.24 by Jelmer Vernooij
Support git merge proposals.
605
                 staging=None, approve=None, fixes=None):
606
        """Constructor.
607
608
        :param source_branch: The branch to propose for merging.
609
        :param target_branch: The branch to merge into.
610
        :param staging: If True, propose the merge against staging instead of
611
            production.
612
        :param approve: If True, mark the new proposal as approved immediately.
613
            This is useful when a project permits some things to be approved
614
            by the submitter (e.g. merges between release and deployment
615
            branches).
616
        """
0.431.26 by Jelmer Vernooij
Fix handling of proposals for Launchapd Git URLs.
617
        self.lp_host = lp_host
618
        self.launchpad = lp_host.launchpad
0.431.24 by Jelmer Vernooij
Support git merge proposals.
619
        self.source_branch = source_branch
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
620
        (self.source_repo_lp,
621
            self.source_branch_lp) = self.lp_host._get_lp_git_ref_from_branch(
622
                source_branch)
0.431.24 by Jelmer Vernooij
Support git merge proposals.
623
        if target_branch is None:
624
            self.target_branch_lp = self.source_branch.get_target()
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
625
            self.target_branch = _mod_branch.Branch.open(
626
                self.target_branch_lp.git_https_url)
0.431.24 by Jelmer Vernooij
Support git merge proposals.
627
        else:
628
            self.target_branch = target_branch
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
629
            (self.target_repo_lp, self.target_branch_lp) = (
630
                self.lp_host._get_lp_git_ref_from_branch(target_branch))
0.431.24 by Jelmer Vernooij
Support git merge proposals.
631
        self.approve = approve
632
        self.fixes = fixes
633
634
    def get_infotext(self):
635
        """Determine the initial comment for the merge proposal."""
636
        info = ["Source: %s\n" % self.source_branch.user_url]
637
        info.append("Target: %s\n" % self.target_branch.user_url)
638
        return ''.join(info)
639
640
    def get_initial_body(self):
641
        """Get a body for the proposal for the user to modify.
642
643
        :return: a str or None.
644
        """
645
        if not self.hooks['merge_proposal_body']:
646
            return None
647
648
        def list_modified_files():
649
            lca_tree = self.source_branch_lp.find_lca_tree(
650
                self.target_branch_lp)
651
            source_tree = self.source_branch.basis_tree()
652
            files = modified_files(lca_tree, source_tree)
653
            return list(files)
654
        with self.target_branch.lock_read(), \
655
                self.source_branch.lock_read():
656
            body = None
657
            for hook in self.hooks['merge_proposal_body']:
658
                body = hook({
659
                    'target_branch': self.target_branch,
660
                    'modified_files_callback': list_modified_files,
661
                    'old_body': body,
662
                })
663
            return body
664
665
    def check_proposal(self):
666
        """Check that the submission is sensible."""
667
        if self.source_branch_lp.self_link == self.target_branch_lp.self_link:
668
            raise errors.BzrCommandError(
669
                'Source and target branches must be different.')
670
        for mp in self.source_branch_lp.landing_targets:
671
            if mp.queue_status in ('Merged', 'Rejected'):
672
                continue
673
            if mp.target_branch.self_link == self.target_branch_lp.self_link:
674
                raise MergeProposalExists(lp_api.canonical_url(mp))
675
676
    def approve_proposal(self, mp):
677
        with self.source_branch.lock_read():
678
            _call_webservice(
679
                mp.createComment,
680
                vote=u'Approve',
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
681
                subject='',  # Use the default subject.
0.431.24 by Jelmer Vernooij
Support git merge proposals.
682
                content=u"Rubberstamp! Proposer approves of own proposal.")
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
683
            _call_webservice(
684
                mp.setStatus, status=u'Approved',
685
                revid=self.source_branch.last_revision())
0.431.24 by Jelmer Vernooij
Support git merge proposals.
686
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
687
    def create_proposal(self, description, reviewers=None, labels=None,
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
688
                        prerequisite_branch=None, commit_message=None):
0.431.24 by Jelmer Vernooij
Support git merge proposals.
689
        """Perform the submission."""
690
        if labels:
7295.2.1 by Jelmer Vernooij
Fix some issues reported by lgtm.com.
691
            raise LabelsUnsupported(self)
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
692
        if prerequisite_branch is not None:
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
693
            (prereq_repo_lp, prereq_branch_lp) = (
694
                self.lp_host._get_lp_git_ref_from_branch(prerequisite_branch))
0.431.24 by Jelmer Vernooij
Support git merge proposals.
695
        else:
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
696
            prereq_branch_lp = None
0.431.24 by Jelmer Vernooij
Support git merge proposals.
697
        if reviewers is None:
698
            reviewers = []
699
        try:
700
            mp = _call_webservice(
701
                self.source_branch_lp.createMergeProposal,
702
                merge_target=self.target_branch_lp,
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
703
                merge_prerequisite=prereq_branch_lp,
0.431.71 by Jelmer Vernooij
Some fixes for Git on Launchpad.
704
                initial_comment=description.strip(),
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
705
                commit_message=commit_message,
0.431.24 by Jelmer Vernooij
Support git merge proposals.
706
                needs_review=True,
707
                reviewers=[self.launchpad.people[reviewer].self_link
708
                           for reviewer in reviewers],
709
                review_types=[None for reviewer in reviewers])
0.431.58 by Jelmer Vernooij
Fix python3 compatibility.
710
        except WebserviceFailure as e:
0.431.24 by Jelmer Vernooij
Support git merge proposals.
711
            # Urgh.
712
            if ('There is already a branch merge proposal '
7211.13.7 by Jelmer Vernooij
Fix formatting.
713
                    'registered for branch ') in e.message:
0.431.24 by Jelmer Vernooij
Support git merge proposals.
714
                raise MergeProposalExists(self.source_branch.user_url)
715
            raise
716
        if self.approve:
717
            self.approve_proposal(mp)
718
        if self.fixes:
719
            if self.fixes.startswith('lp:'):
720
                self.fixes = self.fixes[3:]
721
            _call_webservice(
722
                mp.linkBug,
723
                bug=self.launchpad.bugs[int(self.fixes)])
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
724
        return LaunchpadMergeProposal(mp)
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
725
726
727
def modified_files(old_tree, new_tree):
728
    """Return a list of paths in the new tree with modified contents."""
7322.1.6 by Jelmer Vernooij
Use the new attributes on TreeChange.
729
    for change in new_tree.iter_changes(old_tree):
730
        if change.changed_content and change.kind[1] == 'file':
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
731
            yield str(path)