author | Bryan O'Sullivan <bryano@fb.com> |
Fri, 15 Jan 2016 13:14:46 -0800 | |
changeset 27825 | 4692571df9ee |
parent 27793 | 8c9bbf5cd349 |
child 28014 | 83fc0c055664 |
permissions | -rw-r--r-- |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 |
# chgserver.py - command server extension for cHg |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 |
# |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 |
# Copyright 2011 Yuya Nishihara <yuya@tcha.org> |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 |
# |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of the |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 |
# GNU General Public License version 2 or any later version. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 |
"""command server extension for cHg (EXPERIMENTAL) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 |
'S' channel (read/write) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 |
propagate ui.system() request to client |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
13 |
'attachio' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 |
attach client's stdio passed by sendmsg() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 |
'chdir' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 |
change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
18 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 |
'getpager' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 |
checks if pager is enabled and which pager should be executed |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 |
'setenv' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 |
replace os.environ completely |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
25 |
'SIGHUP' signal |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
26 |
reload configuration files |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
27 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
28 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 |
from __future__ import absolute_import |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
31 |
import SocketServer |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
32 |
import errno |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
33 |
import os |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
34 |
import re |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
35 |
import signal |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 |
import struct |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
37 |
import traceback |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
38 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 |
from mercurial.i18n import _ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
41 |
from mercurial import ( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 |
cmdutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
43 |
commands, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
44 |
commandserver, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
45 |
dispatch, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
46 |
error, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
47 |
osutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
48 |
util, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
49 |
) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
50 |
|
27793
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
51 |
# Note for extension authors: ONLY specify testedwith = 'internal' for |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
52 |
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
53 |
# be specifying the version(s) of Mercurial they are tested with, or |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
54 |
# leave the attribute unspecified. |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
55 |
testedwith = 'internal' |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
56 |
|
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
57 |
_log = commandserver.log |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
58 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
59 |
# copied from hgext/pager.py:uisetup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 |
def _setuppagercmd(ui, options, cmd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 |
if not ui.formatted(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 |
return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 |
p = ui.config("pager", "pager", os.environ.get("PAGER")) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
65 |
usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 |
always = util.parsebool(options['pager']) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 |
auto = options['pager'] == 'auto' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 |
if not p: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
70 |
pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 |
elif always: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
72 |
usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 |
elif not auto: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 |
usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
75 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 |
attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 |
attend = ui.configlist('pager', 'attend', attended) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 |
ignore = ui.configlist('pager', 'ignore') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
79 |
cmds, _ = cmdutil.findcmd(cmd, commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
80 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
81 |
for cmd in cmds: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
82 |
var = 'attend-%s' % cmd |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
83 |
if ui.config('pager', var): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
84 |
usepager = ui.configbool('pager', var) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
85 |
break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
86 |
if (cmd in attend or |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
87 |
(cmd not in ignore and not attend)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
88 |
usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
89 |
break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
90 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 |
if usepager: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 |
ui.setconfig('ui', 'formatted', ui.formatted(), 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 |
ui.setconfig('ui', 'interactive', False, 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
94 |
return p |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
95 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
96 |
_envvarre = re.compile(r'\$[a-zA-Z_]+') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
97 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
98 |
def _clearenvaliases(cmdtable): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
99 |
"""Remove stale command aliases referencing env vars; variable expansion |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
100 |
is done at dispatch.addaliases()""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
101 |
for name, tab in cmdtable.items(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
102 |
cmddef = tab[0] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
103 |
if (isinstance(cmddef, dispatch.cmdalias) and |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
104 |
not cmddef.definition.startswith('!') and # shell alias |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
105 |
_envvarre.search(cmddef.definition)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
106 |
del cmdtable[name] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
107 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
108 |
def _newchgui(srcui, csystem): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
109 |
class chgui(srcui.__class__): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
110 |
def __init__(self, src=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
111 |
super(chgui, self).__init__(src) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
112 |
if src: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
113 |
self._csystem = getattr(src, '_csystem', csystem) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
114 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
115 |
self._csystem = csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
116 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
117 |
def system(self, cmd, environ=None, cwd=None, onerr=None, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
118 |
errprefix=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
119 |
# copied from mercurial/util.py:system() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
120 |
self.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
121 |
def py2shell(val): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
122 |
if val is None or val is False: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
123 |
return '0' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
124 |
if val is True: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
125 |
return '1' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
126 |
return str(val) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
127 |
env = os.environ.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
128 |
if environ: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
129 |
env.update((k, py2shell(v)) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
130 |
env['HG'] = util.hgexecutable() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
131 |
rc = self._csystem(cmd, env, cwd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
132 |
if rc and onerr: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
133 |
errmsg = '%s %s' % (os.path.basename(cmd.split(None, 1)[0]), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
134 |
util.explainexit(rc)[0]) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
135 |
if errprefix: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
136 |
errmsg = '%s: %s' % (errprefix, errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
137 |
raise onerr(errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
138 |
return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
139 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
140 |
return chgui(srcui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
141 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
142 |
def _renewui(srcui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
143 |
newui = srcui.__class__() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
144 |
for a in ['fin', 'fout', 'ferr', 'environ']: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
145 |
setattr(newui, a, getattr(srcui, a)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
146 |
if util.safehasattr(srcui, '_csystem'): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
147 |
newui._csystem = srcui._csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
148 |
# stolen from tortoisehg.util.copydynamicconfig() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
149 |
for section, name, value in srcui.walkconfig(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
150 |
source = srcui.configsource(section, name) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
151 |
if ':' in source: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
152 |
# path:line |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
153 |
continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
154 |
if source == 'none': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
155 |
# ui.configsource returns 'none' by default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
156 |
source = '' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
157 |
newui.setconfig(section, name, value, source) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
158 |
return newui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
159 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
160 |
class channeledsystem(object): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
161 |
"""Propagate ui.system() request in the following format: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
162 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
163 |
payload length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
164 |
cmd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
165 |
cwd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
166 |
envkey, '=', val, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
167 |
... |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
168 |
envkey, '=', val |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
169 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
170 |
and waits: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
171 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
172 |
exitcode length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
173 |
exitcode (int) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
174 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
175 |
def __init__(self, in_, out, channel): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
176 |
self.in_ = in_ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
177 |
self.out = out |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
178 |
self.channel = channel |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
179 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
180 |
def __call__(self, cmd, environ, cwd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
181 |
args = [util.quotecommand(cmd), cwd or '.'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
182 |
args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
183 |
data = '\0'.join(args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
184 |
self.out.write(struct.pack('>cI', self.channel, len(data))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
185 |
self.out.write(data) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
186 |
self.out.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
187 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
188 |
length = self.in_.read(4) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
189 |
length, = struct.unpack('>I', length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
190 |
if length != 4: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
191 |
raise error.Abort(_('invalid response')) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
192 |
rc, = struct.unpack('>i', self.in_.read(4)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
193 |
return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
194 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
195 |
_iochannels = [ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
196 |
# server.ch, ui.fp, mode |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
197 |
('cin', 'fin', 'rb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
198 |
('cout', 'fout', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
199 |
('cerr', 'ferr', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
200 |
] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
201 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
202 |
class chgcmdserver(commandserver.server): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
203 |
def __init__(self, ui, repo, fin, fout, sock): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
204 |
super(chgcmdserver, self).__init__( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
205 |
_newchgui(ui, channeledsystem(fin, fout, 'S')), repo, fin, fout) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
206 |
self.clientsock = sock |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
207 |
self._oldios = [] # original (self.ch, ui.fp, fd) before "attachio" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
208 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
209 |
def cleanup(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
210 |
# dispatch._runcatch() does not flush outputs if exception is not |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
211 |
# handled by dispatch._dispatch() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
212 |
self.ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
213 |
self._restoreio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
214 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
215 |
def attachio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
216 |
"""Attach to client's stdio passed via unix domain socket; all |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
217 |
channels except cresult will no longer be used |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
218 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
219 |
# tell client to sendmsg() with 1-byte payload, which makes it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
220 |
# distinctive from "attachio\n" command consumed by client.read() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
221 |
self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
222 |
clientfds = osutil.recvfds(self.clientsock.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
223 |
_log('received fds: %r\n' % clientfds) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
224 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
225 |
ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
226 |
ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
227 |
first = self._saveio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
228 |
for fd, (cn, fn, mode) in zip(clientfds, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
229 |
assert fd > 0 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
230 |
fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
231 |
os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
232 |
os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
233 |
if not first: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
234 |
continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
235 |
# reset buffering mode when client is first attached. as we want |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
236 |
# to see output immediately on pager, the mode stays unchanged |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
237 |
# when client re-attached. ferr is unchanged because it should |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
238 |
# be unbuffered no matter if it is a tty or not. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
239 |
if fn == 'ferr': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
240 |
newfp = fp |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
241 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
242 |
# make it line buffered explicitly because the default is |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
243 |
# decided on first write(), where fout could be a pager. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
244 |
if fp.isatty(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
245 |
bufsize = 1 # line buffered |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
246 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
247 |
bufsize = -1 # system default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
248 |
newfp = os.fdopen(fp.fileno(), mode, bufsize) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
249 |
setattr(ui, fn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
250 |
setattr(self, cn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
251 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
252 |
self.cresult.write(struct.pack('>i', len(clientfds))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
253 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
254 |
def _saveio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
255 |
if self._oldios: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
256 |
return False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
257 |
ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
258 |
for cn, fn, _mode in _iochannels: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
259 |
ch = getattr(self, cn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
260 |
fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
261 |
fd = os.dup(fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
262 |
self._oldios.append((ch, fp, fd)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
263 |
return True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
264 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
265 |
def _restoreio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
266 |
ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
267 |
for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
268 |
newfp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
269 |
# close newfp while it's associated with client; otherwise it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
270 |
# would be closed when newfp is deleted |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
271 |
if newfp is not fp: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
272 |
newfp.close() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
273 |
# restore original fd: fp is open again |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
274 |
os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
275 |
os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
276 |
setattr(self, cn, ch) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
277 |
setattr(ui, fn, fp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
278 |
del self._oldios[:] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
279 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
280 |
def chdir(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
281 |
"""Change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
282 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
283 |
Note that the behavior of --cwd option is bit different from this. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
284 |
It does not affect --config parameter. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
285 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
286 |
length = struct.unpack('>I', self._read(4))[0] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
287 |
if not length: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
288 |
return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
289 |
path = self._read(length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
290 |
_log('chdir to %r\n' % path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
291 |
os.chdir(path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
292 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
293 |
def getpager(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
294 |
"""Read cmdargs and write pager command to r-channel if enabled |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
295 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
296 |
If pager isn't enabled, this writes '\0' because channeledoutput |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
297 |
does not allow to write empty data. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
298 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
299 |
length = struct.unpack('>I', self._read(4))[0] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
300 |
if not length: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
301 |
args = [] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
302 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
303 |
args = self._read(length).split('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
304 |
try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
305 |
cmd, _func, args, options, _cmdoptions = dispatch._parse(self.ui, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
306 |
args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
307 |
except (error.Abort, error.AmbiguousCommand, error.CommandError, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
308 |
error.UnknownCommand): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
309 |
cmd = None |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
310 |
options = {} |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
311 |
if not cmd or 'pager' not in options: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
312 |
self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
313 |
return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
314 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
315 |
pagercmd = _setuppagercmd(self.ui, options, cmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
316 |
if pagercmd: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
317 |
self.cresult.write(pagercmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
318 |
else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
319 |
self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
320 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
321 |
def setenv(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
322 |
"""Clear and update os.environ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
323 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
324 |
Note that not all variables can make an effect on the running process. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
325 |
""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
326 |
length = struct.unpack('>I', self._read(4))[0] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
327 |
if not length: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
328 |
return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
329 |
s = self._read(length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
330 |
try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
331 |
newenv = dict(l.split('=', 1) for l in s.split('\0')) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
332 |
except ValueError: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
333 |
raise ValueError('unexpected value in setenv request') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
334 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
335 |
diffkeys = set(k for k in set(os.environ.keys() + newenv.keys()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
336 |
if os.environ.get(k) != newenv.get(k)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
337 |
_log('change env: %r\n' % sorted(diffkeys)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
338 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
339 |
os.environ.clear() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
340 |
os.environ.update(newenv) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
341 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
342 |
if set(['HGPLAIN', 'HGPLAINEXCEPT']) & diffkeys: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
343 |
# reload config so that ui.plain() takes effect |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
344 |
self.ui = _renewui(self.ui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
345 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
346 |
_clearenvaliases(commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
347 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
348 |
capabilities = commandserver.server.capabilities.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
349 |
capabilities.update({'attachio': attachio, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
350 |
'chdir': chdir, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
351 |
'getpager': getpager, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
352 |
'setenv': setenv}) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
353 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
354 |
# copied from mercurial/commandserver.py |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
355 |
class _requesthandler(SocketServer.StreamRequestHandler): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
356 |
def handle(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
357 |
ui = self.server.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
358 |
repo = self.server.repo |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
359 |
sv = chgcmdserver(ui, repo, self.rfile, self.wfile, self.connection) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
360 |
try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
361 |
try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
362 |
sv.serve() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
363 |
# handle exceptions that may be raised by command server. most of |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
364 |
# known exceptions are caught by dispatch. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
365 |
except error.Abort as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
366 |
ui.warn(_('abort: %s\n') % inst) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
367 |
except IOError as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
368 |
if inst.errno != errno.EPIPE: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
369 |
raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
370 |
except KeyboardInterrupt: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
371 |
pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
372 |
finally: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
373 |
sv.cleanup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
374 |
except: # re-raises |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
375 |
# also write traceback to error channel. otherwise client cannot |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
376 |
# see it because it is written to server's stderr by default. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
377 |
traceback.print_exc(file=sv.cerr) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
378 |
raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
379 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
380 |
class chgunixservice(commandserver.unixservice): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
381 |
def init(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
382 |
# drop options set for "hg serve --cmdserver" command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
383 |
self.ui.setconfig('progress', 'assume-tty', None) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
384 |
signal.signal(signal.SIGHUP, self._reloadconfig) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
385 |
class cls(SocketServer.ForkingMixIn, SocketServer.UnixStreamServer): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
386 |
ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
387 |
repo = self.repo |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
388 |
self.server = cls(self.address, _requesthandler) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
389 |
# avoid writing "listening at" message to stdout before attachio |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
390 |
# request, which calls setvbuf() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
391 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
392 |
def _reloadconfig(self, signum, frame): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
393 |
self.ui = self.server.ui = _renewui(self.ui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
394 |
|
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
395 |
def uisetup(ui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
396 |
commandserver._servicemap['chgunix'] = chgunixservice |