mirror of
https://github.com/facebook/sapling.git
synced 2024-10-12 01:39:21 +03:00
9dc21f8d0b
Summary: D13853115 adds `edenscm/` to `sys.path` and code still uses `import mercurial`. That has nasty problems if both `import mercurial` and `import edenscm.mercurial` are used, because Python would think `mercurial.foo` and `edenscm.mercurial.foo` are different modules so code like `try: ... except mercurial.error.Foo: ...`, or `isinstance(x, mercurial.foo.Bar)` would fail to handle the `edenscm.mercurial` version. There are also some module-level states (ex. `extensions._extensions`) that would cause trouble if they have multiple versions in a single process. Change imports to use the `edenscm` so ideally the `mercurial` is no longer imported at all. Add checks in extensions.py to catch unexpected extensions importing modules from the old (wrong) locations when running tests. Reviewed By: phillco Differential Revision: D13868981 fbshipit-source-id: f4e2513766957fd81d85407994f7521a08e4de48
84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
# nointerrupt.py - prevent mercurial from being ctrl-c'ed
|
|
#
|
|
# Copyright 2016 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.
|
|
"""warns but doesn't exit when the user first hits Ctrl+C
|
|
|
|
This extension shows a warning the first time a user hits Ctrl+C saying the
|
|
repository could end up in a bad state. If the user hits Ctrl+C a second time,
|
|
hg will exit as usual.
|
|
|
|
By default, this behavior only applies to commands that are explicitly
|
|
whitelisted for it. To whitelist a command (say, "commit"), use:
|
|
|
|
[nointerrupt]
|
|
attend-commit = true
|
|
|
|
To change the default behavior to have all commands instrumented, set config
|
|
option ``nointerrupt.default-attend`` to true, then use the same logic to
|
|
disable it for commands where it's not wanted - for instance, for "log":
|
|
|
|
[nointerrupt]
|
|
default-attend = true
|
|
attend-log = false
|
|
|
|
Finally, to customize the message shown on the first Ctrl+C, set it in
|
|
config option ``nointerrupt.message``.
|
|
"""
|
|
|
|
import signal
|
|
import sys
|
|
|
|
from edenscm.mercurial import cmdutil, commands, dispatch, extensions
|
|
|
|
|
|
def sigintprintwarninghandlerfactory(oldsiginthandler, msg):
|
|
def sigint(*args):
|
|
sys.stderr.write(msg)
|
|
signal.signal(signal.SIGINT, oldsiginthandler)
|
|
|
|
return sigint
|
|
|
|
|
|
def nointerruptcmd(orig, ui, options, cmd, cmdfunc):
|
|
# bail if not in interactive terminal
|
|
if ui.configbool("nointerrupt", "interactiveonly", True):
|
|
if not ui.fout.isatty() or ui.plain():
|
|
return orig(ui, options, cmd, cmdfunc)
|
|
|
|
cmds, _cmdtableentry = cmdutil.findcmd(cmd, commands.table)
|
|
if isinstance(_cmdtableentry[0], dispatch.cmdalias):
|
|
cmds.append(_cmdtableentry[0].cmdname)
|
|
|
|
shouldpreventinterrupt = ui.configbool("nointerrupt", "default-attend", False)
|
|
for cmd in cmds:
|
|
var = "attend-%s" % cmd
|
|
if ui.config("nointerrupt", var):
|
|
shouldpreventinterrupt = ui.configbool("nointerrupt", var)
|
|
break
|
|
|
|
if shouldpreventinterrupt:
|
|
oldsiginthandler = signal.getsignal(signal.SIGINT)
|
|
try:
|
|
msg = ui.config(
|
|
"nointerrupt",
|
|
"message",
|
|
"==========================\n"
|
|
"Interrupting Mercurial may leave your repo in a bad state.\n"
|
|
"If you really want to interrupt your current command, press\n"
|
|
"CTRL-C again.\n"
|
|
"==========================\n",
|
|
)
|
|
signal.signal(
|
|
signal.SIGINT, sigintprintwarninghandlerfactory(oldsiginthandler, msg)
|
|
)
|
|
except AttributeError:
|
|
pass
|
|
return orig(ui, options, cmd, cmdfunc)
|
|
|
|
|
|
def uisetup(ui):
|
|
extensions.wrapfunction(dispatch, "_runcommand", nointerruptcmd)
|