/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
1
# Copyright (C) 2018 Breezy Developers
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
0.434.1 by Jelmer Vernooij
Use absolute_import.
17
"""Support for GitHub."""
18
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
19
from __future__ import absolute_import
20
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
21
import os
22
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
23
from .propose import (
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
24
    Hoster,
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
25
    HosterLoginRequired,
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
26
    MergeProposal,
0.432.2 by Jelmer Vernooij
Publish command sort of works.
27
    MergeProposalBuilder,
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
28
    MergeProposalExists,
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
29
    PrerequisiteBranchUnsupported,
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
30
    CommitMessageUnsupported,
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
31
    UnsupportedHoster,
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
32
    )
33
34
from ... import (
0.431.33 by Jelmer Vernooij
Fix URLs from gitlab.
35
    branch as _mod_branch,
0.432.3 by Jelmer Vernooij
Publish command works for github.
36
    controldir,
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
37
    errors,
38
    hooks,
39
    urlutils,
0.432.3 by Jelmer Vernooij
Publish command works for github.
40
    version_string as breezy_version,
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
41
    )
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
42
from ...config import AuthenticationConfig, GlobalStack, config_dir
0.431.32 by Jelmer Vernooij
Properly resolve git+ssh URLs.
43
from ...git.urls import git_url_to_bzr_url
0.432.3 by Jelmer Vernooij
Publish command works for github.
44
from ...i18n import gettext
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
45
from ...sixish import PY3
0.432.3 by Jelmer Vernooij
Publish command works for github.
46
from ...trace import note
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
47
from ...lazy_import import lazy_import
48
lazy_import(globals(), """
49
from github import Github
50
""")
51
52
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
53
def store_github_token(scheme, host, token):
54
    with open(os.path.join(config_dir(), 'github.conf'), 'w') as f:
55
        f.write(token)
56
57
58
def retrieve_github_token(scheme, host):
59
    path = os.path.join(config_dir(), 'github.conf')
60
    if not os.path.exists(path):
61
        return None
0.435.1 by Jelmer Vernooij
Fix reading github credentials.
62
    with open(path, 'r') as f:
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
63
        return f.read().strip()
64
65
0.431.44 by Jelmer Vernooij
Support get/set description.
66
def determine_title(description):
67
    return description.splitlines()[0]
68
69
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
70
class NotGitHubUrl(errors.BzrError):
71
72
    _fmt = "Not a GitHub URL: %(url)s"
73
74
    def __init__(self, url):
75
        errors.BzrError.__init__(self)
76
        self.url = url
77
78
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
79
class GitHubLoginRequired(HosterLoginRequired):
80
81
    _fmt = "Action requires GitHub login."
82
83
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
84
def connect_github():
7211.13.7 by Jelmer Vernooij
Fix formatting.
85
    """Connect to GitHub.
86
    """
87
    user_agent = "Breezy/%s" % breezy_version
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
88
89
    auth = AuthenticationConfig()
90
91
    credentials = auth.get_credentials('https', 'github.com')
92
    if credentials is not None:
0.432.3 by Jelmer Vernooij
Publish command works for github.
93
        return Github(credentials['user'], credentials['password'],
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
94
                      user_agent=user_agent)
95
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
96
    # TODO(jelmer): token = auth.get_token('https', 'github.com')
97
    token = retrieve_github_token('https', 'github.com')
98
    if token is not None:
0.431.61 by Jelmer Vernooij
Fix token login.
99
        return Github(token, user_agent=user_agent)
0.431.49 by Jelmer Vernooij
Store GitHub tokens in a magic file, for now.
100
    else:
101
        note('Accessing GitHub anonymously. To log in, run \'brz gh-login\'.')
102
        return Github(user_agent=user_agent)
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
103
104
0.431.44 by Jelmer Vernooij
Support get/set description.
105
class GitHubMergeProposal(MergeProposal):
106
107
    def __init__(self, pr):
108
        self._pr = pr
109
110
    @property
111
    def url(self):
112
        return self._pr.html_url
113
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
114
    def _branch_from_part(self, part):
115
        return github_url_to_bzr_url(part.repo.html_url, part.ref)
116
117
    def get_source_branch_url(self):
118
        return self._branch_from_part(self._pr.head)
119
120
    def get_target_branch_url(self):
121
        return self._branch_from_part(self._pr.base)
122
0.431.44 by Jelmer Vernooij
Support get/set description.
123
    def get_description(self):
