/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.431.1 by Jelmer Vernooij
Start work on propose command.
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
17
"""Helper functions for proposing merges."""
18
19
from __future__ import absolute_import
20
21
from ... import (
22
    errors,
23
    hooks,
24
    registry,
7268.12.3 by Jelmer Vernooij
Add missing import.
25
    urlutils,
0.431.1 by Jelmer Vernooij
Start work on propose command.
26
    )
27
28
0.431.38 by Jelmer Vernooij
Add NoSuchProject.
29
class NoSuchProject(errors.BzrError):
30
31
    _fmt = "Project does not exist: %(project)s."
32
33
    def __init__(self, project):
34
        errors.BzrError.__init__(self)
35
        self.project = project
36
37
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
38
class MergeProposalExists(errors.BzrError):
39
40
    _fmt = "A merge proposal already exists: %(url)s."
41
42
    def __init__(self, url):
43
        errors.BzrError.__init__(self)
44
        self.url = url
45
46
0.432.2 by Jelmer Vernooij
Publish command sort of works.
47
class UnsupportedHoster(errors.BzrError):
48
49
    _fmt = "No supported hoster for %(branch)s."
50
51
    def __init__(self, branch):
52
        errors.BzrError.__init__(self)
53
        self.branch = branch
54
55
0.431.1 by Jelmer Vernooij
Start work on propose command.
56
class ProposeMergeHooks(hooks.Hooks):
57
    """Hooks for proposing a merge on Launchpad."""
58
59
    def __init__(self):
60
        hooks.Hooks.__init__(self, __name__, "Proposer.hooks")
0.431.57 by Jelmer Vernooij
Cleanups.
61
        self.add_hook(
62
            'get_prerequisite',
0.431.1 by Jelmer Vernooij
Start work on propose command.
63
            "Return the prerequisite branch for proposing as merge.", (3, 0))
0.431.57 by Jelmer Vernooij
Cleanups.
64
        self.add_hook(
65
            'merge_proposal_body',
0.431.1 by Jelmer Vernooij
Start work on propose command.
66
            "Return an initial body for the merge proposal message.", (3, 0))
67
68
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
69
class LabelsUnsupported(errors.BzrError):
70
    """Labels not supported by this hoster."""
71
72
    _fmt = "Labels are not supported by %(hoster)r."
73
74
    def __init__(self, hoster):
75
        errors.BzrError.__init__(self)
76
        self.hoster = hoster
77
78
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
79
class PrerequisiteBranchUnsupported(errors.BzrError):
80
    """Prerequisite branch not supported by this hoster."""
81
82
    def __init__(self, hoster):
83
        errors.BzrError.__init__(self)
84
        self.hoster = hoster
85
86
7268.8.1 by Jelmer Vernooij
Add HosterLoginRequired exception.
87
class HosterLoginRequired(errors.BzrError):
88
    """Action requires hoster login credentials."""
89
7268.8.2 by Jelmer Vernooij
Handle GitHub errors.
90
    _fmt = "Action requires credentials for hosting site %(hoster)r."""
91
7268.8.1 by Jelmer Vernooij
Add HosterLoginRequired exception.
92
    def __init__(self, hoster):
93
        errors.BzrError.__init__(self)
94
        self.hoster = hoster
95
96
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
97
class MergeProposal(object):
98
    """A merge proposal.
99
100
    :ivar url: URL for the merge proposal
101
    """
102
103
    def __init__(self, url=None):
104
        self.url = url
105
0.431.39 by Jelmer Vernooij
Extend the merge proposal abstraction a bit.
106
    def get_description(self):
107
        """Get the description of the merge proposal."""
108
        raise NotImplementedError(self.get_description)
109
110
    def set_description(self, description):
111
        """Set the description of the merge proposal."""
112
        raise NotImplementedError(self.set_description)
113
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
114
    def get_commit_message(self):
115
        """Get the proposed commit message."""
116
        raise NotImplementedError(self.get_commit_message)
117
118
    def set_commit_message(self, commit_message):
119
        """Set the propose commit message."""
120
        raise NotImplementedError(self.set_commit_message)
121
0.431.64 by Jelmer Vernooij
Add get_source_branch_url/get_target_branch_url methods.
122
    def get_source_branch_url(self):
123
        """Return the source branch."""
124
        raise NotImplementedError(self.get_source_branch_url)
125
126
    def get_target_branch_url(self):
127
        """Return the target branch."""
128
        raise NotImplementedError(self.get_target_branch_url)
129
0.431.39 by Jelmer Vernooij
Extend the merge proposal abstraction a bit.
130
    def close(self):
131
        """Close the merge proposal (without merging it)."""
132
        raise NotImplementedError(self.close)
133
0.431.46 by Jelmer Vernooij
Add MergeProposal.is_merged.
134
    def is_merged(self):
135
        """Check whether this merge proposal has been merged."""
