Mercurial > hg
view hgext/blackbox.py @ 24779:23727465ff72
record: add message when starting record's curses interface
We are adding this log message to reduce a confusion when a command prints
something just before starting the curses interface.
Since the interactive mode is taking over the entire screen, starts with no
delay and does wait for a key press, the user believes that messages printed
before opening the interactive mode were actually printed after using
interactive mode, not before.
The fix adds the line "Starting interactive mode" helping the user separate
the messages that were printed before and after the start of the
interactive mode.
One particular example where this was a problem is the revert command where we
first print the list of changes to be considered for revert, then opens the
curses interface right away without letting the user see the messages.
The user then selects the changes, validates and then see the messages from
before opening the interactive mode and is confused.
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Thu, 16 Apr 2015 14:26:50 -0700 |
parents | 7cc77030c557 |
children | 80c5b2666a96 |
line wrap: on
line source
# blackbox.py - log repository events to a file for post-mortem debugging # # Copyright 2010 Nicolas Dumazet # Copyright 2013 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. """log repository events to a blackbox for debugging Logs event information to .hg/blackbox.log to help debug and diagnose problems. The events that get logged can be configured via the blackbox.track config key. Examples:: [blackbox] track = * [blackbox] track = command, commandfinish, commandexception, exthook, pythonhook [blackbox] track = incoming [blackbox] # limit the size of a log file maxsize = 1.5 MB # rotate up to N log files when the current one gets too big maxfiles = 3 """ from mercurial import util, cmdutil from mercurial.i18n import _ import errno, os, re cmdtable = {} command = cmdutil.command(cmdtable) testedwith = 'internal' lastblackbox = None def wrapui(ui): class blackboxui(ui.__class__): @util.propertycache def track(self): return self.configlist('blackbox', 'track', ['*']) def _openlogfile(self): def rotate(oldpath, newpath): try: os.unlink(newpath) except OSError, err: if err.errno != errno.ENOENT: self.debug("warning: cannot remove '%s': %s\n" % (newpath, err.strerror)) try: if newpath: os.rename(oldpath, newpath) except OSError, err: if err.errno != errno.ENOENT: self.debug("warning: cannot rename '%s' to '%s': %s\n" % (newpath, oldpath, err.strerror)) fp = self._bbopener('blackbox.log', 'a') maxsize = self.configbytes('blackbox', 'maxsize', 1048576) if maxsize > 0: st = os.fstat(fp.fileno()) if st.st_size >= maxsize: path = fp.name fp.close() maxfiles = self.configint('blackbox', 'maxfiles', 7) for i in xrange(maxfiles - 1, 1, -1): rotate(oldpath='%s.%d' % (path, i - 1), newpath='%s.%d' % (path, i)) rotate(oldpath=path, newpath=maxfiles > 0 and path + '.1') fp = self._bbopener('blackbox.log', 'a') return fp def log(self, event, *msg, **opts): global lastblackbox super(blackboxui, self).log(event, *msg, **opts) if not '*' in self.track and not event in self.track: return if util.safehasattr(self, '_blackbox'): blackbox = self._blackbox elif util.safehasattr(self, '_bbopener'): try: self._blackbox = self._openlogfile() except (IOError, OSError), err: self.debug('warning: cannot write to blackbox.log: %s\n' % err.strerror) del self._bbopener self._blackbox = None blackbox = self._blackbox else: # certain ui instances exist outside the context of # a repo, so just default to the last blackbox that # was seen. blackbox = lastblackbox if blackbox: date = util.datestr(None, '%Y/%m/%d %H:%M:%S') user = util.getuser() formattedmsg = msg[0] % msg[1:] try: blackbox.write('%s %s> %s' % (date, user, formattedmsg)) except IOError, err: self.debug('warning: cannot write to blackbox.log: %s\n' % err.strerror) lastblackbox = blackbox def setrepo(self, repo): self._bbopener = repo.vfs ui.__class__ = blackboxui def uisetup(ui): wrapui(ui) def reposetup(ui, repo): # During 'hg pull' a httppeer repo is created to represent the remote repo. # It doesn't have a .hg directory to put a blackbox in, so we don't do # the blackbox setup for it. if not repo.local(): return if util.safehasattr(ui, 'setrepo'): ui.setrepo(repo) @command('^blackbox', [('l', 'limit', 10, _('the number of events to show')), ], _('hg blackbox [OPTION]...')) def blackbox(ui, repo, *revs, **opts): '''view the recent repository events ''' if not os.path.exists(repo.join('blackbox.log')): return limit = opts.get('limit') blackbox = repo.vfs('blackbox.log', 'r') lines = blackbox.read().split('\n') count = 0 output = [] for line in reversed(lines): if count >= limit: break # count the commands by matching lines like: 2013/01/23 19:13:36 root> if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line): count += 1 output.append(line) ui.status('\n'.join(reversed(output)))