6 """ |
6 """ |
7 Module implementing an interface to the Mercurial command server. |
7 Module implementing an interface to the Mercurial command server. |
8 """ |
8 """ |
9 |
9 |
10 try: |
10 try: |
11 str = unicode # __IGNORE_WARNING__ |
11 str = unicode |
12 except (NameError): |
12 except NameError: |
13 pass |
13 pass |
14 |
14 |
15 import struct |
15 import struct |
16 import io |
16 import io |
17 |
17 |
18 from PyQt4.QtCore import QProcess, QObject, QByteArray, QCoreApplication, \ |
18 from PyQt4.QtCore import QProcess, QObject, QByteArray, QCoreApplication, \ |
19 QThread |
19 QThread |
20 from PyQt4.QtGui import QDialog |
20 from PyQt4.QtGui import QDialog |
21 |
21 |
22 from .HgUtilities import prepareProcess |
22 from .HgUtilities import prepareProcess |
23 |
|
24 import Preferences |
|
25 |
23 |
26 |
24 |
27 class HgClient(QObject): |
25 class HgClient(QObject): |
28 """ |
26 """ |
29 Class implementing the Mercurial command server interface. |
27 Class implementing the Mercurial command server interface. |
46 super(HgClient, self).__init__(parent) |
44 super(HgClient, self).__init__(parent) |
47 |
45 |
48 self.__server = None |
46 self.__server = None |
49 self.__started = False |
47 self.__started = False |
50 self.__version = None |
48 self.__version = None |
51 self.__encoding = Preferences.getSystem("IOEncoding") |
49 self.__encoding = parent.getEncoding() |
52 self.__cancel = False |
50 self.__cancel = False |
53 self.__commandRunning = False |
51 self.__commandRunning = False |
54 self.__repoPath = repoPath |
52 self.__repoPath = repoPath |
55 |
53 |
56 # generate command line and environment |
54 # generate command line and environment |
57 self.__serverArgs = [] |
55 self.__serverArgs = parent.initCommand("serve") # parent is hg |
58 self.__serverArgs.append("serve") |
|
59 self.__serverArgs.append("--cmdserver") |
56 self.__serverArgs.append("--cmdserver") |
60 self.__serverArgs.append("pipe") |
57 self.__serverArgs.append("pipe") |
61 self.__serverArgs.append("--config") |
58 self.__serverArgs.append("--config") |
62 self.__serverArgs.append("ui.interactive=True") |
59 self.__serverArgs.append("ui.interactive=True") |
63 if repoPath: |
60 if repoPath: |
64 self.__serverArgs.append("--repository") |
61 self.__serverArgs.append("--repository") |
65 self.__serverArgs.append(repoPath) |
62 self.__serverArgs.append(repoPath) |
66 |
63 |
67 if encoding: |
64 if encoding: |
68 self.__encoding = encoding |
65 self.__encoding = encoding |
|
66 if "--encoding" in self.__serverArgs: |
|
67 # use the defined encoding via the environment |
|
68 index = self.__serverArgs.index("--encoding") |
|
69 del self.__serverArgs[index:index + 2] |
69 |
70 |
70 def startServer(self): |
71 def startServer(self): |
71 """ |
72 """ |
72 Public method to start the command server. |
73 Public method to start the command server. |
73 |
74 |
83 prepareProcess(self.__server, self.__encoding) |
84 prepareProcess(self.__server, self.__encoding) |
84 |
85 |
85 self.__server.start('hg', self.__serverArgs) |
86 self.__server.start('hg', self.__serverArgs) |
86 serverStarted = self.__server.waitForStarted(5000) |
87 serverStarted = self.__server.waitForStarted(5000) |
87 if not serverStarted: |
88 if not serverStarted: |
88 return False, self.trUtf8( |
89 return False, self.tr( |
89 'The process {0} could not be started. ' |
90 'The process {0} could not be started. ' |
90 'Ensure, that it is in the search path.' |
91 'Ensure, that it is in the search path.' |
91 ).format('hg') |
92 ).format('hg') |
92 |
93 |
93 self.__server.setReadChannel(QProcess.StandardOutput) |
94 self.__server.setReadChannel(QProcess.StandardOutput) |
130 @return tuple of flag indicating success (boolean) and an error message |
131 @return tuple of flag indicating success (boolean) and an error message |
131 in case of failure (string) |
132 in case of failure (string) |
132 """ |
133 """ |
133 ch, msg = self.__readChannel() |
134 ch, msg = self.__readChannel() |
134 if not ch: |
135 if not ch: |
135 return False, self.trUtf8("Did not receive the 'hello' message.") |
136 return False, self.tr("Did not receive the 'hello' message.") |
136 elif ch != "o": |
137 elif ch != "o": |
137 return False, self.trUtf8("Received data on unexpected channel.") |
138 return False, self.tr("Received data on unexpected channel.") |
138 |
139 |
139 msg = msg.split("\n") |
140 msg = msg.split("\n") |
140 |
141 |
141 if not msg[0].startswith("capabilities: "): |
142 if not msg[0].startswith("capabilities: "): |
142 return False, self.trUtf8( |
143 return False, self.tr( |
143 "Bad 'hello' message, expected 'capabilities: '" |
144 "Bad 'hello' message, expected 'capabilities: '" |
144 " but got '{0}'.").format(msg[0]) |
145 " but got '{0}'.").format(msg[0]) |
145 self.__capabilities = msg[0][len('capabilities: '):] |
146 self.__capabilities = msg[0][len('capabilities: '):] |
146 if not self.__capabilities: |
147 if not self.__capabilities: |
147 return False, self.trUtf8("'capabilities' message did not contain" |
148 return False, self.tr("'capabilities' message did not contain" |
148 " any capability.") |
149 " any capability.") |
149 |
150 |
150 self.__capabilities = set(self.__capabilities.split()) |
151 self.__capabilities = set(self.__capabilities.split()) |
151 if "runcommand" not in self.__capabilities: |
152 if "runcommand" not in self.__capabilities: |
152 return False, "'capabilities' did not contain 'runcommand'." |
153 return False, "'capabilities' did not contain 'runcommand'." |
153 |
154 |
154 if not msg[1].startswith("encoding: "): |
155 if not msg[1].startswith("encoding: "): |
155 return False, self.trUtf8( |
156 return False, self.tr( |
156 "Bad 'hello' message, expected 'encoding: '" |
157 "Bad 'hello' message, expected 'encoding: '" |
157 " but got '{0}'.").format(msg[1]) |
158 " but got '{0}'.").format(msg[1]) |
158 encoding = msg[1][len('encoding: '):] |
159 encoding = msg[1][len('encoding: '):] |
159 if not encoding: |
160 if not encoding: |
160 return False, self.trUtf8("'encoding' message did not contain" |
161 return False, self.tr("'encoding' message did not contain" |
161 " any encoding.") |
162 " any encoding.") |
162 self.__encoding = encoding |
163 self.__encoding = encoding |
163 |
164 |
164 return True, "" |
165 return True, "" |
165 |
166 |
166 def __serverFinished(self, exitCode, exitStatus): |
167 def __serverFinished(self, exitCode, exitStatus): |
336 return reply |
337 return reply |
337 inputChannels["L"] = func |
338 inputChannels["L"] = func |
338 else: |
339 else: |
339 def myprompt(size): |
340 def myprompt(size): |
340 if outputBuffer is None: |
341 if outputBuffer is None: |
341 msg = self.trUtf8("For message see output dialog.") |
342 msg = self.tr("For message see output dialog.") |
342 else: |
343 else: |
343 msg = outputBuffer.getvalue() |
344 msg = outputBuffer.getvalue() |
344 reply = self.__prompt(size, msg) |
345 reply = self.__prompt(size, msg) |
345 return reply |
346 return reply |
346 inputChannels["L"] = myprompt |
347 inputChannels["L"] = myprompt |