124
        return self._pr.body
125
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
126
    def get_commit_message(self):
127
        return None
128
0.431.44 by Jelmer Vernooij
Support get/set description.
129
    def set_description(self, description):
130
        self._pr.edit(body=description, title=determine_title(description))
131
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
132
    def is_merged(self):
133
        return self._pr.merged
134
7260.2.1 by Jelmer Vernooij
Implement .close on merge proposals.
135
    def close(self):
136
        self._pr.edit(state='closed')
137
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
138
    def merge(self, commit_message=None):
139
        # https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
140
        self._pr.merge(commit_message=commit_message)
141
0.431.44 by Jelmer Vernooij
Support get/set description.
142
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
143
def parse_github_url(url):
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
144
    (scheme, user, password, host, port, path) = urlutils.parse_url(
145
        url)
146
    if host != 'github.com':
147
        raise NotGitHubUrl(url)
148
    (owner, repo_name) = path.strip('/').split('/')
0.432.12 by Jelmer Vernooij
Fix .git ends.
149
    if repo_name.endswith('.git'):
150
        repo_name = repo_name[:-4]
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
151
    return owner, repo_name
152
153
154
def parse_github_branch_url(branch):
155
    url = urlutils.split_segment_parameters(branch.user_url)[0]
156
    owner, repo_name = parse_github_url(url)
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
157
    return owner, repo_name, branch.name
158
159
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
160
def github_url_to_bzr_url(url, branch_name):
161
    if not PY3:
162
        branch_name = branch_name.encode('utf-8')
163
    return urlutils.join_segment_parameters(
7211.13.7 by Jelmer Vernooij
Fix formatting.
164
        git_url_to_bzr_url(url), {"branch": branch_name})
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
165
166
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
167
def convert_github_error(fn):
168
    def convert(self, *args, **kwargs):
169
        import github
170
        try:
171
            return fn(self, *args, **kwargs)
172
        except github.GithubException as e:
173
            if e.args[0] == 401:
174
                raise GitHubLoginRequired(self)
175
            raise
176
    return convert
177
178
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
179
class GitHub(Hoster):
180
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
181
    name = 'github'
182
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
183
    supports_merge_proposal_labels = True
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
184
    supports_merge_proposal_commit_message = False
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
185
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
186
    def __repr__(self):
187
        return "GitHub()"
188
7260.1.1 by Jelmer Vernooij
Add .base_url property to Hoster.
189
    @property
190
    def base_url(self):
191
        # TODO(jelmer): Can we get the default URL from the Python API package
192
        # somehow?
193
        return "https://github.com"
194
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
195
    def __init__(self):
196
        self.gh = connect_github()
197
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
198
    @convert_github_error
0.431.20 by Jelmer Vernooij
publish -> publish_derived.
199
    def publish_derived(self, local_branch, base_branch, name, project=None,
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
200
                        owner=None, revision_id=None, overwrite=False,
201
                        allow_lossy=True):
0.432.12 by Jelmer Vernooij
Fix .git ends.
202
        import github
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
203
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
204
        base_repo = self.gh.get_repo('%s/%s' % (base_owner, base_project))
0.432.3 by Jelmer Vernooij
Publish command works for github.
205
        if owner is None:
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
206
            owner = self.gh.get_user().login
0.432.3 by Jelmer Vernooij
Publish command works for github.
207
        if project is None:
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
208
            project = base_repo.name
0.432.3 by Jelmer Vernooij
Publish command works for github.
209
        try:
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
210
            remote_repo = self.gh.get_repo('%s/%s' % (owner, project))
0.432.12 by Jelmer Vernooij
Fix .git ends.
211
            remote_repo.id
212
        except github.UnknownObjectException:
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
213
            base_repo = self.gh.get_repo('%s/%s' % (base_owner, base_project))
214
            if owner == self.gh.get_user().login:
215
                owner_obj = self.gh.get_user()
0.432.3 by Jelmer Vernooij
Publish command works for github.
216
            else:
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
217
                owner_obj = self.gh.get_organization(owner)
0.432.12 by Jelmer Vernooij
Fix .git ends.
218
            remote_repo = owner_obj.create_fork(base_repo)
0.432.3 by Jelmer Vernooij
Publish command works for github.
219
            note(gettext('Forking new repository %s from %s') %
7211.13.7 by Jelmer Vernooij
Fix formatting.
220
                 (remote_repo.html_url, base_repo.html_url))
