/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 Jelmer Vernooij <jelmer@jelmer.uk>
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
"""Propose command implementations."""
18
0.434.1 by Jelmer Vernooij
Use absolute_import.
19
from __future__ import absolute_import
20
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
21
from io import StringIO
22
0.431.1 by Jelmer Vernooij
Start work on propose command.
23
from ... import (
24
    branch as _mod_branch,
25
    controldir,
26
    errors,
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
27
    log as _mod_log,
28
    missing as _mod_missing,
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
29
    msgeditor,
0.432.2 by Jelmer Vernooij
Publish command sort of works.
30
    urlutils,
0.431.1 by Jelmer Vernooij
Start work on propose command.
31
    )
32
from ...i18n import gettext
33
from ...commands import Command
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
34
from ...option import (
35
    ListOption,
0.432.2 by Jelmer Vernooij
Publish command sort of works.
36
    Option,
0.431.6 by Jelmer Vernooij
Initial gitlab support works.
37
    RegistryOption,
38
    )
39
from ...sixish import text_type
0.432.2 by Jelmer Vernooij
Publish command sort of works.
40
from ...trace import note
7408.3.1 by Jelmer Vernooij
Move propose module into core.
41
from ... import (
0.431.1 by Jelmer Vernooij
Start work on propose command.
42
    propose as _mod_propose,
43
    )
44
45
0.432.2 by Jelmer Vernooij
Publish command sort of works.
46
def branch_name(branch):
47
    if branch.name:
48
        return branch.name
49
    return urlutils.basename(branch.user_url)
50
51
7490.54.2 by Jelmer Vernooij
Also run checks in 'brz publish'.
52
def _check_already_merged(branch, target):
53
    # TODO(jelmer): Check entire ancestry rather than just last revision?
54
    if branch.last_revision() == target.last_revision():
7490.61.1 by Jelmer Vernooij
Rename BzrCommandError to CommandError.
55
        raise errors.CommandError(gettext(
7490.54.2 by Jelmer Vernooij
Also run checks in 'brz publish'.
56
            'All local changes are already present in target.'))
57
58
0.431.18 by Jelmer Vernooij
Rename 'brz publish' to 'brz publish-derived'.
59
class cmd_publish_derived(Command):
60
    __doc__ = """Publish a derived branch.
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
61
0.431.18 by Jelmer Vernooij
Rename 'brz publish' to 'brz publish-derived'.
62
    Try to create a public copy of a local branch on a hosting site,
63
    derived from the specified base branch.
0.432.2 by Jelmer Vernooij
Publish command sort of works.
64
65
    Reasonable defaults are picked for owner name, branch name and project
66
    name, but they can also be overridden from the command-line.
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
67
    """
68
0.432.2 by Jelmer Vernooij
Publish command sort of works.
69
    takes_options = [
7211.13.7 by Jelmer Vernooij
Fix formatting.
70
        'directory',
71
        Option('owner', help='Owner of the new remote branch.', type=str),
72
        Option('project', help='Project name for the new remote branch.',
73
               type=str),
74
        Option('name', help='Name of the new remote branch.', type=str),
75
        Option('no-allow-lossy',
76
               help='Allow fallback to lossy push, if necessary.'),
77
        Option('overwrite', help="Overwrite existing commits."),
78
        ]
0.432.2 by Jelmer Vernooij
Publish command sort of works.
79
    takes_args = ['submit_branch?']
80
81
    def run(self, submit_branch=None, owner=None, name=None, project=None,
0.431.52 by Jelmer Vernooij
Add --overwrite flag to 'brz publish'.
82
            no_allow_lossy=False, overwrite=False, directory='.'):
0.432.2 by Jelmer Vernooij
Publish command sort of works.
83
        local_branch = _mod_branch.Branch.open_containing(directory)[0]
84
        self.add_cleanup(local_branch.lock_write().unlock)
85
        if submit_branch is None:
86
            submit_branch = local_branch.get_submit_branch()
87
            note(gettext('Using submit branch %s') % submit_branch)
0.431.22 by Jelmer Vernooij
Add Hoster.get_derived_branch.
88
        if submit_branch is None:
89
            submit_branch = local_branch.get_parent()
90
            note(gettext('Using parent branch %s') % submit_branch)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
91
        submit_branch = _mod_branch.Branch.open(submit_branch)
7490.54.2 by Jelmer Vernooij
Also run checks in 'brz publish'.
92
        _check_already_merged(local_branch, submit_branch)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
