sapling/hgext3rd/debuginhibit.py
Wez Furlong 04ee6433d4 warnings: squelch contextlib.nested DeprecationWarnings
Summary:
deals with the tests failing like this on my python 2.7 system:

```
+  /data/users/wez/facebook-hg-rpms/fb-hgext/hgext3rd/uncommit.py:144: DeprecationWarning: With-statements now directly support multiple context managers
+    with nested(repo.wlock(), repo.lock()):
```

Test Plan: arc unit

Reviewers: #mercurial, stash, simonfar, wez

Reviewed By: stash, simonfar

Subscribers: mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D4910040

Signature: t1:4910040:1492593520:ff815c5dbed4a341e0a313cd7160b700d878ee2c
2017-04-19 03:28:23 -07:00

148 lines
4.6 KiB
Python

# debuginhibit.py
#
# Copyright 2017 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.
"""debug commands and instrumentation for the inhibit extension
Adds the `debuginhibit` and `debugdeinhibit` commands to manually inhibit
and deinhibit nodes for testing purposes. Also causes inhibit to print
out the nodes being inhihibited or deinhibited and/or a stack trace of each
call site with the following config options::
[debuginhibit]
printnodes = true
printstack = true
stackdepth = 4
If stackdepth is not specified, a full stack trace will be printed.
"""
import inspect
import os
from contextlib import nested
from functools import partial
from operator import itemgetter
from mercurial import (
cmdutil,
extensions,
error,
scmutil,
)
from mercurial.i18n import _
from mercurial.node import short
from hgext3rd.nodeprecate import nodeprecate
testedwith = 'ships-with-fb-hgext'
cmdtable = {}
command = cmdutil.command(cmdtable)
inhibit = None
def extsetup(ui):
global inhibit
try:
inhibit = extensions.find('inhibit')
except KeyError:
ui.debug("no inhibit extension detected - "
"disabling debuginhibit\n")
return
if ui.configbool('debuginhibit', 'printnodes'):
extensions.wrapfunction(
inhibit,
'_inhibitmarkers',
partial(printnodeswrapper, ui, label="Inhibiting")
)
extensions.wrapfunction(
inhibit,
'_deinhibitmarkers',
partial(printnodeswrapper, ui, label="Deinhibiting")
)
def printnodeswrapper(ui, orig, repo, nodes, label=None):
"""Wrapper function that prints the nodes being inhibited/dehinhibited."""
if label is None:
label = "Nodes"
# `nodes` may be a generator, so collect it into a list first.
nodes = list(nodes)
ui.status(_("%s: %s\n") % (label, [short(n) for n in nodes]))
# Print out a truncated stack trace at the callsite if specified.
if ui.configbool('debuginhibit', 'printstack'):
trace = [_printframe(fi) for fi in inspect.stack()]
# Truncate the stack trace is specified by the user's config.
# Always remove the first two entries since they correspond
# to this wrapper function.
depth = ui.config('debuginhibit', 'stackdepth')
trace = trace[2:] if depth is None else trace[2:2 + int(depth)]
ui.status(_("Context:\n\t%s\n") % "\n\t".join(trace))
return orig(repo, nodes)
@command('debuginhibit', [
('r', 'rev', [], _("revisions to inhibit or deinhibit")),
('d', 'deinhibit', False, _("deinhibit the specified revs"))
])
@nodeprecate
def debuginhibit(ui, repo, *revs, **opts):
"""manually inhibit or deinhibit the specified revisions
By default inhibits any obsolescence markers on the given revs.
With no arguments prints out a list of inhibited nodes.
"""
_checkenabled(repo)
revs = list(revs) + opts.get('rev', [])
# If no arguments were passed to the command, just print out all the
# inhibited nodes and exit.
if not revs:
_prettyprintnodes(ui, repo, repo._obsinhibit)
return
revs = scmutil.revrange(repo, revs)
nodes = (repo.changelog.node(rev) for rev in revs)
with nested(repo.wlock(), repo.lock()):
with repo.transaction('debuginhibit') as tr:
if opts.get('deinhibit', False):
inhibit._deinhibitmarkers(repo, nodes)
else:
inhibit._inhibitmarkers(repo, nodes)
# Disable inhibit's post-transaction callback so that we only
# affect the changesets specified by the user.
del tr._postclosecallback['inhibitposttransaction']
def _prettyprintnodes(ui, repo, nodes):
"""Pretty print a list of nodes."""
contexts = [repo[node] for node in nodes]
showopts = {
'template': '{rev}:{node} {if(bookmarks, "({bookmarks}) ")}'
'{desc|firstline}\n'
}
displayer = cmdutil.show_changeset(ui, repo, showopts)
for ctx in contexts:
displayer.show(ctx)
def _printframe(frameinfo):
"""Return a human-readable string representation of a FrameInfo object."""
path, line, fn = itemgetter(1, 2, 3)(frameinfo)
return "[%s:%d] %s()" % (os.path.basename(path), line, fn)
def _checkenabled(repo):
"""Abort if inhibit is unavailable or disabled."""
if inhibit is None:
raise error.Abort(_("no inhibit extension detected"))
if not inhibit._inhibitenabled(repo):
raise error.Abort(_("inhibit extension is present but disabled"))