comparison contrib/hgclient.py @ 22566:480b7fefbb08

test-commandserver: split helper functions to new hgclient module This prepares for porting test-commandserver.py to .t test. Though command-server test needs many Python codes, .t test will be more readable than .py test thanks to inlined output.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 28 Sep 2014 13:31:16 +0900
parents
children db497a1ef1c1
comparison
equal deleted inserted replaced
22565:8d45a42b0c0f 22566:480b7fefbb08
1 # A minimal client for Mercurial's command server
2
3 import sys, struct, subprocess, cStringIO
4
5 def connect(path=None):
6 cmdline = ['hg', 'serve', '--cmdserver', 'pipe']
7 if path:
8 cmdline += ['-R', path]
9
10 server = subprocess.Popen(cmdline, stdin=subprocess.PIPE,
11 stdout=subprocess.PIPE)
12
13 return server
14
15 def writeblock(server, data):
16 server.stdin.write(struct.pack('>I', len(data)))
17 server.stdin.write(data)
18 server.stdin.flush()
19
20 def readchannel(server):
21 data = server.stdout.read(5)
22 if not data:
23 raise EOFError
24 channel, length = struct.unpack('>cI', data)
25 if channel in 'IL':
26 return channel, length
27 else:
28 return channel, server.stdout.read(length)
29
30 def sep(text):
31 return text.replace('\\', '/')
32
33 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None,
34 outfilter=lambda x: x):
35 print ' runcommand', ' '.join(args)
36 sys.stdout.flush()
37 server.stdin.write('runcommand\n')
38 writeblock(server, '\0'.join(args))
39
40 if not input:
41 input = cStringIO.StringIO()
42
43 while True:
44 ch, data = readchannel(server)
45 if ch == 'o':
46 output.write(outfilter(data))
47 output.flush()
48 elif ch == 'e':
49 error.write(data)
50 error.flush()
51 elif ch == 'I':
52 writeblock(server, input.read(data))
53 elif ch == 'L':
54 writeblock(server, input.readline(data))
55 elif ch == 'r':
56 ret, = struct.unpack('>i', data)
57 if ret != 0:
58 print ' [%d]' % ret
59 return ret
60 else:
61 print "unexpected channel %c: %r" % (ch, data)
62 if ch.isupper():
63 return
64
65 def check(func, repopath=None):
66 print
67 print 'testing %s:' % func.__name__
68 print
69 sys.stdout.flush()
70 server = connect(repopath)
71 try:
72 return func(server)
73 finally:
74 server.stdin.close()
75 server.wait()