0.432.3 by Jelmer Vernooij
Publish command works for github.
221
        else:
222
            note(gettext('Reusing existing repository %s') % remote_repo.html_url)
0.431.32 by Jelmer Vernooij
Properly resolve git+ssh URLs.
223
        remote_dir = controldir.ControlDir.open(git_url_to_bzr_url(remote_repo.ssh_url))
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
224
        try:
7211.13.7 by Jelmer Vernooij
Fix formatting.
225
            push_result = remote_dir.push_branch(
226
                local_branch, revision_id=revision_id, overwrite=overwrite,
227
                name=name)
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
228
        except errors.NoRoundtrippingSupport:
229
            if not allow_lossy:
230
                raise
7211.13.7 by Jelmer Vernooij
Fix formatting.
231
            push_result = remote_dir.push_branch(
232
                local_branch, revision_id=revision_id,
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
233
                overwrite=overwrite, name=name, lossy=True)
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
234
        return push_result.target_branch, github_url_to_bzr_url(
7211.13.7 by Jelmer Vernooij
Fix formatting.
235
            remote_repo.html_url, name)
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
236
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
237
    @convert_github_error
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
238
    def get_push_url(self, branch):
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
239
        owner, project, branch_name = parse_github_branch_url(branch)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
240
        repo = self.gh.get_repo('%s/%s' % (owner, project))
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
241
        return github_url_to_bzr_url(repo.ssh_url, branch_name)
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
242
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
243
    @convert_github_error
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
244
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
245
        import github
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
246
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
247
        base_repo = self.gh.get_repo('%s/%s' % (base_owner, base_project))
248
        if owner is None:
249
            owner = self.gh.get_user().login
250
        if project is None:
251
            project = base_repo.name
252
        try:
253
            remote_repo = self.gh.get_repo('%s/%s' % (owner, project))
0.433.3 by Jelmer Vernooij
Some python 3 compatibility.
254
            full_url = github_url_to_bzr_url(remote_repo.ssh_url, name)
0.431.33 by Jelmer Vernooij
Fix URLs from gitlab.
255
            return _mod_branch.Branch.open(full_url)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
256
        except github.UnknownObjectException:
257
            raise errors.NotBranchError('https://github.com/%s/%s' % (owner, project))
258
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
259
    @convert_github_error
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
260
    def get_proposer(self, source_branch, target_branch):
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
261
        return GitHubMergeProposalBuilder(self.gh, source_branch, target_branch)
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
262
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
263
    @convert_github_error
0.431.68 by Jelmer Vernooij
Add status to other Hosters.
264
    def iter_proposals(self, source_branch, target_branch, status='open'):
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
265
        (source_owner, source_repo_name, source_branch_name) = (
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
266
            parse_github_branch_url(source_branch))
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
267
        (target_owner, target_repo_name, target_branch_name) = (
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
268
            parse_github_branch_url(target_branch))
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
269
        target_repo = self.gh.get_repo(
270
            "%s/%s" % (target_owner, target_repo_name))
0.431.68 by Jelmer Vernooij
Add status to other Hosters.
271
        state = {
272
            'open': 'open',
273
            'merged': 'closed',
274
            'closed': 'closed',
275
            'all': 'all'}
276
        for pull in target_repo.get_pulls(
277
                head=target_branch_name,
278
                state=state[status]):
279
            if (status == 'closed' and pull.merged or
280
                    status == 'merged' and not pull.merged):
281
                continue
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
282
            if pull.head.ref != source_branch_name:
283
                continue
7268.4.1 by Jelmer Vernooij
Don't attempt to resolve None when repo has gone away.
284
            if pull.head.repo is None:
285
                # Repo has gone the way of the dodo
286
                continue
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
287
            if (pull.head.repo.owner.login != source_owner or
7211.13.7 by Jelmer Vernooij
Fix formatting.
288
                    pull.head.repo.name != source_repo_name):
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
289
                continue
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
290
            yield GitHubMergeProposal(pull)
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
291
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
292
    def hosts(self, branch):
293
        try:
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
294
            parse_github_branch_url(branch)
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
295
        except NotGitHubUrl:
296
            return False
297
        else:
298
            return True
299
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
300
    @classmethod
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
301
    def probe_from_url(cls, url):
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
302
        try:
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
303
            parse_github_url(url)
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
304
        except NotGitHubUrl:
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
305
            raise UnsupportedHoster(url)
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
306
        return cls()
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
307
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
308
    @classmethod
