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