93
        if name is None:
94
            name = branch_name(local_branch)
95
        hoster = _mod_propose.get_hoster(submit_branch)
0.431.20 by Jelmer Vernooij
publish -> publish_derived.
96
        remote_branch, public_url = hoster.publish_derived(
7211.13.7 by Jelmer Vernooij
Fix formatting.
97
            local_branch, submit_branch, name=name, project=project,
98
            owner=owner, allow_lossy=not no_allow_lossy,
99
            overwrite=overwrite)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
100
        local_branch.set_push_location(remote_branch.user_url)
101
        local_branch.set_public_branch(public_url)
7342.1.2 by Jelmer Vernooij
Set the submit branch after 'brz publish' / 'brz propose'
102
        local_branch.set_submit_branch(submit_branch.user_url)
0.432.2 by Jelmer Vernooij
Publish command sort of works.
103
        note(gettext("Pushed to %s") % public_url)
0.432.1 by Jelmer Vernooij
Initial work on hoster support.
104
105
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
106
def summarize_unmerged(local_branch, remote_branch, target,
107
                       prerequisite_branch=None):
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
108
    """Generate a text description of the unmerged revisions in branch.
109
110
    :param branch: The proposed branch
111
    :param target: Target branch
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
112
    :param prerequisite_branch: Optional prerequisite branch
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
113
    :return: A string
114
    """
0.431.55 by Jelmer Vernooij
Cope with lossy pushes better in `brz propose` texts.
115
    log_format = _mod_log.log_formatter_registry.get_default(local_branch)
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
116
    to_file = StringIO()
117
    lf = log_format(to_file=to_file, show_ids=False, show_timezone='original')
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
118
    if prerequisite_branch:
119
        local_extra = _mod_missing.find_unmerged(
120
            remote_branch, prerequisite_branch, restrict='local')[0]
121
    else:
122
        local_extra = _mod_missing.find_unmerged(
123
            remote_branch, target, restrict='local')[0]
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
124
0.431.55 by Jelmer Vernooij
Cope with lossy pushes better in `brz propose` texts.
125
    if remote_branch.supports_tags():
126
        rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
127
    else:
128
        rev_tag_dict = {}
129
130
    for revision in _mod_missing.iter_log_revisions(
0.431.55 by Jelmer Vernooij
Cope with lossy pushes better in `brz propose` texts.
131
            local_extra, local_branch.repository, False, rev_tag_dict):
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
132
        lf.log_revision(revision)
133
    return to_file.getvalue()
134
135
0.431.1 by Jelmer Vernooij
Start work on propose command.
136
class cmd_propose_merge(Command):
137
    __doc__ = """Propose a branch for merging.
138
139
    This command creates a merge proposal for the local
140
    branch to the target branch. The format of the merge
141
    proposal depends on the submit branch.
142
    """
143
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
144
    takes_options = [
7211.13.7 by Jelmer Vernooij
Fix formatting.
145
        'directory',
146
        RegistryOption(
147
            'hoster',
148
            help='Use the hoster.',
149
            lazy_registry=('breezy.plugins.propose.propose', 'hosters')),
150
        ListOption('reviewers', short_name='R', type=text_type,
151
                   help='Requested reviewers.'),
152
        Option('name', help='Name of the new remote branch.', type=str),
153
        Option('description', help='Description of the change.', type=str),
154
        Option('prerequisite', help='Prerequisite branch.', type=str),
7467.3.2 by Jelmer Vernooij
Add --wip flag for 'brz propose'.
155
        Option('wip', help='Mark merge request as work-in-progress'),
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
156
        Option(
157
            'commit-message',
158
            help='Set commit message for merge, if supported', type=str),
7211.13.7 by Jelmer Vernooij
Fix formatting.
159
        ListOption('labels', short_name='l', type=text_type,
160
                   help='Labels to apply.'),
161
        Option('no-allow-lossy',
162
               help='Allow fallback to lossy push, if necessary.'),
7490.6.1 by Jelmer Vernooij
Add allow-collaboration flag.
163
        Option('allow-collaboration',
164
               help='Allow collaboration from target branch maintainer(s)'),
7490.54.1 by Jelmer Vernooij
Prevent empty proposals.
165
        Option('allow-empty',
166
               help='Do not prevent empty merge proposals.'),
7211.13.7 by Jelmer Vernooij
Fix formatting.
167
        ]
