1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
# thg - mercurial extension for TortoiseHg repository browser
#
# Copyright (C) 2014 Steve Borho <steve@borho.org>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""browse the repository in a graphical way using tortoisehg
The 'tortoisehg' extension introduces a :hg:`view` command to spawn a light
version of the tortoisehg workbench.
"""
from __future__ import annotations
import os
import sys
from mercurial import (
pycompat,
registrar,
ui as uimod,
util,
)
from mercurial.utils import (
procutil,
)
from tortoisehg.util.i18n import agettext as _
testedwith = b'4.3'
cmdtable = {}
command = registrar.command(cmdtable)
if hasattr(sys, "frozen"):
if sys.frozen == 'windows_exe':
# sys.stdin is invalid, should be None. Fixes svn, git subrepos
sys.stdin = None
if 'THGDEBUG' in os.environ:
import win32traceutil
print('starting')
# os.Popen() needs this, and Mercurial still uses os.Popen
if 'COMSPEC' not in os.environ:
comspec = os.path.join(os.environ.get('SystemRoot', r'C:\Windows'),
'system32', 'cmd.exe')
os.environ['COMSPEC'] = comspec
else:
thgpath = os.path.dirname(os.path.realpath(__file__))
thgpath = os.path.dirname(thgpath)
testpath = os.path.join(thgpath, 'tortoisehg')
if os.path.isdir(testpath) and thgpath not in sys.path:
sys.path.insert(0, thgpath)
if 'HGPATH' in os.environ:
hgpath = os.environ['HGPATH']
testpath = os.path.join(hgpath, 'mercurial')
if os.path.isdir(testpath) and hgpath not in sys.path:
sys.path.insert(0, hgpath)
# Make sure to load threading by main thread; otherwise, _MainThread instance
# may have wrong thread id and results KeyError at exit.
import threading
from mercurial import demandimport
demandimport.IGNORES.update([
'win32com.shell',
'numpy', # comtypes.npsupport does try-import
'tortoisehg.util.config',
'tortoisehg.hgqt.icons_rc',
'tortoisehg.hgqt.translations_rc',
# don't create troublesome demandmods for bunch of Q* attributes
'tortoisehg.hgqt.qsci',
'tortoisehg.hgqt.qtcore',
'tortoisehg.hgqt.qtgui',
'tortoisehg.hgqt.qtnetwork',
# TODO: fix name resolution in demandimporter and remove these
'qsci',
'qtcore',
'qtgui',
'qtnetwork',
# pygments seems to have trouble on loading plugins (see #4271, #4298)
'pkgutil',
'pkg_resources',
])
demandimport.enable()
# Verify we can reach TortoiseHg sources first
try:
import tortoisehg.hgqt.run
except ImportError as e:
sys.stderr.write(str(e)+'\n')
sys.stderr.write("abort: couldn't find tortoisehg libraries in [%s]\n" %
os.pathsep.join(sys.path))
sys.stderr.write("(check your install and PYTHONPATH)\n")
sys.exit(-1)
def enforceversion():
"""Verify we have an acceptable version of Mercurial
Display an error dialog in the contrary.
"""
from tortoisehg.util.hgversion import hgversion, checkhgversion
errmsg = checkhgversion(hgversion)
if errmsg:
from tortoisehg.hgqt.bugreport import run
from tortoisehg.hgqt.run import qtrun
opts = {
'cmd': b' '.join(pycompat.sysargv),
'error': b'\n' + errmsg + b'\n',
'nofork': True,
}
qtrun(run, uimod.ui(), **opts)
sys.exit(1)
@command(b'view', [], _("hg view"), inferrepo=True)
def cmdview(ui, repo, *pats, **opts):
"""start light interactive history viewer from tortoisehg"""
enforceversion()
origstderr = sys.stderr
# TODO: Figure out if this hack for py2exe is still needed, and possibly
# wrap this to handle unicode on py3
if not pycompat.ispy3:
mystderr = util.bytesio()
sys.stderr = mystderr
sys.__stdout__ = sys.stdout
sys.__stderr__ = sys.stderr
procutil.stderr = sys.stderr
ret = 0
try:
from tortoisehg.hgqt.run import qtrun
from tortoisehg.hgqt.run import debuglighthg as startfunc
opts['repository'] = repo.root
qtrun(startfunc, ui, *pats, **opts)
if not pycompat.ispy3:
sys.stderr = origstderr
stderrout = mystderr.getvalue()
else:
stderrout = '' # TODO: handle stderr stream on py3
errors = ('Traceback', 'TypeError', 'NameError', 'AttributeError',
'NotImplementedError')
for l in stderrout.splitlines():
if l.startswith(errors):
from tortoisehg.hgqt.bugreport import run
opts = {'cmd': ' '.join(sys.argv),
'error': 'Recoverable error (stderr):\n' + stderrout,
'nofork': True}
qtrun(run, uimod.ui(), **opts)
break
sys.exit(ret)
except SystemExit:
raise
except:
procutil.stderr = sys.__stderr__ = sys.stderr = origstderr
raise
|