hgext/blackbox.py
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Tue, 08 Mar 2016 23:04:53 +0900
changeset 28394 dcb4209bd30d
parent 28305 f5ae291dfedf
child 28407 63da8bd0c65e
permissions -rw-r--r--
revset: replace extpredicate by revsetpredicate of registrar This patch consists of changes below (these can't be applied separately). - replace revset.extpredicate by registrar.revsetpredicate in extensions - remove setup() on an instance named as revsetpredicate in uisetup()/extsetup() of each extensions registrar.revsetpredicate doesn't have setup() API. - put new entry for revsetpredicate into extraloaders in dispatch This causes implicit loading predicate functions at loading extension. This loading mechanism requires that an extension has an instance named as revsetpredicate, and this is reason why largefiles/__init__.py is also changed in this patch. Before this patch, test-revset.t tests that all decorated revset predicates are loaded by explicit setup() at once ("all or nothing"). Now, test-revset.t tests that any revset predicate isn't loaded at failure of loading extension, because loading itself is executed by dispatch and it can't be controlled on extension side.
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.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
    13
19162
27013ace80eb blackbox: fix literal block syntax
Takumi IINO <trot.thunder@gmail.com>
parents: 19066
diff changeset
    14
Examples::
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    15
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    16
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    17
  track = *
28303
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
    18
  # dirty is *EXPENSIVE* (slow);
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
    19
  # each log entry indicates `+` if the repository is dirty, like :hg:`id`.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
    20
  dirty = True
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
    21
  # record the source of log messages
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
    22
  logsource = True
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    23
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    24
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    25
  track = command, commandfinish, commandexception, exthook, pythonhook
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    26
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    27
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    28
  track = incoming
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    29
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    30
  [blackbox]
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    31
  # limit the size of a log file
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    32
  maxsize = 1.5 MB
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    33
  # 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
    34
  maxfiles = 3
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    35
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    36
"""
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    37
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    38
from __future__ import absolute_import
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    39
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    40
import errno
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    41
import re
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    42
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    43
from mercurial.i18n import _
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    44
from mercurial.node import hex
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    45
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    46
from mercurial import (
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    47
    cmdutil,
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    48
    ui as uimod,
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    49
    util,
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    50
)
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    51
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    52
cmdtable = {}
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    53
command = cmdutil.command(cmdtable)
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    54
# 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
    55
# 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
    56
# 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
    57
# leave the attribute unspecified.
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    58
testedwith = 'internal'
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
    59
lastui = None
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    60
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    61
filehandles = {}
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 _openlog(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
    if path in filehandles:
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    66
        return filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    67
    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
    68
    return fp
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    69
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    70
def _closelog(vfs):
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    71
    path = vfs.join('blackbox.log')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    72
    fp = filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    73
    del filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    74
    fp.close()
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
    75
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    76
def wrapui(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    77
    class blackboxui(ui.__class__):
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    78
        def __init__(self, src=None):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    79
            super(blackboxui, self).__init__(src)
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    80
            if src is None:
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    81
                self._partialinit()
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    82
            else:
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    83
                self._bbfp = src._bbfp
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    84
                self._bbrepo = src._bbrepo
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    85
                self._bbvfs = src._bbvfs
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    86
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    87
        def _partialinit(self):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    88
            if util.safehasattr(self, '_bbvfs'):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    89
                return
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    90
            self._bbfp = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    91
            self._bbrepo = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    92
            self._bbvfs = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    93
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    94
        def copy(self):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    95
            self._partialinit()
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    96
            return self.__class__(self)
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    97
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    98
        @util.propertycache
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    99
        def track(self):
19052
63a783d1ac85 blackbox: fix a case of name capture
Bryan O'Sullivan <bryano@fb.com>
parents: 18831
diff changeset
   100
            return self.configlist('blackbox', 'track', ['*'])
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   101
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   102
        def _openlogfile(self):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   103
            def rotate(oldpath, newpath):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   104
                try:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   105
                    self._bbvfs.unlink(newpath)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   106
                except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   107
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   108
                        self.debug("warning: cannot remove '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   109
                                   (newpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   110
                try:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   111
                    if newpath:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   112
                        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
   113
                except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   114
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   115
                        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
   116
                                   (newpath, oldpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   117
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
   118
            fp = _openlog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   119
            maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   120
            if maxsize > 0:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   121
                st = self._bbvfs.fstat(fp)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   122
                if st.st_size >= maxsize:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   123
                    path = fp.name
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
   124
                    _closelog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   125
                    maxfiles = self.configint('blackbox', 'maxfiles', 7)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   126
                    for i in xrange(maxfiles - 1, 1, -1):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   127
                        rotate(oldpath='%s.%d' % (path, i - 1),
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   128
                               newpath='%s.%d' % (path, i))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   129
                    rotate(oldpath=path,
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   130
                           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
   131
                    fp = _openlog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   132
            return fp
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
   133
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   134
        def _bbwrite(self, fmt, *args):
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   135
            self._bbfp.write(fmt % args)
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   136
            self._bbfp.flush()
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   137
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   138
        def log(self, event, *msg, **opts):
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   139
            global lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   140
            super(blackboxui, self).log(event, *msg, **opts)
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   141
            self._partialinit()
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   142
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   143
            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
   144
                return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   145
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   146
            if self._bbfp:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   147
                ui = self
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   148
            elif self._bbvfs:
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
   149
                try:
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   150
                    self._bbfp = self._openlogfile()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   151
                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
   152
                    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
   153
                               err.strerror)
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   154
                    del self._bbvfs
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   155
                    self._bbfp = None
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   156
                ui = self
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   157
            else:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   158
                # certain ui instances exist outside the context of
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   159
                # a repo, so just default to the last blackbox that
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   160
                # was seen.
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   161
                ui = lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   162
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   163
            if ui and ui._bbfp:
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   164
                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
   165
                user = util.getuser()
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 28026
diff changeset
   166
                pid = str(util.getpid())
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   167
                formattedmsg = msg[0] % msg[1:]
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
   168
                rev = '(unknown)'
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
   169
                changed = ''
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   170
                if ui._bbrepo:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   171
                    ctx = ui._bbrepo[None]
28304
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   172
                    parents = ctx.parents()
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   173
                    rev = ('+'.join([hex(p.node()) for p in parents]))
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   174
                    if (ui.configbool('blackbox', 'dirty', False) and (
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   175
                        any(ui._bbrepo.status()) or
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   176
                        any(ctx.sub(s).dirty() for s in ctx.substate)
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   177
                    )):
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
   178
                        changed = '+'
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   179
                if ui.configbool('blackbox', 'logsource', False):
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   180
                    src = ' [%s]' % event
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   181
                else:
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   182
                    src = ''
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   183
                try:
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   184
                    ui._bbwrite('%s %s @%s%s (%s)%s> %s',
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
   185
                        date, user, rev, changed, pid, src, formattedmsg)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   186
                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
   187
                    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
   188
                               err.strerror)
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   189
                if not lastui or ui._bbrepo:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   190
                    lastui = ui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   191
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   192
        def setrepo(self, repo):
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   193
            self._bbfp = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   194
            self._bbrepo = repo
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   195
            self._bbvfs = repo.vfs
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   196
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   197
    ui.__class__ = blackboxui
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   198
    uimod.ui = blackboxui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   199
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   200
def uisetup(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   201
    wrapui(ui)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   202
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   203
def reposetup(ui, repo):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   204
    # 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
   205
    # 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
   206
    # the blackbox setup for it.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   207
    if not repo.local():
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   208
        return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   209
19230
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   210
    if util.safehasattr(ui, 'setrepo'):
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   211
        ui.setrepo(repo)
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   212
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   213
@command('^blackbox',
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   214
    [('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
   215
    ],
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   216
    _('hg blackbox [OPTION]...'))
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   217
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
   218
    '''view the recent repository events
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   219
    '''
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   220
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   221
    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
   222
        return
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   223
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   224
    limit = opts.get('limit')
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   225
    fp = repo.vfs('blackbox.log', 'r')
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   226
    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
   227
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   228
    count = 0
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   229
    output = []
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   230
    for line in reversed(lines):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   231
        if count >= limit:
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   232
            break
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   233
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   234
        # 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
   235
        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
   236
            count += 1
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   237
        output.append(line)
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   238
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   239
    ui.status('\n'.join(reversed(output)))