Show More
@@ -0,0 +1,75 b'' | |||||
|
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 | ||||
|
67 | print 'testing %s:' % func.__name__ | |||
|
68 | ||||
|
69 | sys.stdout.flush() | |||
|
70 | server = connect(repopath) | |||
|
71 | try: | |||
|
72 | return func(server) | |||
|
73 | finally: | |||
|
74 | server.stdin.close() | |||
|
75 | server.wait() |
@@ -1,76 +1,7 b'' | |||||
1 |
import sys, os |
|
1 | import sys, os, cStringIO, re, shutil | |
2 |
|
||||
3 | def connect(path=None): |
|
|||
4 | cmdline = ['hg', 'serve', '--cmdserver', 'pipe'] |
|
|||
5 | if path: |
|
|||
6 | cmdline += ['-R', path] |
|
|||
7 |
|
||||
8 | server = subprocess.Popen(cmdline, stdin=subprocess.PIPE, |
|
|||
9 | stdout=subprocess.PIPE) |
|
|||
10 |
|
||||
11 | return server |
|
|||
12 |
|
||||
13 | def writeblock(server, data): |
|
|||
14 | server.stdin.write(struct.pack('>I', len(data))) |
|
|||
15 | server.stdin.write(data) |
|
|||
16 | server.stdin.flush() |
|
|||
17 |
|
||||
18 | def readchannel(server): |
|
|||
19 | data = server.stdout.read(5) |
|
|||
20 | if not data: |
|
|||
21 | raise EOFError |
|
|||
22 | channel, length = struct.unpack('>cI', data) |
|
|||
23 | if channel in 'IL': |
|
|||
24 | return channel, length |
|
|||
25 | else: |
|
|||
26 | return channel, server.stdout.read(length) |
|
|||
27 |
|
||||
28 | def sep(text): |
|
|||
29 | return text.replace('\\', '/') |
|
|||
30 |
|
||||
31 | def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None, |
|
|||
32 | outfilter=lambda x: x): |
|
|||
33 | print ' runcommand', ' '.join(args) |
|
|||
34 | sys.stdout.flush() |
|
|||
35 | server.stdin.write('runcommand\n') |
|
|||
36 | writeblock(server, '\0'.join(args)) |
|
|||
37 |
|
2 | |||
38 | if not input: |
|
3 | sys.path.insert(0, os.path.join(os.environ['TESTDIR'], '..', 'contrib')) | |
39 | input = cStringIO.StringIO() |
|
4 | from hgclient import readchannel, sep, runcommand, check | |
40 |
|
||||
41 | while True: |
|
|||
42 | ch, data = readchannel(server) |
|
|||
43 | if ch == 'o': |
|
|||
44 | output.write(outfilter(data)) |
|
|||
45 | output.flush() |
|
|||
46 | elif ch == 'e': |
|
|||
47 | error.write(data) |
|
|||
48 | error.flush() |
|
|||
49 | elif ch == 'I': |
|
|||
50 | writeblock(server, input.read(data)) |
|
|||
51 | elif ch == 'L': |
|
|||
52 | writeblock(server, input.readline(data)) |
|
|||
53 | elif ch == 'r': |
|
|||
54 | ret, = struct.unpack('>i', data) |
|
|||
55 | if ret != 0: |
|
|||
56 | print ' [%d]' % ret |
|
|||
57 | return ret |
|
|||
58 | else: |
|
|||
59 | print "unexpected channel %c: %r" % (ch, data) |
|
|||
60 | if ch.isupper(): |
|
|||
61 | return |
|
|||
62 |
|
||||
63 | def check(func, repopath=None): |
|
|||
64 |
|
||||
65 | print 'testing %s:' % func.__name__ |
|
|||
66 |
|
||||
67 | sys.stdout.flush() |
|
|||
68 | server = connect(repopath) |
|
|||
69 | try: |
|
|||
70 | return func(server) |
|
|||
71 | finally: |
|
|||
72 | server.stdin.close() |
|
|||
73 | server.wait() |
|
|||
74 |
|
5 | |||
75 | def unknowncommand(server): |
|
6 | def unknowncommand(server): | |
76 | server.stdin.write('unknowncommand\n') |
|
7 | server.stdin.write('unknowncommand\n') |
General Comments 0
You need to be logged in to leave comments.
Login now