136
        raise NotImplementedError(self.is_merged)
137
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
138
    def merge(self, commit_message=None):
139
        """Merge this merge proposal."""
140
        raise NotImplementedError(self.merge)
141
7380.1.1 by Jelmer Vernooij
Several more fixes for git merge proposals.
142
    def can_be_merged(self):
143
        """Can this merge proposal be merged?
144
145
        The answer to this can be no if e.g. it has conflics.
146
        """
147
        raise NotImplementedError(self.can_be_merged)
148
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
149
0.432.2 by Jelmer Vernooij
Publish command sort of works.
150
class MergeProposalBuilder(object):
0.431.1 by Jelmer Vernooij
Start work on propose command.
151
    """Merge proposal creator.
152
153
    :param source_branch: Branch to propose for merging
154
    :param target_branch: Target branch
155
    """
156
157
    hooks = ProposeMergeHooks()
158
159
    def __init__(self, source_branch, target_branch):
160
        self.source_branch = source_branch
161
        self.target_branch = target_branch
162
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
163
    def get_initial_body(self):
164
        """Get a body for the proposal for the user to modify.
165
166
        :return: a str or None.
167
        """
168
        raise NotImplementedError(self.get_initial_body)
169
170
    def get_infotext(self):
171
        """Determine the initial comment for the merge proposal.
172
        """
173
        raise NotImplementedError(self.get_infotext)
174
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
175
    def create_proposal(self, description, reviewers=None, labels=None,
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
176
                        prerequisite_branch=None, commit_message=None):
0.431.1 by Jelmer Vernooij
Start work on propose command.
177
        """Create a proposal to merge a branch for merging.
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
178
179
        :param description: Description for the merge proposal
0.431.5 by Jelmer Vernooij
Initial work on gitlab support.
180
        :param reviewers: Optional list of people to ask reviews from
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
181
        :param labels: Labels to attach to the proposal
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
182
        :param prerequisite_branch: Optional prerequisite branch
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
183
        :param commit_message: Optional commit message
0.431.3 by Jelmer Vernooij
Add a MergeProposal object.
184
        :return: A `MergeProposal` object
0.431.1 by Jelmer Vernooij
Start work on propose command.
185
        """
186
        raise NotImplementedError(self.create_proposal)
187
188
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
189
class Hoster(object):
190
    """A hosting site manager.
191
    """
192
7260.1.1 by Jelmer Vernooij
Add .base_url property to Hoster.
193
    # Does this hoster support arbitrary labels being attached to merge
194
    # proposals?
0.431.13 by Jelmer Vernooij
Add support for labels on merge proposals.
195
    supports_merge_proposal_labels = None
196
7296.8.2 by Jelmer Vernooij
Add feature flag for commit message.
197
    # Does this hoster support suggesting a commit message in the
198
    # merge proposal?
199
    supports_merge_proposal_commit_message = None
200
7260.1.1 by Jelmer Vernooij
Add .base_url property to Hoster.
201
    # The base_url that would be visible to users. I.e. https://github.com/
202
    # rather than https://api.github.com/
203
    base_url = None
204
0.431.20 by Jelmer Vernooij
publish -> publish_derived.
205
    def publish_derived(self, new_branch, base_branch, name, project=None,
0.431.51 by Jelmer Vernooij
Allow fallback to lossy by default.
206
                        owner=None, revision_id=None, overwrite=False,
207
                        allow_lossy=True):
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
208
        """Publish a branch to the site, derived from base_branch.
209
210
        :param base_branch: branch to derive the new branch from
211
        :param new_branch: branch to publish
0.432.3 by Jelmer Vernooij
Publish command works for github.
212
        :return: resulting branch, public URL
7268.8.1 by Jelmer Vernooij
Add HosterLoginRequired exception.
213
        :raise HosterLoginRequired: Action requires a hoster login, but none is
214
            known.
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
215
        """
216
        raise NotImplementedError(self.publish)
217
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
218
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
0.431.31 by Jelmer Vernooij
Drop autopropose command.
219
        """Get a derived branch ('a fork').
220
        """
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
221
        raise NotImplementedError(self.get_derived_branch)
222
0.431.28 by Jelmer Vernooij
Implement Hoster.get_push_url.
223
    def get_push_url(self, branch):
224
        """Get the push URL for a branch."""
225
        raise NotImplementedError(self.get_push_url)
226
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
227
    def get_proposer(self, source_branch, target_branch):
228
        """Get a merge proposal creator.
229
0.431.31 by Jelmer Vernooij
Drop autopropose command.
230
        :note: source_branch does not have to be hosted by the hoster.
231
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
232
        :param source_branch: Source branch
233
        :param target_branch: Target branch
0.432.2 by Jelmer Vernooij
Publish command sort of works.
234
        :return: A MergeProposalBuilder object
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
235
        """
236
        raise NotImplementedError(self.get_proposer)