0.431.1 by Jelmer Vernooij
Start work on propose command.
168
    takes_args = ['submit_branch?']
169
170
    aliases = ['propose']
171
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
172
    def run(self, submit_branch=None, directory='.', hoster=None,
173
            reviewers=None, name=None, no_allow_lossy=False, description=None,
7490.6.1 by Jelmer Vernooij
Add allow-collaboration flag.
174
            labels=None, prerequisite=None, commit_message=None, wip=False,
7490.54.1 by Jelmer Vernooij
Prevent empty proposals.
175
            allow_collaboration=False, allow_empty=False):
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
176
        tree, branch, relpath = (
177
            controldir.ControlDir.open_containing_tree_or_branch(directory))
0.431.1 by Jelmer Vernooij
Start work on propose command.
178
        if submit_branch is None:
179
            submit_branch = branch.get_submit_branch()
180
        if submit_branch is None:
0.432.7 by Jelmer Vernooij
propose works \o/
181
            submit_branch = branch.get_parent()
182
        if submit_branch is None:
7490.61.1 by Jelmer Vernooij
Rename BzrCommandError to CommandError.
183
            raise errors.CommandError(
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
184
                gettext("No target location specified or remembered"))
7490.54.1 by Jelmer Vernooij
Prevent empty proposals.
185
        target = _mod_branch.Branch.open(submit_branch)
7490.54.2 by Jelmer Vernooij
Also run checks in 'brz publish'.
186
        if not allow_empty:
187
            _check_already_merged(branch, target)
0.432.7 by Jelmer Vernooij
propose works \o/
188
        if hoster is None:
189
            hoster = _mod_propose.get_hoster(target)
0.431.5 by Jelmer Vernooij
Initial work on gitlab support.
190
        else:
0.432.7 by Jelmer Vernooij
propose works \o/
191
            hoster = hoster.probe(target)
192
        if name is None:
193
            name = branch_name(branch)
0.431.20 by Jelmer Vernooij
publish -> publish_derived.
194
        remote_branch, public_branch_url = hoster.publish_derived(
7211.13.7 by Jelmer Vernooij
Fix formatting.
195
            branch, target, name=name, allow_lossy=not no_allow_lossy)
0.431.37 by Jelmer Vernooij
add a find-merge-proposal command.
196
        branch.set_push_location(remote_branch.user_url)
7342.1.2 by Jelmer Vernooij
Set the submit branch after 'brz publish' / 'brz propose'
197
        branch.set_submit_branch(target.user_url)
0.432.7 by Jelmer Vernooij
propose works \o/
198
        note(gettext('Published branch to %s') % public_branch_url)
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
199
        if prerequisite is not None:
200
            prerequisite_branch = _mod_branch.Branch.open(prerequisite)
201
        else:
202
            prerequisite_branch = None
0.432.7 by Jelmer Vernooij
propose works \o/
203
        proposal_builder = hoster.get_proposer(remote_branch, target)
0.432.10 by Jelmer Vernooij
More test fixes.
204
        if description is None:
205
            body = proposal_builder.get_initial_body()
206
            info = proposal_builder.get_infotext()
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
207
            info += "\n\n" + summarize_unmerged(
208
                branch, remote_branch, target, prerequisite_branch)
0.431.54 by Jelmer Vernooij
Include commit data in 'brz propose'.
209
            description = msgeditor.edit_commit_message(
210
                info, start_message=body)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
211
        try:
0.432.7 by Jelmer Vernooij
propose works \o/
212
            proposal = proposal_builder.create_proposal(
0.431.56 by Jelmer Vernooij
Add support for prerequisite branches.
213
                description=description, reviewers=reviewers,
7296.8.1 by Jelmer Vernooij
Add commit-message option to 'brz propose'.
214
                prerequisite_branch=prerequisite_branch, labels=labels,
7467.3.2 by Jelmer Vernooij
Add --wip flag for 'brz propose'.
215
                commit_message=commit_message,
7490.6.1 by Jelmer Vernooij
Add allow-collaboration flag.
216
                work_in_progress=wip, allow_collaboration=allow_collaboration)
0.431.2 by Jelmer Vernooij
Add launchpad implementation.
217
        except _mod_propose.MergeProposalExists as e:
7359.1.3 by Jelmer Vernooij
Fix GitHub API interaction.
218
            note(gettext('There is already a branch merge proposal: %s'), e.url)
219
        else:
