Mercurial > hg
annotate contrib/hgclient.py @ 28490:959eadae589a
changelog: lazily parse manifest node
Like the description, we store the raw bytes and convert from
hex on access.
This patch also marks the beginning of our new parsing method,
which is based on newline offsets and doesn't rely on
str.split().
Many revsets showed a performance improvement:
author(mpm)
0.896565
0.869085
0.868598
desc(bug)
0.887169
0.928164
0.910400
extra(rebase_source)
0.865446
0.871500
0.841644
author(mpm) or author(greg)
1.801832
1.791589
1.731503
author(mpm) or desc(bug)
1.812438
1.851003
1.798764
date(2015) or branch(default)
0.968276
0.974027
0.945792
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sun, 06 Mar 2016 14:29:13 -0800 |
parents | 897a4bbd578b |
children | 3f45488d70df |
rev | line source |
---|---|
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 # A minimal client for Mercurial's command server |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 |
28355
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
3 from __future__ import absolute_import, print_function |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
4 import cStringIO |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
5 import os |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
6 import signal |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
7 import socket |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
8 import struct |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
9 import subprocess |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
10 import sys |
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
11 import time |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
22992
892b2b8c1b50
test-commandserver: allow check() to make connection in different way
Yuya Nishihara <yuya@tcha.org>
parents:
22991
diff
changeset
|
13 def connectpipe(path=None): |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 cmdline = ['hg', 'serve', '--cmdserver', 'pipe'] |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 if path: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 cmdline += ['-R', path] |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
18 server = subprocess.Popen(cmdline, stdin=subprocess.PIPE, |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 stdout=subprocess.PIPE) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 return server |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 |
22993
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
23 class unixconnection(object): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
24 def __init__(self, sockpath): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
25 self.sock = sock = socket.socket(socket.AF_UNIX) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
26 sock.connect(sockpath) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
27 self.stdin = sock.makefile('wb') |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
28 self.stdout = sock.makefile('rb') |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
29 |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
30 def wait(self): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
31 self.stdin.close() |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
32 self.stdout.close() |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
33 self.sock.close() |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
34 |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
35 class unixserver(object): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
36 def __init__(self, sockpath, logpath=None, repopath=None): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
37 self.sockpath = sockpath |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
38 cmdline = ['hg', 'serve', '--cmdserver', 'unix', '-a', sockpath] |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
39 if repopath: |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
40 cmdline += ['-R', repopath] |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
41 if logpath: |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
42 stdout = open(logpath, 'a') |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
43 stderr = subprocess.STDOUT |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
44 else: |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
45 stdout = stderr = None |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
46 self.server = subprocess.Popen(cmdline, stdout=stdout, stderr=stderr) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
47 # wait for listen() |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
48 while self.server.poll() is None: |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
49 if os.path.exists(sockpath): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
50 break |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
51 time.sleep(0.1) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
52 |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
53 def connect(self): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
54 return unixconnection(self.sockpath) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
55 |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
56 def shutdown(self): |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
57 os.kill(self.server.pid, signal.SIGTERM) |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
58 self.server.wait() |
24c5fd2894f8
test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents:
22992
diff
changeset
|
59 |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 def writeblock(server, data): |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 server.stdin.write(struct.pack('>I', len(data))) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 server.stdin.write(data) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 server.stdin.flush() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
65 def readchannel(server): |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 data = server.stdout.read(5) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 if not data: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 raise EOFError |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 channel, length = struct.unpack('>cI', data) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
70 if channel in 'IL': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 return channel, length |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
72 else: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 return channel, server.stdout.read(length) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
75 def sep(text): |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 return text.replace('\\', '/') |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None, |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
79 outfilter=lambda x: x): |
28355
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
80 print('*** runcommand', ' '.join(args)) |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
81 sys.stdout.flush() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
82 server.stdin.write('runcommand\n') |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
83 writeblock(server, '\0'.join(args)) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
84 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
85 if not input: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
86 input = cStringIO.StringIO() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
87 |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
88 while True: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
89 ch, data = readchannel(server) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
90 if ch == 'o': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 output.write(outfilter(data)) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 output.flush() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 elif ch == 'e': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
94 error.write(data) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
95 error.flush() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
96 elif ch == 'I': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
97 writeblock(server, input.read(data)) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
98 elif ch == 'L': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
99 writeblock(server, input.readline(data)) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
100 elif ch == 'r': |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
101 ret, = struct.unpack('>i', data) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
102 if ret != 0: |
28355
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
103 print(' [%d]' % ret) |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
104 return ret |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
105 else: |
28355
897a4bbd578b
hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
22993
diff
changeset
|
106 print("unexpected channel %c: %r" % (ch, data)) |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
107 if ch.isupper(): |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
108 return |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
109 |
22992
892b2b8c1b50
test-commandserver: allow check() to make connection in different way
Yuya Nishihara <yuya@tcha.org>
parents:
22991
diff
changeset
|
110 def check(func, connect=connectpipe): |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
111 sys.stdout.flush() |
22991
a94594f5d52f
test-commandserver: remove unused repopath argument from check()
Yuya Nishihara <yuya@tcha.org>
parents:
22572
diff
changeset
|
112 server = connect() |
22566
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
113 try: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
114 return func(server) |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
115 finally: |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
116 server.stdin.close() |
480b7fefbb08
test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
117 server.wait() |