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