Mercurial > hg
annotate mercurial/commandserver.py @ 27407:bf4d5d8dc2aa
histedit: omit useless message from update (edit)
specifically:
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
author | timeless <timeless@mozdev.org> |
---|---|
date | Mon, 14 Dec 2015 23:04:17 +0000 |
parents | 9fd8f1552369 |
children | f4ca33e33781 |
rev | line source |
---|---|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
1 # commandserver.py - communicate with Mercurial's API over a pipe |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
2 # |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
3 # Copyright Matt Mackall <mpm@selenic.com> |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
4 # |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
7 |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
8 from __future__ import absolute_import |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
9 |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
10 import SocketServer |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
11 import errno |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
12 import os |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
13 import struct |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
14 import sys |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
15 import traceback |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
16 |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
17 from .i18n import _ |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
18 from . import ( |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
19 encoding, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
20 error, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
21 util, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
22 ) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
23 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
24 logfile = None |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
25 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
26 def log(*args): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
27 if not logfile: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
28 return |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
29 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
30 for a in args: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
31 logfile.write(str(a)) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
32 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
33 logfile.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
34 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
35 class channeledoutput(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
36 """ |
22561
1120b1e2f975
cmdserver: correct doc of channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
21195
diff
changeset
|
37 Write data to out in the following format: |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
38 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
39 data length (unsigned int), |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
40 data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
41 """ |
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
42 def __init__(self, out, channel): |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
43 self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
44 self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
45 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
46 def write(self, data): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
47 if not data: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
48 return |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
49 self.out.write(struct.pack('>cI', self.channel, len(data))) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
50 self.out.write(data) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
51 self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
52 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
53 def __getattr__(self, attr): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
54 if attr in ('isatty', 'fileno'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
55 raise AttributeError(attr) |
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
56 return getattr(self.out, attr) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
57 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
58 class channeledinput(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
59 """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
60 Read data from in_. |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
61 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
62 Requests for input are written to out in the following format: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
63 channel identifier - 'I' for plain input, 'L' line based (1 byte) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
64 how many bytes to send at most (unsigned int), |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
65 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
66 The client replies with: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
67 data length (unsigned int), 0 meaning EOF |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
68 data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
69 """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
70 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
71 maxchunksize = 4 * 1024 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
72 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
73 def __init__(self, in_, out, channel): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
74 self.in_ = in_ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
75 self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
76 self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
77 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
78 def read(self, size=-1): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
79 if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
80 # if we need to consume all the clients input, ask for 4k chunks |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
81 # so the pipe doesn't fill up risking a deadlock |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
82 size = self.maxchunksize |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
83 s = self._read(size, self.channel) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
84 buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
85 while s: |
14728
350dcd481410
cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents:
14719
diff
changeset
|
86 s = self._read(size, self.channel) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
87 buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
88 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
89 return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
90 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
91 return self._read(size, self.channel) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
92 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
93 def _read(self, size, channel): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
94 if not size: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
95 return '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
96 assert size > 0 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
97 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
98 # tell the client we need at most size bytes |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
99 self.out.write(struct.pack('>cI', channel, size)) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
100 self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
101 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
102 length = self.in_.read(4) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
103 length = struct.unpack('>I', length)[0] |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
104 if not length: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
105 return '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
106 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
107 return self.in_.read(length) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
108 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
109 def readline(self, size=-1): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
110 if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
111 size = self.maxchunksize |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
112 s = self._read(size, 'L') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
113 buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
114 # keep asking for more until there's either no more or |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
115 # we got a full line |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
116 while s and s[-1] != '\n': |
14728
350dcd481410
cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents:
14719
diff
changeset
|
117 s = self._read(size, 'L') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
118 buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
119 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
120 return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
121 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
122 return self._read(size, 'L') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
123 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
124 def __iter__(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
125 return self |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
126 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
127 def next(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
128 l = self.readline() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
129 if not l: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
130 raise StopIteration |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
131 return l |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
132 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
133 def __getattr__(self, attr): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
134 if attr in ('isatty', 'fileno'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
135 raise AttributeError(attr) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
136 return getattr(self.in_, attr) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
137 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
138 class server(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
139 """ |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
140 Listens for commands on fin, runs them and writes the output on a channel |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
141 based stream to fout. |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
142 """ |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
143 def __init__(self, ui, repo, fin, fout): |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
144 self.cwd = os.getcwd() |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
145 |
25832
5857be01962e
commandserver: mark developer-only logging option
Matt Mackall <mpm@selenic.com>
parents:
25660
diff
changeset
|
146 # developer config: cmdserver.log |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
147 logpath = ui.config("cmdserver", "log", None) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
148 if logpath: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
149 global logfile |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
150 if logpath == '-': |
17425
e95ec38f86b0
fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents:
16687
diff
changeset
|
151 # write log on a special 'd' (debug) channel |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
152 logfile = channeledoutput(fout, 'd') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
153 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
154 logfile = open(logpath, 'a') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
155 |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
156 if repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
157 # the ui here is really the repo ui so take its baseui so we don't |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
158 # end up with its local configuration |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
159 self.ui = repo.baseui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
160 self.repo = repo |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
161 self.repoui = repo.ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
162 else: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
163 self.ui = ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
164 self.repo = self.repoui = None |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
165 |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
166 self.cerr = channeledoutput(fout, 'e') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
167 self.cout = channeledoutput(fout, 'o') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
168 self.cin = channeledinput(fin, fout, 'I') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
169 self.cresult = channeledoutput(fout, 'r') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
170 |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
171 self.client = fin |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
172 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
173 def _read(self, size): |
14706
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
174 if not size: |
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
175 return '' |
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
176 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
177 data = self.client.read(size) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
178 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
179 # is the other end closed? |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
180 if not data: |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16683
diff
changeset
|
181 raise EOFError |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
182 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
183 return data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
184 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
185 def runcommand(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
186 """ reads a list of \0 terminated arguments, executes |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
187 and writes the return code to the result channel """ |
27352
9fd8f1552369
commandserver: cut import cycle by itself
Yuya Nishihara <yuya@tcha.org>
parents:
27351
diff
changeset
|
188 from . import dispatch # avoid cycle |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
189 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
190 length = struct.unpack('>I', self._read(4))[0] |
14707
964a72038bb0
cmdserver, runcommand: properly handle the client sending no arguments
Idan Kamara <idankk86@gmail.com>
parents:
14706
diff
changeset
|
191 if not length: |
964a72038bb0
cmdserver, runcommand: properly handle the client sending no arguments
Idan Kamara <idankk86@gmail.com>
parents:
14706
diff
changeset
|
192 args = [] |
964a72038bb0
cmdserver, runcommand: properly handle the client sending no arguments
Idan Kamara <idankk86@gmail.com>
parents:
14706
diff
changeset
|
193 else: |
964a72038bb0
cmdserver, runcommand: properly handle the client sending no arguments
Idan Kamara <idankk86@gmail.com>
parents:
14706
diff
changeset
|
194 args = self._read(length).split('\0') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
195 |
14750
f5f97a0f983f
cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14728
diff
changeset
|
196 # copy the uis so changes (e.g. --config or --verbose) don't |
f5f97a0f983f
cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14728
diff
changeset
|
197 # persist between requests |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
198 copiedui = self.ui.copy() |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
199 uis = [copiedui] |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
200 if self.repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
201 self.repo.baseui = copiedui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
202 # clone ui without using ui.copy because this is protected |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
203 repoui = self.repoui.__class__(self.repoui) |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
204 repoui.copy = copiedui.copy # redo copy protection |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
205 uis.append(repoui) |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
206 self.repo.ui = self.repo.dirstate._ui = repoui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
207 self.repo.invalidateall() |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
208 |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
209 for ui in uis: |
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
210 # any kind of interaction must use server channels |
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
211 ui.setconfig('ui', 'nontty', 'true', 'commandserver') |
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
212 |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
213 req = dispatch.request(args[:], copiedui, self.repo, self.cin, |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
214 self.cout, self.cerr) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
215 |
20631
5d4606bec54c
cmdserver: mask return code of runcommand in the same way as dispatch.run
Yuya Nishihara <yuya@tcha.org>
parents:
20627
diff
changeset
|
216 ret = (dispatch.dispatch(req) or 0) & 255 # might return None |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
217 |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
218 # restore old cwd |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
219 if '--cwd' in args: |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
220 os.chdir(self.cwd) |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
221 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
222 self.cresult.write(struct.pack('>i', int(ret))) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
223 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
224 def getencoding(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
225 """ writes the current encoding to the result channel """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
226 self.cresult.write(encoding.encoding) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
227 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
228 def serveone(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
229 cmd = self.client.readline()[:-1] |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
230 if cmd: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
231 handler = self.capabilities.get(cmd) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
232 if handler: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
233 handler(self) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
234 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
235 # clients are expected to check what commands are supported by |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
236 # looking at the servers capabilities |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
237 raise error.Abort(_('unknown command %s') % cmd) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
238 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
239 return cmd != '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
240 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
241 capabilities = {'runcommand' : runcommand, |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
242 'getencoding' : getencoding} |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
243 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
244 def serve(self): |
18359
4b09e6f7d7de
commandserver: report capabilities sorted
Mads Kiilerich <mads@kiilerich.com>
parents:
18174
diff
changeset
|
245 hellomsg = 'capabilities: ' + ' '.join(sorted(self.capabilities)) |
14719
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
246 hellomsg += '\n' |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
247 hellomsg += 'encoding: ' + encoding.encoding |
23036
19f5273c9f3e
cmdserver: include pid of server handling requests in hello message
Yuya Nishihara <yuya@tcha.org>
parents:
22994
diff
changeset
|
248 hellomsg += '\n' |
19f5273c9f3e
cmdserver: include pid of server handling requests in hello message
Yuya Nishihara <yuya@tcha.org>
parents:
22994
diff
changeset
|
249 hellomsg += 'pid: %d' % os.getpid() |
14719
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
250 |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
251 # write the hello msg in -one- chunk |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
252 self.cout.write(hellomsg) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
253 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
254 try: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
255 while self.serveone(): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
256 pass |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
257 except EOFError: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
258 # we'll get here if the client disconnected while we were reading |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
259 # its request |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
260 return 1 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
261 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
262 return 0 |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
263 |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
264 def _protectio(ui): |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
265 """ duplicates streams and redirect original to null if ui uses stdio """ |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
266 ui.flush() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
267 newfiles = [] |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
268 nullfd = os.open(os.devnull, os.O_RDWR) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
269 for f, sysf, mode in [(ui.fin, sys.stdin, 'rb'), |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
270 (ui.fout, sys.stdout, 'wb')]: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
271 if f is sysf: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
272 newfd = os.dup(f.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
273 os.dup2(nullfd, f.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
274 f = os.fdopen(newfd, mode) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
275 newfiles.append(f) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
276 os.close(nullfd) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
277 return tuple(newfiles) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
278 |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
279 def _restoreio(ui, fin, fout): |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
280 """ restores streams from duplicated ones """ |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
281 ui.flush() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
282 for f, uif in [(fin, ui.fin), (fout, ui.fout)]: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
283 if f is not uif: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
284 os.dup2(f.fileno(), uif.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
285 f.close() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
286 |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
287 class pipeservice(object): |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
288 def __init__(self, ui, repo, opts): |
23323
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
289 self.ui = ui |
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
290 self.repo = repo |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
291 |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
292 def init(self): |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
293 pass |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
294 |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
295 def run(self): |
23323
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
296 ui = self.ui |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
297 # redirect stdio to null device so that broken extensions or in-process |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
298 # hooks will never cause corruption of channel protocol. |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
299 fin, fout = _protectio(ui) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
300 try: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
301 sv = server(ui, self.repo, fin, fout) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
302 return sv.serve() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
303 finally: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
304 _restoreio(ui, fin, fout) |
22989
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
305 |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
306 class _requesthandler(SocketServer.StreamRequestHandler): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
307 def handle(self): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
308 ui = self.server.ui |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
309 repo = self.server.repo |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
310 sv = server(ui, repo, self.rfile, self.wfile) |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
311 try: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
312 try: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
313 sv.serve() |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
314 # handle exceptions that may be raised by command server. most of |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
315 # known exceptions are caught by dispatch. |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
316 except error.Abort as inst: |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
317 ui.warn(_('abort: %s\n') % inst) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23324
diff
changeset
|
318 except IOError as inst: |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
319 if inst.errno != errno.EPIPE: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
320 raise |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
321 except KeyboardInterrupt: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
322 pass |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
323 except: # re-raises |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
324 # also write traceback to error channel. otherwise client cannot |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
325 # see it because it is written to server's stderr by default. |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
326 traceback.print_exc(file=sv.cerr) |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
327 raise |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
328 |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
329 class unixservice(object): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
330 """ |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
331 Listens on unix domain socket and forks server per connection |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
332 """ |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
333 def __init__(self, ui, repo, opts): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
334 self.ui = ui |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
335 self.repo = repo |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
336 self.address = opts['address'] |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
337 if not util.safehasattr(SocketServer, 'UnixStreamServer'): |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
338 raise error.Abort(_('unsupported platform')) |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
339 if not self.address: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
340 raise error.Abort(_('no socket path specified with --address')) |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
341 |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
342 def init(self): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
343 class cls(SocketServer.ForkingMixIn, SocketServer.UnixStreamServer): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
344 ui = self.ui |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
345 repo = self.repo |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
346 self.server = cls(self.address, _requesthandler) |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
347 self.ui.status(_('listening at %s\n') % self.address) |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
348 self.ui.flush() # avoid buffering of status message |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
349 |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
350 def run(self): |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
351 try: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
352 self.server.serve_forever() |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
353 finally: |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
354 os.unlink(self.address) |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
355 |
22989
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
356 _servicemap = { |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
357 'pipe': pipeservice, |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
358 'unix': unixservice, |
22989
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
359 } |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
360 |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
361 def createservice(ui, repo, opts): |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
362 mode = opts['cmdserver'] |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
363 try: |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
364 return _servicemap[mode](ui, repo, opts) |
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
365 except KeyError: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
366 raise error.Abort(_('unknown mode %s') % mode) |