/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/msgeditor.py

  • Committer: Jelmer Vernooij
  • Date: 2018-02-18 21:42:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6859.
  • Revision ID: jelmer@jelmer.uk-20180218214257-jpevutp1wa30tz3v
Update TODO to reference Breezy, not Bazaar.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Commit message editor support."""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
import codecs
20
 
from io import (
21
 
    BytesIO,
22
 
    StringIO,
23
 
    )
24
22
import os
25
23
from subprocess import call
26
24
import sys
27
25
 
28
26
from . import (
29
 
    bedding,
30
27
    cmdline,
31
28
    config,
32
29
    osutils,
36
33
    )
37
34
from .errors import BzrError
38
35
from .hooks import Hooks
 
36
from .sixish import (
 
37
    StringIO,
 
38
    )
39
39
 
40
40
 
41
41
class BadCommitMessageEncoding(BzrError):
45
45
 
46
46
 
47
47
def _get_editor():
48
 
    """Return sequence of possible editor binaries for the current platform"""
 
48
    """Return a sequence of possible editor binaries for the current platform"""
49
49
    try:
50
50
        yield os.environ["BRZ_EDITOR"], '$BRZ_EDITOR'
51
51
    except KeyError:
53
53
 
54
54
    e = config.GlobalStack().get('editor')
55
55
    if e is not None:
56
 
        yield e, bedding.config_path()
 
56
        yield e, config.config_filename()
57
57
 
58
58
    for varname in 'VISUAL', 'EDITOR':
59
59
        if varname in os.environ:
72
72
    for candidate, candidate_source in _get_editor():
73
73
        edargs = cmdline.split(candidate)
74
74
        try:
 
75
            ## mutter("trying editor: %r", (edargs +[filename]))
75
76
            x = call(edargs + [filename])
76
77
        except OSError as e:
77
78
            if candidate_source is not None:
91
92
            break
92
93
    raise BzrError("Could not start any editor.\nPlease specify one with:\n"
93
94
                   " - $BRZ_EDITOR\n - editor=/some/path in %s\n"
94
 
                   " - $VISUAL\n - $EDITOR" %
95
 
                   bedding.config_path())
 
95
                   " - $VISUAL\n - $EDITOR" % \
 
96
                    config.config_filename())
96
97
 
97
98
 
98
99
DEFAULT_IGNORE_LINE = "%(bar)s %(msg)s %(bar)s" % \
99
 
    {'bar': '-' * 14, 'msg': 'This line and the following will be ignored'}
 
100
    { 'bar' : '-' * 14, 'msg' : 'This line and the following will be ignored' }
100
101
 
101
102
 
102
103
def edit_commit_message(infotext, ignoreline=DEFAULT_IGNORE_LINE,
119
120
    :return:    commit message or None.
120
121
    """
121
122
 
122
 
    if start_message is not None:
 
123
    if not start_message is None:
123
124
        start_message = start_message.encode(osutils.get_user_encoding())
124
125
    infotext = infotext.encode(osutils.get_user_encoding(), 'replace')
125
126
    return edit_commit_message_encoded(infotext, ignoreline, start_message)
149
150
    msgfilename = None
150
151
    try:
151
152
        msgfilename, hasinfo = _create_temp_file_with_commit_template(
152
 
            infotext, ignoreline, start_message)
 
153
                                    infotext, ignoreline, start_message)
153
154
        if not msgfilename:
154
155
            return None
155
156
        basename = osutils.basename(msgfilename)
156
 
        msg_transport = transport.get_transport_from_path(
157
 
            osutils.dirname(msgfilename))
 
157
        msg_transport = transport.get_transport_from_path(osutils.dirname(msgfilename))
158
158
        reference_content = msg_transport.get_bytes(basename)
159
159
        if not _run_editor(msgfilename):
160
160
            return None
163
163
            if not ui.ui_factory.confirm_action(
164
164
                u"Commit message was not edited, use anyway",
165
165
                "breezy.msgeditor.unchanged",
166
 
                    {}):
 
