hgext/blackbox.py
author timeless <timeless@mozdev.org>
Tue, 09 Feb 2016 19:16:06 +0000
changeset 28245 caa2a0c6fbb7
parent 28244 c17d7b1c40be
child 28246 b862e793ec10
permissions -rw-r--r--
blackbox: log working directory version Without this, while you could see the list of commands run, it wasn't possible to identify what they were doing, because commads could rely on revsets (including remote input which varies over time).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
     1
# blackbox.py - log repository events to a file for post-mortem debugging
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     2
#
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
     3
# Copyright 2010 Nicolas Dumazet
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     4
# Copyright 2013 Facebook, Inc.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     5
#
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     7
# GNU General Public License version 2 or any later version.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     8
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     9
"""log repository events to a blackbox for debugging
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    10
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    11
Logs event information to .hg/blackbox.log to help debug and diagnose problems.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    12
The events that get logged can be configured via the blackbox.track config key.
19162
27013ace80eb blackbox: fix literal block syntax
Takumi IINO <trot.thunder@gmail.com>
parents: 19066
diff changeset
    13
Examples::
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    14
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    15
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    16
  track = *
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    17
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    18
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    19
  track = command, commandfinish, commandexception, exthook, pythonhook
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    20
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    21
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    22
  track = incoming
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    23
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    24
  [blackbox]
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    25
  # limit the size of a log file
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    26
  maxsize = 1.5 MB
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    27
  # rotate up to N log files when the current one gets too big
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    28
  maxfiles = 3
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    29
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    30
"""
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    31
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    32
from __future__ import absolute_import
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    33
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    34
import errno
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    35
import re
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    36
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    37
from mercurial.i18n import _
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    38
from mercurial.node import hex
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    39
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    40
from mercurial import (
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    41
    cmdutil,
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    42
    util,
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    43
)
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    44
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    45
cmdtable = {}
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    46
command = cmdutil.command(cmdtable)
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    47
# Note for extension authors: ONLY specify testedwith = 'internal' for
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    48
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    49
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    50
# leave the attribute unspecified.
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    51
testedwith = 'internal'
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
    52
