/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/propose/github.py

  • Committer: Jelmer Vernooij
  • Date: 2019-03-02 22:31:28 UTC
  • mfrom: (7291 work)
  • mto: This revision was merged to the branch mainline in revision 7293.
  • Revision ID: jelmer@jelmer.uk-20190302223128-0qk1i5tozmzq5nyq
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
from .propose import (
24
24
    Hoster,
 
25
    HosterLoginRequired,
25
26
    MergeProposal,
26
27
    MergeProposalBuilder,
27
28
    MergeProposalExists,
74
75
        self.url = url
75
76
 
76
77
 
 
78
class GitHubLoginRequired(HosterLoginRequired):
 
79
 
 
80
    _fmt = "Action requires GitHub login."
 
81
 
 
82
 
77
83
def connect_github():
78
84
    """Connect to GitHub.
79
85
    """
126
132
        self._pr.edit(state='closed')
127
133
 
128
134
 
129
 
def parse_github_url(branch):
130
 
    url = urlutils.split_segment_parameters(branch.user_url)[0]
 
135
def parse_github_url(url):
131
136
    (scheme, user, password, host, port, path) = urlutils.parse_url(
132
137
        url)
133
138
    if host != 'github.com':
135
140
    (owner, repo_name) = path.strip('/').split('/')
136
141
    if repo_name.endswith('.git'):
137
142
        repo_name = repo_name[:-4]
 
143
    return owner, repo_name
 
144
 
 
145
 
 
146
def parse_github_branch_url(branch):
 
147
    url = urlutils.split_segment_parameters(branch.user_url)[0]
 
148
    owner, repo_name = parse_github_url(url)
138
149
    return owner, repo_name, branch.name
139
150
 
140
151
 
145
156
        git_url_to_bzr_url(url), {"branch": branch_name})
146
157
 
147
158
 
 
159
def convert_github_error(fn):
 
160
    def convert(self, *args, **kwargs):
 
161
        import github
 
162
        try:
 
163
            return fn(self, *args, **kwargs)
 
164
        except github.GithubException as e:
 
165
            if e.args[0] == 401:
 
166
                raise GitHubLoginRequired(self)
 
167
            raise
 
168
    return convert
 
169
 
 
170
 
148
171
class GitHub(Hoster):
149
172
 
150
173
    name = 'github'
163
186
    def __init__(self):
164
187
        self.gh = connect_github()
165
188
 
 
189
    @convert_github_error
166
190
    def publish_derived(self, local_branch, base_branch, name, project=None,
167
191
                        owner=None, revision_id=None, overwrite=False,
168
192
                        allow_lossy=True):
169
193
        import github
170
 
        base_owner, base_project, base_branch_name = parse_github_url(base_branch)
 
194
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
171
195
        base_repo = self.gh.get_repo('%s/%s' % (base_owner, base_project))
172
196
        if owner is None:
173
197
            owner = self.gh.get_user().login
201
225
        return push_result.target_branch, github_url_to_bzr_url(
202
226
            remote_repo.html_url, name)
203
227
 
 
228
    @convert_github_error
204
229
    def get_push_url(self, branch):
205
 
        owner, project, branch_name = parse_github_url(branch)
 
230
        owner, project, branch_name = parse_github_branch_url(branch)
206
231
        repo = self.gh.get_repo('%s/%s' % (owner, project))
207
232
        return github_url_to_bzr_url(repo.ssh_url, branch_name)
208
233
 
 
234
    @convert_github_error
209
235
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
210
236
        import github
211
 
        base_owner, base_project, base_branch_name = parse_github_url(base_branch)
 
237
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
212
238
        base_repo = self.gh.get_repo('%s/%s' % (base_owner, base_project))
213
239
        if owner is None:
214
240
            owner = self.gh.get_user().login
221
247
        except github.UnknownObjectException:
222
248
            raise errors.NotBranchError('https://github.com/%s/%s' % (owner, project))
223
249
 
 
250
    @convert_github_error
224
251
    def get_proposer(self, source_branch, target_branch):
225
252
        return GitHubMergeProposalBuilder(self.gh, source_branch, target_branch)
226
253
 
 
254
    @convert_github_error
227
255
    def iter_proposals(self, source_branch, target_branch, status='open'):
228
256
        (source_owner, source_repo_name, source_branch_name) = (
229
 
            parse_github_url(source_branch))
 
257
            parse_github_branch_url(source_branch))
230
258
        (target_owner, target_repo_name, target_branch_name) = (
231
 
            parse_github_url(target_branch))
 
259
            parse_github_branch_url(target_branch))
232
260
        target_repo = self.gh.get_repo(
233
261
            "%s/%s" % (target_owner, target_repo_name))
234
262
        state = {
244
272
                continue
245
273
            if pull.head.ref != source_branch_name:
246
274
                continue
 
275
            if pull.head.repo is None:
 
276
                # Repo has gone the way of the dodo
 
277
                continue
247
278
            if (pull.head.repo.owner.login != source_owner or
248
279
                    pull.head.repo.name != source_repo_name):
249
280
                continue
251
282
 
252
283
    def hosts(self, branch):
253
284
        try:
254
 
            parse_github_url(branch)
 
285
            parse_github_branch_url(branch)
255
286
        except NotGitHubUrl:
256
287
            return False
257
288
        else:
258
289
            return True
259
290
 
260
291
    @classmethod
261
 
    def probe(cls, branch):
 
292
    def probe_from_url(cls, url):
262
293
        try:
263
 
            parse_github_url(branch)
 
294
            parse_github_url(url)
264
295
        except NotGitHubUrl:
265
 
            raise UnsupportedHoster(branch)
 
296
            raise UnsupportedHoster(url)
266
297
        return cls()
267
298
 
268
299
    @classmethod
269
300
    def iter_instances(cls):
270
301
        yield cls()
271
302
 
 
303
    @convert_github_error
272
304
    def iter_my_proposals(self, status='open'):
273
305
        query = ['is:pr']
274
306
        if status == 'open':
275
307
            query.append('is:open')
276
308
        elif status == 'closed':
277
 
            # Note that we don't use is:closed here, since that also includes
278
 
            # merged pull requests.
279
309
            query.append('is:unmerged')
 
310
            # Also use "is:closed" otherwise unmerged open pull requests are
 
311
            # also included.
 
312
            query.append('is:closed')
280
313
        elif status == 'merged':
281
314
            query.append('is:merged')
282
315
        query.append('author:%s' % self.gh.get_user().login)
291
324
        self.source_branch = source_branch
292
325
        self.target_branch = target_branch
293
326
        (self.target_owner, self.target_repo_name, self.target_branch_name) = (
294
 
            parse_github_url(self.target_branch))
 
327
            parse_github_branch_url(self.target_branch))
295
328
        (self.source_owner, self.source_repo_name, self.source_branch_name) = (
296
 
            parse_github_url(self.source_branch))
 
329
            parse_github_branch_url(self.source_branch))
297
330
 
298
331
    def get_infotext(self):
299
332
        """Determine the initial comment for the merge proposal."""