166
                {}):
167
167
                # Returning "" makes cmd_commit raise 'empty commit message
168
168
                # specified' which is a reasonable error, given the user has
169
169
                # rejected using the unedited template.
171
171
        started = False
172
172
        msg = []
173
173
        lastline, nlines = 0, 0
174
 
        with codecs.open(msgfilename, mode='rb', encoding=osutils.get_user_encoding()) as f:
 
174
        # codecs.open() ALWAYS opens file in binary mode but we need text mode
 
175
        # 'rU' mode useful when bzr.exe used on Cygwin (bialix 20070430)
 
176
        f = file(msgfilename, 'rU')
 
177
        try:
175
178
            try:
176
 
                for line in f:
 
179
                for line in codecs.getreader(osutils.get_user_encoding())(f):
177
180
                    stripped_line = line.strip()
178
181
                    # strip empty line before the log message starts
179
182
                    if not started:
192
195
                    msg.append(line)
193
196
            except UnicodeDecodeError:
194
197
                raise BadCommitMessageEncoding()
 
198
        finally:
 
199
            f.close()
195
200
 
196
201
        if len(msg) == 0:
197
202
            return ""
233
238
    import tempfile
234
239
    tmp_fileno, msgfilename = tempfile.mkstemp(prefix='bzr_log.',
235
240
                                               dir=tmpdir, text=True)
236
 
    with os.fdopen(tmp_fileno, 'wb') as msgfile:
 
241
    msgfile = os.fdopen(tmp_fileno, 'w')
 
242
    try:
237
243
        if start_message is not None:
238
 
            msgfile.write(b"%s\n" % start_message)
 
244
            msgfile.write("%s\n" % start_message)
239
245
 
240
246
        if infotext is not None and infotext != "":
241
247
            hasinfo = True
242
 
            trailer = b"\n\n%s\n\n%s" % (
243
 
                ignoreline.encode(osutils.get_user_encoding()), infotext)
244
 
            msgfile.write(trailer)
 
248
            msgfile.write("\n\n%s\n\n%s" %(ignoreline, infotext))
245
249
        else:
246
250
            hasinfo = False
 
251
    finally:
 
252
        msgfile.close()
247
253
 
248
254
    return (msgfilename, hasinfo)
249
255
 
282
288
    template = template.encode(output_encoding, "replace")
283
289
 
284
290
    if diff:
285
 
        stream = BytesIO()
 
291
        stream = StringIO()
286
292
        show_diff_trees(working_tree.basis_tree(),
287
293
                        working_tree, stream, specific_files,
288
294
                        path_encoding=output_encoding)
289
 
        template = template + b'\n' + stream.getvalue()
 
295
        template = template + '\n' + stream.getvalue()
290
296
 
291
297
    return template
292
298
 
305
311
        These are all empty initially.
306
312
        """
307
313
        Hooks.__init__(self, "breezy.msgeditor", "hooks")
308
 
        self.add_hook(
309
 
            'set_commit_message',
 
314
        self.add_hook('set_commit_message',
310
315
            "Set a fixed commit message. "
311
316
            "set_commit_message is called with the "
312
 
            "breezy.commit.Commit object (so you can also change e.g. "
313
 
            "revision properties by editing commit.builder._revprops) and the "
314
 
            "message so far. set_commit_message must return the message to "
315
 
            "use or None if it should use the message editor as normal.",
316
 
            (2, 4))
317
 
        self.add_hook(
318
 
            'commit_message_template',
 
317
            "breezy.commit.Commit object (so you can also change e.g. revision "
 
318
            "properties by editing commit.builder._revprops) and the message "
 
319
            "so far. set_commit_message must return the message to use or None"
 
320
            " if it should use the message editor as normal.", (2, 4))
 
321
        self.add_hook('commit_message_template',
319
322
            "Called when a commit message is being generated. "
320
323
            "commit_message_template is called with the breezy.commit.Commit "
321
324
            "object and the message that is known so far. "