contrib/lock-checker.py
author Angel Ezquerra <angel.ezquerra@gmail.com>
Thu, 13 Dec 2012 23:37:53 +0100
changeset 18109 9e3910db4e78
parent 17738 b8424c92ba2b
child 20244 47d0843647d1
permissions -rw-r--r--
subrepo: append subrepo path to subrepo error messages This change appends the subrepo path to subrepo errors. That is, when there is an error performing an operation a subrepo, rather than displaying a message such as: pushing subrepo MYSUBREPO to PATH searching for changes abort: push creates new remote head HEADHASH! hint: did you forget to merge? use push -f to force mercurial will show: pushing subrepo MYSUBREPO to PATH searching for changes abort: push creates new remote head HEADHASH! (in subrepo MYSUBREPO) hint: did you forget to merge? use push -f to force The rationale for this change is that the current error messages make it hard for TortoiseHg (and similar tools) to tell the user which subrepo caused the push failure. The "(in subrepo MYSUBREPO)" message has been added to those subrepo methods were it made sense (by using a decorator). We avoid appending "(in subrepo XXX)" multiple times when subrepos are nexted by throwing a "SubrepoAbort" exception after the extra message is appended. The decorator will then "ignore" (i.e. just re-raise) the exception and never add the message again. A small drawback of this method is that part of the exception trace is lost when the exception is catched and re-raised by the annotatesubrepoerror decorator. Also, because the state() function already printed the subrepo path when it threw an error, that error has been changed to avoid duplicating the subrepo path in the error message. Note that I have also updated several subrepo related tests to reflect these changes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17669
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     1
"""Extension to verify locks are obtained in the required places.
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     2
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     3
This works by wrapping functions that should be surrounded by a lock
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     4
and asserting the lock is held. Missing locks are called out with a
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     5
traceback printed to stderr.
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     6
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     7
This currently only checks store locks, not working copy locks.
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     8
"""
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
     9
import os
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    10
import traceback
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    11
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    12
def _warnstack(ui, msg, skip=1):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    13
    '''issue warning with the message and the current stack, skipping the
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    14
    skip last entries'''
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    15
    ui.warn('%s at:\n' % msg)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    16
    entries = traceback.extract_stack()[:-skip]
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    17
    fnmax = max(len(entry[0]) for entry in entries)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    18
    for fn, ln, func, _text in entries:
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    19
        ui.warn(' %*s:%-4s in %s\n' % (fnmax, fn, ln, func))
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    20
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    21
def _checklock(repo):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    22
    l = repo._lockref and repo._lockref()
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    23
    if l is None or not l.held:
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    24
        _warnstack(repo.ui, 'missing lock', skip=2)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    25
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    26
def reposetup(ui, repo):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    27
    orig = repo.__class__
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    28
    class lockcheckrepo(repo.__class__):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    29
        def _writejournal(self, *args, **kwargs):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    30
            _checklock(self)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    31
            return orig._writejournal(self, *args, **kwargs)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    32
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    33
        def transaction(self, *args, **kwargs):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    34
            _checklock(self)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    35
            return orig.transaction(self, *args, **kwargs)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    36
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    37
        # TODO(durin42): kiilerix had a commented-out lock check in
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17669
diff changeset
    38
        # _writebranchcache and _writerequirements
17669
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    39
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    40
        def _tag(self, *args, **kwargs):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    41
            _checklock(self)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    42
            return orig._tag(self, *args, **kwargs)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    43
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    44
        def write(self, *args, **kwargs):
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    45
            assert os.path.lexists(self._join('.hg/wlock'))
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    46
            return orig.write(self, *args, **kwargs)
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    47
405b5f8fdad7 lock-checker: new contrib extension based on work done by Mads
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    48
    repo.__class__ = lockcheckrepo