309
    def iter_instances(cls):
310
        yield cls()
311
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
312
    @convert_github_error
0.431.66 by Jelmer Vernooij
Add support for status argument.
313
    def iter_my_proposals(self, status='open'):
314
        query = ['is:pr']
315
        if status == 'open':
316
            query.append('is:open')
317
        elif status == 'closed':
318
            query.append('is:unmerged')
7268.2.1 by Jelmer Vernooij
Don't include open unmerged pull requests in 'closed'.
319
            # Also use "is:closed" otherwise unmerged open pull requests are
320
            # also included.
321
            query.append('is:closed')
0.431.66 by Jelmer Vernooij
Add support for status argument.
322
        elif status == 'merged':
323
            query.append('is:merged')
324
        query.append('author:%s' % self.gh.get_user().login)
325
        for issue in self.gh.search_issues(query=' '.join(query)):
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
326
            yield GitHubMergeProposal(issue.as_pull_request())
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
327
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
328
    @convert_github_error
329
    def get_proposal_by_url(self, url):
330
        raise UnsupportedHoster(url)
331
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
332
0.432.2 by Jelmer Vernooij
Publish command sort of works.
333
class GitHubMergeProposalBuilder(MergeProposalBuilder):
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
334
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
335
    def __init__(self, gh, source_branch, target_branch):
336
        self.gh = gh
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
337
        self.source_branch = source_branch
338
        self.target_branch = target_branch
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
339
        (self.target_owner, self.target_repo_name, self.target_branch_name) = (
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
340
            parse_github_branch_url(self.target_branch))
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
341
        (self.source_owner, self.source_repo_name, self.source_branch_name) = (
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
342
            parse_github_branch_url(self.source_branch))
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
343
344
    def get_infotext(self):
345
        """Determine the initial comment for the merge proposal."""
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
346
        info = []
347
        info.append("Merge %s into %s:%s\n" % (
348
            self.source_branch_name, self.target_owner,
349
            self.target_branch_name))
350
        info.append("Source: %s\n" % self.source_branch.user_url)
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
351
        info.append("Target: %s\n" % self.target_branch.user_url)
352
        return ''.join(info)
353
354
    def get_initial_body(self):
355
        """Get a body for the proposal for the user to modify.
356
357
        :return: a str or None.
358
        """
359
        return None
360
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
361
    def create_proposal(self, description, reviewers=None, labels=None,
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
362
                        prerequisite_branch=None, commit_message=None):
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
363
        """Perform the submission."""
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
364
        if prerequisite_branch is not None:
365
            raise PrerequisiteBranchUnsupported(self)
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
366
        # Note that commit_message is ignored, since github doesn't support it.
0.432.10 by Jelmer Vernooij
More test fixes.
367
        import github
0.432.7 by Jelmer Vernooij
propose works \o/
368
        # TODO(jelmer): Probe for right repo name
0.432.12 by Jelmer Vernooij
Fix .git ends.
369
        if self.target_repo_name.endswith('.git'):
370
            self.target_repo_name = self.target_repo_name[:-4]
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
371
        target_repo = self.gh.get_repo("%s/%s" % (self.target_owner, self.target_repo_name))
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
372
        # TODO(jelmer): Allow setting title explicitly?
0.431.44 by Jelmer Vernooij
Support get/set description.
373
        title = determine_title(description)
0.431.4 by Jelmer Vernooij
Add basic GitHub support.
374
        # TOOD(jelmer): Set maintainers_can_modify?
0.432.10 by Jelmer Vernooij
More test fixes.
375
        try:
376
            pull_request = target_repo.create_pull(
377
                title=title, body=description,
378
                head="%s:%s" % (self.source_owner, self.source_branch_name),
379
                base=self.target_branch_name)
380
        except github.GithubException as e:
381
            if e.status == 422:
382
                raise MergeProposalExists(self.source_branch.user_url)
383
            raise
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
384
        if reviewers:
385
            for reviewer in reviewers:
386
                pull_request.assignees.append(
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
387
                    self.gh.get_user(reviewer))
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
388
        if labels:
389
            for label in labels:
390
                pull_request.issue.labels.append(label)
0.431.44 by Jelmer Vernooij
Support get/set description.
391
        return GitHubMergeProposal(pull_request)