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