File: thg.py

package info (click to toggle)
tortoisehg 6.9-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 22,264 kB
  • sloc: python: 48,948; xml: 444; makefile: 107; sh: 5
file content (160 lines) | stat: -rw-r--r-- 5,076 bytes parent folder | download
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