31 |
31 |
32 def __init__(self, repoPath, encoding, vcs, parent=None): |
32 def __init__(self, repoPath, encoding, vcs, parent=None): |
33 """ |
33 """ |
34 Constructor |
34 Constructor |
35 |
35 |
36 @param repoPath root directory of the repository (string) |
36 @param repoPath root directory of the repository |
37 @param encoding encoding to be used by the command server (string) |
37 @type str |
38 @param vcs reference to the VCS object (Hg) |
38 @param encoding encoding to be used by the command server |
39 @param parent reference to the parent object (QObject) |
39 @type str |
|
40 @param vcs reference to the VCS object |
|
41 @type Hg |
|
42 @param parent reference to the parent object |
|
43 @type QObject |
40 """ |
44 """ |
41 super(HgClient, self).__init__(parent) |
45 super(HgClient, self).__init__(parent) |
42 |
46 |
43 self.__server = None |
47 self.__server = None |
44 self.__started = False |
48 self.__started = False |
67 |
71 |
68 def startServer(self): |
72 def startServer(self): |
69 """ |
73 """ |
70 Public method to start the command server. |
74 Public method to start the command server. |
71 |
75 |
72 @return tuple of flag indicating a successful start (boolean) and |
76 @return tuple of flag indicating a successful start and an error |
73 an error message (string) in case of failure |
77 message in case of failure |
|
78 @rtype tuple of (bool, str) |
74 """ |
79 """ |
75 self.__server = QProcess() |
80 self.__server = QProcess() |
76 self.__server.setWorkingDirectory(self.__repoPath) |
81 self.__server.setWorkingDirectory(self.__repoPath) |
77 |
82 |
78 # connect signals |
83 # connect signals |
113 |
118 |
114 def restartServer(self): |
119 def restartServer(self): |
115 """ |
120 """ |
116 Public method to restart the command server. |
121 Public method to restart the command server. |
117 |
122 |
118 @return tuple of flag indicating a successful start (boolean) and |
123 @return tuple of flag indicating a successful start and an error |
119 an error message (string) in case of failure |
124 message in case of failure |
|
125 @rtype tuple of (bool, str) |
120 """ |
126 """ |
121 self.stopServer() |
127 self.stopServer() |
122 return self.startServer() |
128 return self.startServer() |
123 |
129 |
124 def __readHello(self): |
130 def __readHello(self): |
125 """ |
131 """ |
126 Private method to read the hello message sent by the command server. |
132 Private method to read the hello message sent by the command server. |
127 |
133 |
128 @return tuple of flag indicating success (boolean) and an error message |
134 @return tuple of flag indicating success and an error message in case |
129 in case of failure (string) |
135 of failure |
|
136 @rtype tuple of (bool, str) |
130 """ |
137 """ |
131 ch, msg = self.__readChannel() |
138 ch, msg = self.__readChannel() |
132 if not ch: |
139 if not ch: |
133 return False, self.tr("Did not receive the 'hello' message.") |
140 return False, self.tr("Did not receive the 'hello' message.") |
134 elif ch != "o": |
141 elif ch != "o": |
163 |
170 |
164 def __serverFinished(self, exitCode, exitStatus): |
171 def __serverFinished(self, exitCode, exitStatus): |
165 """ |
172 """ |
166 Private slot connected to the finished signal. |
173 Private slot connected to the finished signal. |
167 |
174 |
168 @param exitCode exit code of the process (integer) |
175 @param exitCode exit code of the process |
169 @param exitStatus exit status of the process (QProcess.ExitStatus) |
176 @type int |
|
177 @param exitStatus exit status of the process |
|
178 @type QProcess.ExitStatus |
170 """ |
179 """ |
171 self.__started = False |
180 self.__started = False |
172 |
181 |
173 def __readChannel(self): |
182 def __readChannel(self): |
174 """ |
183 """ |
175 Private method to read data from the command server. |
184 Private method to read data from the command server. |
176 |
185 |
177 @return tuple of channel designator and channel data |
186 @return tuple of channel designator and channel data |
178 (string, integer or string or bytes) |
187 @rtype tuple of (str, int or str or bytes) |
179 """ |
188 """ |
180 if ( |
189 if ( |
181 self.__server.bytesAvailable() > 0 or |
190 self.__server.bytesAvailable() > 0 or |
182 self.__server.waitForReadyRead(10000) |
191 self.__server.waitForReadyRead(10000) |
183 ): |
192 ): |
207 |
216 |
208 def __writeDataBlock(self, data): |
217 def __writeDataBlock(self, data): |
209 """ |
218 """ |
210 Private slot to write some data to the command server. |
219 Private slot to write some data to the command server. |
211 |
220 |
212 @param data data to be sent (string) |
221 @param data data to be sent |
|
222 @type str |
213 """ |
223 """ |
214 if not isinstance(data, bytes): |
224 if not isinstance(data, bytes): |
215 data = data.encode(self.__encoding) |
225 data = data.encode(self.__encoding) |
216 self.__server.write( |
226 self.__server.write( |
217 QByteArray(struct.pack(HgClient.InputFormat, len(data)))) |
227 QByteArray(struct.pack(HgClient.InputFormat, len(data)))) |
220 |
230 |
221 def __runcommand(self, args, inputChannels, outputChannels): |
231 def __runcommand(self, args, inputChannels, outputChannels): |
222 """ |
232 """ |
223 Private method to run a command in the server (low level). |
233 Private method to run a command in the server (low level). |
224 |
234 |
225 @param args list of arguments for the command (list of string) |
235 @param args list of arguments for the command |
|
236 @type list of str |
226 @param inputChannels dictionary of input channels. The dictionary must |
237 @param inputChannels dictionary of input channels. The dictionary must |
227 have the keys 'I' and 'L' and each entry must be a function |
238 have the keys 'I' and 'L' and each entry must be a function |
228 receiving the number of bytes to write. |
239 receiving the number of bytes to write. |
|
240 @type dict |
229 @param outputChannels dictionary of output channels. The dictionary |
241 @param outputChannels dictionary of output channels. The dictionary |
230 must have the keys 'o' and 'e' and each entry must be a function |
242 must have the keys 'o' and 'e' and each entry must be a function |
231 receiving the data. |
243 receiving the data. |
|
244 @type dict |
232 @return result code of the command, -1 if the command server wasn't |
245 @return result code of the command, -1 if the command server wasn't |
233 started or -10, if the command was canceled (integer) |
246 started or -10, if the command was canceled |
|
247 @rtype int |
234 @exception RuntimeError raised to indicate an unexpected command |
248 @exception RuntimeError raised to indicate an unexpected command |
235 channel |
249 channel |
236 """ |
250 """ |
237 if not self.__started: |
251 if not self.__started: |
238 return -1 |
252 return -1 |
284 |
298 |
285 def __prompt(self, size, message): |
299 def __prompt(self, size, message): |
286 """ |
300 """ |
287 Private method to prompt the user for some input. |
301 Private method to prompt the user for some input. |
288 |
302 |
289 @param size maximum length of the requested input (integer) |
303 @param size maximum length of the requested input |
290 @param message message sent by the server (string) |
304 @type int |
291 @return data entered by the user (string) |
305 @param message message sent by the server |
|
306 @type str |
|
307 @return tuple containing data entered by the user and |
|
308 a flag indicating a password input |
|
309 @rtype tuple of (str, bool) |
292 """ |
310 """ |
293 from .HgClientPromptDialog import HgClientPromptDialog |
311 from .HgClientPromptDialog import HgClientPromptDialog |
294 inputData = "" |
312 inputData = "" |
295 isPassword = False |
313 isPassword = False |
296 dlg = HgClientPromptDialog(size, message) |
314 dlg = HgClientPromptDialog(size, message) |
302 def runcommand(self, args, prompt=None, inputData=None, output=None, |
320 def runcommand(self, args, prompt=None, inputData=None, output=None, |
303 error=None): |
321 error=None): |
304 """ |
322 """ |
305 Public method to execute a command via the command server. |
323 Public method to execute a command via the command server. |
306 |
324 |
307 @param args list of arguments for the command (list of string) |
325 @param args list of arguments for the command |
308 @keyparam prompt function to reply to prompts by the server. It |
326 @type list of str |
|
327 @param prompt function to reply to prompts by the server. It |
309 receives the max number of bytes to return and the contents |
328 receives the max number of bytes to return and the contents |
310 of the output channel received so far. |
329 of the output channel received so far. If an output function is |
311 @keyparam inputData function to reply to bulk data requests by the |
330 given as well, the prompt data is passed through the output |
|
331 function. The function must return the input data and a flag |
|
332 indicating a password input. |
|
333 @type func(int, str) -> (str, bool) |
|
334 @param inputData function to reply to bulk data requests by the |
312 server. It receives the max number of bytes to return. |
335 server. It receives the max number of bytes to return. |
313 @keyparam output function receiving the data from the server (string). |
336 @type func(int) -> bytes |
314 If a prompt function is given, this parameter will be ignored. |
337 @param output function receiving the data from the server. If a |
315 @keyparam error function receiving error messages from the server |
338 prompt function is given, it is assumed, that the prompt output |
316 (string) |
339 is passed via this function. |
317 @return output and errors of the command server (string). In case |
340 @type func(str) |
|
341 @param error function receiving error messages from the server |
|
342 @type func(str) |
|
343 @return tuple of output and errors of the command server. In case |
318 output and/or error functions were given, the respective return |
344 output and/or error functions were given, the respective return |
319 value will be an empty string. |
345 value will be an empty string. |
|
346 @rtype tuple of (str, str) |
320 """ |
347 """ |
321 if not self.__started: |
348 if not self.__started: |
322 # try to start the Mercurial command server |
349 # try to start the Mercurial command server |
323 ok, startError = self.startServer() |
350 ok, startError = self.startServer() |
324 if not ok: |
351 if not ok: |
341 outputChannels["e"] = errorBuffer.write |
368 outputChannels["e"] = errorBuffer.write |
342 |
369 |
343 inputChannels = {} |
370 inputChannels = {} |
344 if prompt is not None: |
371 if prompt is not None: |
345 def func(size): |
372 def func(size): |
346 reply = prompt(size, outputBuffer.getvalue()) |
373 if outputBuffer is None: |
347 return reply, False |
374 msg = "" |
|
375 else: |
|
376 msg = outputBuffer.getvalue() |
|
377 reply, isPassword = prompt(size, msg) |
|
378 return reply, isPassword |
348 inputChannels["L"] = func |
379 inputChannels["L"] = func |
349 else: |
380 else: |
350 def myprompt(size): |
381 def myprompt(size): |
351 if outputBuffer is None: |
382 if outputBuffer is None: |
352 msg = self.tr("For message see output dialog.") |
383 msg = self.tr("For message see output dialog.") |
382 |
413 |
383 def wasCanceled(self): |
414 def wasCanceled(self): |
384 """ |
415 """ |
385 Public method to check, if the last command was canceled. |
416 Public method to check, if the last command was canceled. |
386 |
417 |
387 @return flag indicating the cancel state (boolean) |
418 @return flag indicating the cancel state |
|
419 @rtype bool |
388 """ |
420 """ |
389 return self.__cancel |
421 return self.__cancel |
390 |
422 |
391 def isExecuting(self): |
423 def isExecuting(self): |
392 """ |
424 """ |
393 Public method to check, if the server is executing a command. |
425 Public method to check, if the server is executing a command. |
394 |
426 |
395 @return flag indicating the execution of a command (boolean) |
427 @return flag indicating the execution of a command |
|
428 @rtype bool |
396 """ |
429 """ |
397 return self.__commandRunning |
430 return self.__commandRunning |
398 |
431 |
399 # |
432 # |
400 # eflag: noqa = M702 |
433 # eflag: noqa = M702 |