lastfp = None
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    53
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    54
filehandles = {}
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    55
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    56
def _openlog(vfs):
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    57
    path = vfs.join('blackbox.log')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    58
    if path in filehandles:
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    59
        return filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    60
    filehandles[path] = fp = vfs('blackbox.log', 'a')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    61
    return fp
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    62
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    63
def _closelog(vfs):
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    64
    path = vfs.join('blackbox.log')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    65
    fp = filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    66
    del filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    67
    fp.close()
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    68
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    69
def hexfn(node):
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    70
    if node is None:
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    71
        return None
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    72
    else:
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    73
        return hex(node)
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    74
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    75
def wrapui(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    76
    class blackboxui(ui.__class__):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    77
        @util.propertycache
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    78
        def track(self):
19052
63a783d1ac85 blackbox: fix a case of name capture
Bryan O'Sullivan <bryano@fb.com>
parents: 18831
diff changeset
    79
            return self.configlist('blackbox', 'track', ['*'])
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    80
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    81
        def _openlogfile(self):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    82
            def rotate(oldpath, newpath):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    83
                try:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
    84
                    self._bbvfs.unlink(newpath)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
    85
                except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    86
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    87
                        self.debug("warning: cannot remove '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    88
                                   (newpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    89
                try:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    90
                    if newpath:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
    91
                        self._bbvfs.rename(oldpath, newpath)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
    92
                except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    93
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    94
                        self.debug("warning: cannot rename '%s' to '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    95
                                   (newpath, oldpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    96
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    97
            fp = _openlog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    98
            maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    99
            if maxsize > 0:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   100
                st = self._bbvfs.fstat(fp)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   101
                if st.st_size >= maxsize:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   102
                    path = fp.name
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
   103
                    _closelog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   104
                    maxfiles = self.configint('blackbox', 'maxfiles', 7)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   105
                    for i in xrange(maxfiles - 1, 1, -1):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   106
                        rotate(oldpath='%s.%d' % (path, i - 1),
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   107
                               newpath='%s.%d' % (path, i))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   108
                    rotate(oldpath=path,
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   109
                           newpath=maxfiles > 0 and path + '.1')
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
   110
                    fp = _openlog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   111
            return fp
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   112
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   113
        def log(self, event, *msg, **opts):
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   114
            global lastfp
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   115
            super(blackboxui, self).log(event, *msg, **opts)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   116
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   117
            if not '*' in self.track and not event in self.track:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   118
                return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   119
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   120
            if util.safehasattr(self, '_blackbox'):
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   121
                fp = self._blackbox
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   122
            elif util.safehasattr(self, '_bbvfs'):
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
   123
                try:
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   124
                    self._bbfp = self._openlogfile()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   125
                except (IOError, OSError) as err:
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
   126
                    self.debug('warning: cannot write to blackbox.log: %s\n' %
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
   127
                               err.strerror)
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   128
                    del self._bbvfs
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   129
                    self._bbfp = None
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   130
                fp = self._bbfp
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   131
            else:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   132
                # certain ui instances exist outside the context of
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   133
                # a repo, so just default to the last blackbox that
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   134
                # was seen.
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   135
                fp = lastfp
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   136
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   137
            if fp:
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   138
                date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
18787
f56278a0a0c5 blackbox: use util.getuser for portability
Bryan O'Sullivan <bryano@fb.com>
parents: 18786
diff changeset
   139
                user = util.getuser()
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 28026
diff changeset
   140
                pid = str(util.getpid())
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   141
                formattedmsg = msg[0] % msg[1:]
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   142
                rev = '(unknown)'
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   143
                if util.safehasattr(self, '_bbrepo'):
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   144
                    ctx = self._bbrepo[None]
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   145
                    if ctx.rev() is not None:
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   146
                        rev = hexfn(ctx.node())
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   147
                    else:
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   148
                        parents = ctx.parents()
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   149
                        rev = ('+'.join([hexfn(p.node()) for p in parents]))
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   150
                try:
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   151
                    fp.write('%s %s @%s (%s)> %s' %
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   152
                        (date, user, rev, pid, formattedmsg))
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   153
                    fp.flush()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   154
                except IOError as err:
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   155
                    self.debug('warning: cannot write to blackbox.log: %s\n' %
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   156
                               err.strerror)
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   157
                if not lastfp or util.safehasattr(self, '_bbrepo'):
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   158
                    lastfp = fp
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   159
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   160
        def setrepo(self, repo):
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   161
            self._bbvfs = repo.vfs
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   162
            self._bbrepo = repo
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   163
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   164
    ui.__class__ = blackboxui
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   165
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   166
def uisetup(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   167
    wrapui(ui)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   168
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   169
def reposetup(ui, repo):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   170
    # During 'hg pull' a httppeer repo is created to represent the remote repo.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   171
    # It doesn't have a .hg directory to put a blackbox in, so we don't do
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   172
    # the blackbox setup for it.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   173
    if not repo.local():
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   174
        return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   175
19230
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   176
    if util.safehasattr(ui, 'setrepo'):
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   177
        ui.setrepo(repo)
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   178
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   179
@command('^blackbox',
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   180
    [('l', 'limit', 10, _('the number of events to show')),
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   181
    ],
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   182
    _('hg blackbox [OPTION]...'))
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   183
def blackbox(ui, repo, *revs, **opts):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   184
    '''view the recent repository events
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   185
    '''
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   186
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   187
    if not repo.vfs.exists('blackbox.log'):
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   188
        return
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   189
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   190
    limit = opts.get('limit')
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   191
    fp = repo.vfs('blackbox.log', 'r')
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   192
    lines = fp.read().split('\n')
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   193
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   194
    count = 0
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   195
    output = []
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   196
    for line in reversed(lines):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   197
        if count >= limit:
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   198
            break
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   199
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   200
        # count the commands by matching lines like: 2013/01/23 19:13:36 root>
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   201
        if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   202
            count += 1
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   203
        output.append(line)
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   204
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   205
    ui.status('\n'.join(reversed(output)))