237
0.431.68 by Jelmer Vernooij
Add status to other Hosters.
238
    def iter_proposals(self, source_branch, target_branch, status='open'):
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
239
        """Get the merge proposals for a specified branch tuple.
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
240
241
        :param source_branch: Source branch
242
        :param target_branch: Target branch
0.431.68 by Jelmer Vernooij
Add status to other Hosters.
243
        :param status: Status of proposals to iterate over
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
244
        :return: Iterate over MergeProposal object
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
245
        """
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
246
        raise NotImplementedError(self.iter_proposals)
0.431.35 by Jelmer Vernooij
Add Hoster.get_proposal.
247
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
248
    def get_proposal_by_url(self, url):
249
        """Retrieve a branch proposal by URL.
250
251
        :param url: Merge proposal URL.
252
        :return: MergeProposal object
253
        :raise UnsupportedHoster: Hoster does not support this URL
254
        """
255
        raise NotImplementedError(self.get_proposal_by_url)
256
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
257
    def hosts(self, branch):
258
        """Return true if this hoster hosts given branch."""
259
        raise NotImplementedError(self.hosts)
260
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
261
    @classmethod
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
262
    def probe_from_branch(cls, branch):
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
263
        """Create a Hoster object if this hoster knows about a branch."""
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
264
        url = urlutils.split_segment_parameters(branch.user_url)[0]
7296.10.1 by Jelmer Vernooij
Initial work making gitlab just directly use ReST.
265
        return cls.probe_from_url(
7296.10.2 by Jelmer Vernooij
More fixes.
266
            url, possible_transports=[branch.control_transport])
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
267
268
    @classmethod
7296.10.1 by Jelmer Vernooij
Initial work making gitlab just directly use ReST.
269
    def probe_from_url(cls, url, possible_hosters=None):
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
270
        """Create a Hoster object if this hoster knows about a URL."""
271
        raise NotImplementedError(cls.probe_from_url)
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
272
0.432.4 by Jelmer Vernooij
Some work on gitlab.
273
    # TODO(jelmer): Some way of cleaning up old branch proposals/branches
274
0.431.66 by Jelmer Vernooij
Add support for status argument.
275
    def iter_my_proposals(self, status='open'):
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
276
        """Iterate over the proposals created by the currently logged in user.
277
0.431.66 by Jelmer Vernooij
Add support for status argument.
278
        :param status: Only yield proposals with this status
279
            (one of: 'open', 'closed', 'merged', 'all')
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
280
        :return: Iterator over MergeProposal objects
7268.8.1 by Jelmer Vernooij
Add HosterLoginRequired exception.
281
        :raise HosterLoginRequired: Action requires a hoster login, but none is
282
            known.
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
283
        """
284
        raise NotImplementedError(self.iter_my_proposals)
285
286
    @classmethod
287
    def iter_instances(cls):
288
        """Iterate instances.
289
290
        :return: Hoster instances
291
        """
292
        raise NotImplementedError(cls.iter_instances)
293
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
294
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
295
def get_hoster(branch, possible_hosters=None):
0.432.2 by Jelmer Vernooij
Publish command sort of works.
296
    """Find the hoster for a branch."""
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
297
    if possible_hosters:
298
        for hoster in possible_hosters:
299
            if hoster.hosts(branch):
300
                return hoster
0.432.2 by Jelmer Vernooij
Publish command sort of works.
301
    for name, hoster_cls in hosters.items():
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
302
        try:
7268.12.1 by Jelmer Vernooij
Split out probe_from_url.
303
            hoster = hoster_cls.probe_from_branch(branch)
0.432.9 by Jelmer Vernooij
Drop is_compatible nonesense.
304
        except UnsupportedHoster:
305
            pass
0.433.1 by Jelmer Vernooij
Add Hoster.hosts.
306
        else:
307
            if possible_hosters is not None:
308
                possible_hosters.append(hoster)
309
            return hoster
0.432.2 by Jelmer Vernooij
Publish command sort of works.
310
    raise UnsupportedHoster(branch)
311
312
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
313
def get_proposal_by_url(url):
314
    for name, hoster_cls in hosters.items():
315
        for instance in hoster_cls.iter_instances():
316
            try:
317
                return instance.get_proposal_by_url(url)
318
            except UnsupportedHoster:
319
                pass
320
    raise UnsupportedHoster(url)
321
322
0.432.2 by Jelmer Vernooij
Publish command sort of works.
323
hosters = registry.Registry()
324
hosters.register_lazy(
7211.13.7 by Jelmer Vernooij
Fix formatting.
325
    "launchpad", "breezy.plugins.propose.launchpad",
326
    "Launchpad")
327
hosters.register_lazy(
328
    "github", "breezy.plugins.propose.github",
329
    "GitHub")
330
hosters.register_lazy(
331
    "gitlab", "breezy.plugins.propose.gitlabs",
332
    "GitLab")