220
            note(gettext('Merge proposal created: %s') % proposal.url)
0.431.37 by Jelmer Vernooij
add a find-merge-proposal command.
221
222
223
class cmd_find_merge_proposal(Command):
224
    __doc__ = """Find a merge proposal.
225
226
    """
227
228
    takes_options = ['directory']
229
    takes_args = ['submit_branch?']
230
    aliases = ['find-proposal']
231
232
    def run(self, directory='.', submit_branch=None):
233
        tree, branch, relpath = controldir.ControlDir.open_containing_tree_or_branch(
234
            directory)
235
        public_location = branch.get_public_branch()
236
        if public_location:
237
            branch = _mod_branch.Branch.open(public_location)
238
        if submit_branch is None:
239
            submit_branch = branch.get_submit_branch()
240
        if submit_branch is None:
241
            submit_branch = branch.get_parent()
242
        if submit_branch is None:
7490.61.1 by Jelmer Vernooij
Rename BzrCommandError to CommandError.
243
            raise errors.CommandError(
0.431.55 by Jelmer Vernooij
Cope with lossy pushes better in `brz propose` texts.
244
                gettext("No target location specified or remembered"))
0.431.37 by Jelmer Vernooij
add a find-merge-proposal command.
245
        else:
246
            target = _mod_branch.Branch.open(submit_branch)
247
        hoster = _mod_propose.get_hoster(branch)
0.431.67 by Jelmer Vernooij
Support multiple merge proposals per branch.
248
        for mp in hoster.iter_proposals(branch, target):
249
            self.outf.write(gettext('Merge proposal: %s\n') % mp.url)
0.431.47 by Jelmer Vernooij
Add github login command.
250
251
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
252
class cmd_my_merge_proposals(Command):
0.431.66 by Jelmer Vernooij
Add support for status argument.
253
    __doc__ = """List all merge proposals owned by the logged-in user.
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
254
255
    """
256
0.431.69 by Jelmer Vernooij
Make 'brz my-proposals' hidden for the moment.
257
    hidden = True
258
0.431.66 by Jelmer Vernooij
Add support for status argument.
259
    takes_options = [
7296.10.3 by Jelmer Vernooij
More fixes.
260
        'verbose',
0.431.66 by Jelmer Vernooij
Add support for status argument.
261
        RegistryOption.from_kwargs(
262
            'status',
263
            title='Proposal Status',
264
            help='Only include proposals with specified status.',
265
            value_switches=True,
266
            enum_switch=True,
267
            all='All merge proposals',
268
            open='Open merge proposals',
269
            merged='Merged merge proposals',
270
            closed='Closed merge proposals')]
271
7296.10.3 by Jelmer Vernooij
More fixes.
272
    def run(self, status='open', verbose=False):
7408.3.1 by Jelmer Vernooij
Move propose module into core.
273
        for name, hoster_cls in _mod_propose.hosters.items():
0.431.63 by Jelmer Vernooij
Add 'brz my-proposals' command.
274
            for instance in hoster_cls.iter_instances():
0.431.66 by Jelmer Vernooij
Add support for status argument.
275
                for mp in instance.iter_my_proposals(status=status):
0.431.65 by Jelmer Vernooij
Avoid print.
276
                    self.outf.write('%s\n' % mp.url)
7296.10.3 by Jelmer Vernooij
More fixes.
277
                    if verbose:
278
                        self.outf.write(
279
                            '(Merging %s into %s)\n' %
280
                            (mp.get_source_branch_url(),
281
                             mp.get_target_branch_url()))
7360.1.2 by Jelmer Vernooij
Cope with description being None.
282
                        description = mp.get_description()
283
                        if description:
284
                            self.outf.writelines(
285
                                ['\t%s\n' % l
286
                                 for l in description.splitlines()])
7296.10.3 by Jelmer Vernooij
More fixes.
287
                        self.outf.write('\n')
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
288
289
290
class cmd_land_merge_proposal(Command):
291
    __doc__ = """Land a merge proposal."""
292
293
    takes_args = ['url']
294
    takes_options = [
295
        Option('message', help='Commit message to use.', type=str)]
296
297
    def run(self, url, message=None):
7408.3.1 by Jelmer Vernooij
Move propose module into core.
298
        proposal = _mod_propose.get_proposal_by_url(url)
7296.9.1 by Jelmer Vernooij
Add 'brz land' subcommand.
299
        proposal.merge(commit_message=message)