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

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
Messages are classified by severity levels: critical, error, warning, info,
24
24
and debug.
25
25
 
26
 
They can be sent to two places: to stderr, and to ~/.brz.log.  For purposes
27
 
such as running the test suite, they can also be redirected away from both of
28
 
those two places to another location.
 
26
They can be sent to two places: stderr, and `$XDG_CACHE_HOME/breezy/brz.log`.
 
27
For purposes such as running the test suite, they can also be redirected away
 
28
from both of those two places to another location.
29
29
 
30
 
~/.brz.log gets all messages, and full tracebacks for uncaught exceptions.
 
30
`brz.log` gets all messages, and full tracebacks for uncaught exceptions.
31
31
This trace file is always in UTF-8, regardless of the user's default encoding,
32
32
so that we can always rely on writing any message.
33
33
 
45
45
form.
46
46
"""
47
47
 
48
 
from __future__ import absolute_import
49
 
 
50
48
# FIXME: Unfortunately it turns out that python's logging module
51
49
# is quite expensive, even when the message is not printed by any handlers.
52
50
# We should perhaps change back to just simply doing it here.
57
55
# that.
58
56
 
59
57
import errno
 
58
from io import StringIO
60
59
import logging
61
60
import os
62
61
import sys
72
71
 
73
72
lazy_import(globals(), """
74
73
from breezy import (
 
74
    bedding,
75
75
    debug,
76
 
    errors,
77
76
    osutils,
78
77
    ui,
79
78
    )
80
79
""")
81
 
 
82
 
from .sixish import (
83
 
    PY3,
84
 
    StringIO,
85
 
    text_type,
 
80
from . import (
 
81
    errors,
86
82
    )
87
83
 
88
84
 
96
92
# than push/pop_log_file.
97
93
_trace_file = None
98
94
 
99
 
# Absolute path for ~/.brz.log.  Not changed even if the log/trace output is
 
95
# Absolute path for brz.log.  Not changed even if the log/trace output is
100
96
# redirected elsewhere.  Used to show the location in --version.
101
97
_brz_log_filename = None
102
98
 
159
155
        fmt = fmt.decode('ascii', 'replace')
160
156
 
161
157
    if args:
162
 
        if not PY3:
163
 
            args = tuple(
164
 
                _Bytes(arg) if isinstance(arg, bytes) else arg for arg in args)
165
158
        out = fmt % args
166
159
    else:
167
160
        out = fmt
203
196
 
204
197
 
205
198
def _get_brz_log_filename():
206
 
    brz_log = osutils.path_from_environ('BRZ_LOG')
 
199
    """Return the brz log filename.
 
200
 
 
201
    :return: A path to the log file
 
202
    :raise EnvironmentError: If the cache directory could not be created
 
203
    """
 
204
    brz_log = os.environ.get('BRZ_LOG')
207
205
    if brz_log:
208
206
        return brz_log
209
 
    home = osutils.path_from_environ('BRZ_HOME')
210
 
    if home is None:
211
 
        # GZ 2012-02-01: Logging to the home dir is bad, but XDG is unclear
212
 
        #                over what would be better. On windows, bug 240550
213
 
        #                suggests LOCALAPPDATA be used instead.
214
 
        home = osutils._get_home_dir()
215
 
    return os.path.join(home, '.brz.log')
 
207
    return os.path.join(bedding.cache_dir(), 'brz.log')
216
208
 
217
209
 
218
210
def _open_brz_log():
219
 
    """Open the .brz.log trace file.
 
211
    """Open the brz.log trace file.
220
212
 
221
213
    If the log is more than a particular length, the old file is renamed to
222
 
    .brz.log.old and a new file is started.  Otherwise, we append to the
 
214
    brz.log.old and a new file is started.  Otherwise, we append to the
223
215
    existing file.
224
216
 
225
217
    This sets the global _brz_log_filename.
251
243
                break
252
244
        return os.fdopen(fd, 'ab', 0)  # unbuffered
253
245
 
254
 
    _brz_log_filename = _get_brz_log_filename()
255
 
    _rollover_trace_maybe(_brz_log_filename)
256
246
    try:
 
247
        _brz_log_filename = _get_brz_log_filename()
 
248
        _rollover_trace_maybe(_brz_log_filename)
 
249
 
257
250
        brz_log_file = _open_or_create_log_file(_brz_log_filename)
258
251
        brz_log_file.write(b'\n')
259
252
        if brz_log_file.tell() <= 2:
280
273
 
281
274
 
282
275
def enable_default_logging():
283
 
    """Configure default logging: messages to stderr and debug to .brz.log
 
276
    """Configure default logging: messages to stderr and debug to brz.log
284
277
 
285
278
    This should only be called once per process.
286
279
 
303
296
        r'%Y-%m-%d %H:%M:%S')
304
297
    # after hooking output into brz_log, we also need to attach a stderr
305
298
    # handler, writing only at level info and with encoding
306
 
    if sys.version_info[0] == 2:
307
 
        stderr_handler = EncodedStreamHandler(
308
 
            sys.stderr, osutils.get_terminal_encoding(), 'replace',
309
 
            level=logging.INFO)
310
 
    else:
311
 
        stderr_handler = logging.StreamHandler(stream=sys.stderr)
 
299
    stderr_handler = logging.StreamHandler(stream=sys.stderr)
312
300
    logging.getLogger('brz').addHandler(stderr_handler)
313
301
    return memento
314
302
 
490
478
 
491
479
 
492
480
def report_exception(exc_info, err_file):
493
 
    """Report an exception to err_file (typically stderr) and to .brz.log.
 
481
    """Report an exception to err_file (typically stderr) and to brz.log.
494
482
 
495
483
    This will show either a full traceback or a short message as appropriate.
496
484
 
497
485
    :return: The appropriate exit code for this error.
498
486
    """
499
 
    # Log the full traceback to ~/.brz.log
 
487
    # Log the full traceback to brz.log
500
488
    log_exception_quietly()
501
489
    if 'error' in debug.debug_flags:
502
490
        print_exception(exc_info, err_file)
521
509
    elif not getattr(exc_object, 'internal_error', True):
522
510
        report_user_error(exc_info, err_file)
523
511
        return errors.EXIT_ERROR
524
 
    elif osutils.is_environment_error(exc_object):
 
512
    elif isinstance(exc_object, EnvironmentError):
525
513
        if getattr(exc_object, 'errno', None) == errno.EPIPE:
526
514
            err_file.write("brz: broken pipe\n")
527
515
            return errors.EXIT_ERROR
612
600
 
613
601
    def emit(self, record):
614
602
        try:
615
 
            if not isinstance(record.msg, text_type):
 
603
            if not isinstance(record.msg, str):
616
604
                msg = record.msg.decode("utf-8")
617
 
                if PY3:
618
 
                    record.msg = msg
 
605
                record.msg = msg
619
606
            line = self.format(record)
620
 
            if not isinstance(line, text_type):
 
607
            if not isinstance(line, str):
621
608
                line = line.decode("utf-8")
622
609
            self.stream.write(line.encode(self.encoding, self.errors) + b"\n")
623
610
        except Exception: