OLD | NEW |
1 # Copyright 2009 Google Inc. All Rights Reserved. | 1 # Copyright 2009 Google Inc. All Rights Reserved. |
2 # | 2 # |
3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
4 # you may not use this file except in compliance with the License. | 4 # you may not use this file except in compliance with the License. |
5 # You may obtain a copy of the License at | 5 # You may obtain a copy of the License at |
6 # | 6 # |
7 # http://www.apache.org/licenses/LICENSE-2.0 | 7 # http://www.apache.org/licenses/LICENSE-2.0 |
8 # | 8 # |
9 # Unless required by applicable law or agreed to in writing, software | 9 # Unless required by applicable law or agreed to in writing, software |
10 # distributed under the License is distributed on an "AS IS" BASIS, | 10 # distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 description. | 259 description. |
260 """ | 260 """ |
261 # Call subprocess and capture nothing: | 261 # Call subprocess and capture nothing: |
262 SubprocessCallAndFilter(command, in_directory, True, True, fail_status) | 262 SubprocessCallAndFilter(command, in_directory, True, True, fail_status) |
263 | 263 |
264 | 264 |
265 def SubprocessCallAndFilter(command, | 265 def SubprocessCallAndFilter(command, |
266 in_directory, | 266 in_directory, |
267 print_messages, | 267 print_messages, |
268 print_stdout, | 268 print_stdout, |
269 fail_status=None, filter_fn=None): | 269 fail_status=None, |
| 270 filter_fn=None, |
| 271 stdout=None): |
270 """Runs command, a list, in directory in_directory. | 272 """Runs command, a list, in directory in_directory. |
271 | 273 |
272 If print_messages is true, a message indicating what is being done | 274 If print_messages is true, a message indicating what is being done |
273 is printed to stdout. If print_messages is false, the message is printed | 275 is printed to stdout. If print_messages is false, the message is printed |
274 only if we actually need to print something else as well, so you can | 276 only if we actually need to print something else as well, so you can |
275 get the context of the output. If print_messages is false and print_stdout | 277 get the context of the output. If print_messages is false and print_stdout |
276 is false, no output at all is generated. | 278 is false, no output at all is generated. |
277 | 279 |
278 Also, if print_stdout is true, the command's stdout is also forwarded | 280 Also, if print_stdout is true, the command's stdout is also forwarded |
279 to stdout. | 281 to stdout. |
280 | 282 |
281 If a filter_fn function is specified, it is expected to take a single | 283 If a filter_fn function is specified, it is expected to take a single |
282 string argument, and it will be called with each line of the | 284 string argument, and it will be called with each line of the |
283 subprocess's output. Each line has had the trailing newline character | 285 subprocess's output. Each line has had the trailing newline character |
284 trimmed. | 286 trimmed. |
285 | 287 |
286 If the command fails, as indicated by a nonzero exit status, gclient will | 288 If the command fails, as indicated by a nonzero exit status, gclient will |
287 exit with an exit status of fail_status. If fail_status is None (the | 289 exit with an exit status of fail_status. If fail_status is None (the |
288 default), gclient will raise an Error exception. | 290 default), gclient will raise an Error exception. |
289 """ | 291 """ |
| 292 stdout = stdout or sys.stdout |
290 logging.debug(command) | 293 logging.debug(command) |
291 if print_messages: | 294 if print_messages: |
292 print('\n________ running \'%s\' in \'%s\'' | 295 stdout.write('\n________ running \'%s\' in \'%s\'\n' |
293 % (' '.join(command), in_directory)) | 296 % (' '.join(command), in_directory)) |
294 | 297 |
295 kid = Popen(command, bufsize=0, cwd=in_directory, | 298 kid = Popen(command, bufsize=0, cwd=in_directory, |
296 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 299 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
297 | 300 |
298 # Do a flush of sys.stdout before we begin reading from the subprocess's | 301 # Do a flush of sys.stdout before we begin reading from the subprocess's |
299 # stdout. | 302 # stdout. |
300 last_flushed_at = time.time() | 303 last_flushed_at = time.time() |
301 sys.stdout.flush() | 304 stdout.flush() |
302 | 305 |
303 # Also, we need to forward stdout to prevent weird re-ordering of output. | 306 # Also, we need to forward stdout to prevent weird re-ordering of output. |
304 # This has to be done on a per byte basis to make sure it is not buffered: | 307 # This has to be done on a per byte basis to make sure it is not buffered: |
305 # normally buffering is done for each line, but if svn requests input, no | 308 # normally buffering is done for each line, but if svn requests input, no |
306 # end-of-line character is output after the prompt and it would not show up. | 309 # end-of-line character is output after the prompt and it would not show up. |
307 in_byte = kid.stdout.read(1) | 310 in_byte = kid.stdout.read(1) |
308 in_line = '' | 311 in_line = '' |
309 while in_byte: | 312 while in_byte: |
310 if in_byte != '\r': | 313 if in_byte != '\r': |
311 if print_stdout: | 314 if print_stdout: |
312 if not print_messages: | 315 if not print_messages: |
313 print('\n________ running \'%s\' in \'%s\'' | 316 stdout.write('\n________ running \'%s\' in \'%s\'\n' |
314 % (' '.join(command), in_directory)) | 317 % (' '.join(command), in_directory)) |
315 print_messages = True | 318 print_messages = True |
316 sys.stdout.write(in_byte) | 319 stdout.write(in_byte) |
317 if in_byte != '\n': | 320 if in_byte != '\n': |
318 in_line += in_byte | 321 in_line += in_byte |
319 if in_byte == '\n': | 322 if in_byte == '\n': |
320 if filter_fn: | 323 if filter_fn: |
321 filter_fn(in_line) | 324 filter_fn(in_line) |
322 in_line = '' | 325 in_line = '' |
323 # Flush at least 10 seconds between line writes. We wait at least 10 | 326 # Flush at least 10 seconds between line writes. We wait at least 10 |
324 # seconds to avoid overloading the reader that called us with output, | 327 # seconds to avoid overloading the reader that called us with output, |
325 # which can slow busy readers down. | 328 # which can slow busy readers down. |
326 if (time.time() - last_flushed_at) > 10: | 329 if (time.time() - last_flushed_at) > 10: |
327 last_flushed_at = time.time() | 330 last_flushed_at = time.time() |
328 sys.stdout.flush() | 331 stdout.flush() |
329 in_byte = kid.stdout.read(1) | 332 in_byte = kid.stdout.read(1) |
330 # Flush the rest of buffered output. This is only an issue with files not | 333 # Flush the rest of buffered output. This is only an issue with files not |
331 # ending with a \n. | 334 # ending with a \n. |
332 if len(in_line) and filter_fn: | 335 if len(in_line) and filter_fn: |
333 filter_fn(in_line) | 336 filter_fn(in_line) |
334 rv = kid.wait() | 337 rv = kid.wait() |
335 | 338 |
336 if rv: | 339 if rv: |
337 msg = 'failed to run command: %s' % ' '.join(command) | 340 msg = 'failed to run command: %s' % ' '.join(command) |
338 | |
339 if fail_status != None: | 341 if fail_status != None: |
340 print >> sys.stderr, msg | 342 sys.stderr.write(msg + '\n') |
341 sys.exit(fail_status) | 343 sys.exit(fail_status) |
342 | |
343 raise Error(msg) | 344 raise Error(msg) |
344 | 345 |
345 | 346 |
346 def FindGclientRoot(from_dir, filename='.gclient'): | 347 def FindGclientRoot(from_dir, filename='.gclient'): |
347 """Tries to find the gclient root.""" | 348 """Tries to find the gclient root.""" |
348 path = os.path.realpath(from_dir) | 349 path = os.path.realpath(from_dir) |
349 while not os.path.exists(os.path.join(path, filename)): | 350 while not os.path.exists(os.path.join(path, filename)): |
350 split_path = os.path.split(path) | 351 split_path = os.path.split(path) |
351 if not split_path[1]: | 352 if not split_path[1]: |
352 return None | 353 return None |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 if exception: | 535 if exception: |
535 self.parent.exceptions.append(exception) | 536 self.parent.exceptions.append(exception) |
536 if self.parent.progress: | 537 if self.parent.progress: |
537 self.parent.progress.update(1) | 538 self.parent.progress.update(1) |
538 assert not self.item.name in self.parent.ran | 539 assert not self.item.name in self.parent.ran |
539 if not self.item.name in self.parent.ran: | 540 if not self.item.name in self.parent.ran: |
540 self.parent.ran.append(self.item.name) | 541 self.parent.ran.append(self.item.name) |
541 finally: | 542 finally: |
542 self.parent.ready_cond.notifyAll() | 543 self.parent.ready_cond.notifyAll() |
543 self.parent.ready_cond.release() | 544 self.parent.ready_cond.release() |
OLD | NEW |