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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 try: | 244 try: |
245 os.rmdir(file_path) | 245 os.rmdir(file_path) |
246 except OSError, e: | 246 except OSError, e: |
247 if e.errno != errno.EACCES or sys.platform != 'win32': | 247 if e.errno != errno.EACCES or sys.platform != 'win32': |
248 raise | 248 raise |
249 print 'Failed to remove %s: trying again' % file_path | 249 print 'Failed to remove %s: trying again' % file_path |
250 time.sleep(0.1) | 250 time.sleep(0.1) |
251 os.rmdir(file_path) | 251 os.rmdir(file_path) |
252 | 252 |
253 | 253 |
254 def SubprocessCall(command, in_directory, fail_status=None): | 254 def SubprocessCall(args, **kwargs): |
255 """Runs command, a list, in directory in_directory. | 255 """Wraps SubprocessCallAndFilter() with different default arguments. |
256 | 256 |
257 This function wraps SubprocessCallAndFilter, but does not perform the | 257 Calls subprocess and capture nothing.""" |
258 filtering functions. See that function for a more complete usage | 258 kwargs['print_messages'] = True |
259 description. | 259 kwargs['print_stdout'] = True |
260 """ | 260 return SubprocessCallAndFilter(args, **kwargs) |
261 # Call subprocess and capture nothing: | |
262 SubprocessCallAndFilter(command, in_directory, True, True, fail_status) | |
263 | 261 |
264 | 262 |
265 def SubprocessCallAndFilter(command, | 263 def SubprocessCallAndFilter(args, **kwargs): |
266 in_directory, | 264 """Runs a command and prints a header line if appropriate. |
267 print_messages, | |
268 print_stdout, | |
269 fail_status=None, | |
270 filter_fn=None, | |
271 stdout=None): | |
272 """Runs command, a list, in directory in_directory. | |
273 | 265 |
274 If print_messages is true, a message indicating what is being done | 266 If |print_messages| is True, a message indicating what is being done |
275 is printed to stdout. If print_messages is false, the message is printed | 267 is printed to stdout. Otherwise the message is printed only if the call |
276 only if we actually need to print something else as well, so you can | 268 generated any ouput. If both |print_messages| and |print_stdout| are False, |
277 get the context of the output. If print_messages is false and print_stdout | 269 no output at all is generated. |
278 is false, no output at all is generated. | |
279 | 270 |
280 Also, if print_stdout is true, the command's stdout is also forwarded | 271 If |print_stdout| is True, the command's stdout is also forwarded to stdout. |
281 to stdout. | |
282 | 272 |
283 If a filter_fn function is specified, it is expected to take a single | 273 If |filter_fn| function is specified, it is expected to take a single |
284 string argument, and it will be called with each line of the | 274 string argument, and it will be called with each line of the |
285 subprocess's output. Each line has had the trailing newline character | 275 subprocess's output. Each line has had the trailing newline character |
286 trimmed. | 276 trimmed. |
287 | 277 |
288 If the command fails, as indicated by a nonzero exit status, gclient will | 278 If the command fails, as indicated by a nonzero exit status, gclient will |
289 exit with an exit status of fail_status. If fail_status is None (the | 279 exit with an exit status of fail_status. If fail_status is None (the |
290 default), gclient will raise an Error exception. | 280 default), gclient will raise an Error exception. |
| 281 |
| 282 Other subprocess.Popen parameters can be specified. |
291 """ | 283 """ |
292 stdout = stdout or sys.stdout | 284 stdout = kwargs.pop('stdout', sys.stdout) or sys.stdout |
293 logging.debug(command) | 285 assert not 'stderr' in kwargs |
| 286 filter_fn = kwargs.pop('filter_fn', None) |
| 287 print_messages = kwargs.pop('print_messages', False) |
| 288 print_stdout = kwargs.pop('print_stdout', False) |
| 289 fail_status = kwargs.pop('fail_status', None) |
| 290 |
| 291 logging.debug(args) |
294 if print_messages: | 292 if print_messages: |
295 stdout.write('\n________ running \'%s\' in \'%s\'\n' | 293 stdout.write('\n________ running \'%s\' in \'%s\'\n' |
296 % (' '.join(command), in_directory)) | 294 % (' '.join(args), kwargs['cwd'])) |
297 | 295 |
298 kid = Popen(command, bufsize=0, cwd=in_directory, | 296 kid = Popen(args, bufsize=0, |
299 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 297 stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
| 298 **kwargs) |
300 | 299 |
301 # Do a flush of sys.stdout before we begin reading from the subprocess's | 300 # Do a flush of sys.stdout before we begin reading from the subprocess's |
302 # stdout. | 301 # stdout. |
303 last_flushed_at = time.time() | 302 last_flushed_at = time.time() |
304 stdout.flush() | 303 stdout.flush() |
305 | 304 |
306 # Also, we need to forward stdout to prevent weird re-ordering of output. | 305 # Also, we need to forward stdout to prevent weird re-ordering of output. |
307 # This has to be done on a per byte basis to make sure it is not buffered: | 306 # This has to be done on a per byte basis to make sure it is not buffered: |
308 # normally buffering is done for each line, but if svn requests input, no | 307 # normally buffering is done for each line, but if svn requests input, no |
309 # end-of-line character is output after the prompt and it would not show up. | 308 # end-of-line character is output after the prompt and it would not show up. |
310 in_byte = kid.stdout.read(1) | 309 in_byte = kid.stdout.read(1) |
311 in_line = '' | 310 in_line = '' |
312 while in_byte: | 311 while in_byte: |
313 if in_byte != '\r': | 312 if in_byte != '\r': |
314 if print_stdout: | 313 if print_stdout: |
315 if not print_messages: | 314 if not print_messages: |
316 stdout.write('\n________ running \'%s\' in \'%s\'\n' | 315 stdout.write('\n________ running \'%s\' in \'%s\'\n' |
317 % (' '.join(command), in_directory)) | 316 % (' '.join(args), kwargs['cwd'])) |
318 print_messages = True | 317 print_messages = True |
319 stdout.write(in_byte) | 318 stdout.write(in_byte) |
320 if in_byte != '\n': | 319 if in_byte != '\n': |
321 in_line += in_byte | 320 in_line += in_byte |
322 if in_byte == '\n': | 321 if in_byte == '\n': |
323 if filter_fn: | 322 if filter_fn: |
324 filter_fn(in_line) | 323 filter_fn(in_line) |
325 in_line = '' | 324 in_line = '' |
326 # Flush at least 10 seconds between line writes. We wait at least 10 | 325 # Flush at least 10 seconds between line writes. We wait at least 10 |
327 # seconds to avoid overloading the reader that called us with output, | 326 # seconds to avoid overloading the reader that called us with output, |
328 # which can slow busy readers down. | 327 # which can slow busy readers down. |
329 if (time.time() - last_flushed_at) > 10: | 328 if (time.time() - last_flushed_at) > 10: |
330 last_flushed_at = time.time() | 329 last_flushed_at = time.time() |
331 stdout.flush() | 330 stdout.flush() |
332 in_byte = kid.stdout.read(1) | 331 in_byte = kid.stdout.read(1) |
333 # Flush the rest of buffered output. This is only an issue with files not | 332 # Flush the rest of buffered output. This is only an issue with files not |
334 # ending with a \n. | 333 # ending with a \n. |
335 if len(in_line) and filter_fn: | 334 if len(in_line) and filter_fn: |
336 filter_fn(in_line) | 335 filter_fn(in_line) |
337 rv = kid.wait() | 336 rv = kid.wait() |
338 | 337 |
339 if rv: | 338 if rv: |
340 msg = 'failed to run command: %s' % ' '.join(command) | 339 msg = 'failed to run command: %s' % ' '.join(args) |
341 if fail_status != None: | 340 if fail_status != None: |
342 sys.stderr.write(msg + '\n') | 341 sys.stderr.write(msg + '\n') |
343 sys.exit(fail_status) | 342 sys.exit(fail_status) |
344 raise Error(msg) | 343 raise Error(msg) |
345 | 344 |
346 | 345 |
347 def FindGclientRoot(from_dir, filename='.gclient'): | 346 def FindGclientRoot(from_dir, filename='.gclient'): |
348 """Tries to find the gclient root.""" | 347 """Tries to find the gclient root.""" |
349 path = os.path.realpath(from_dir) | 348 path = os.path.realpath(from_dir) |
350 while not os.path.exists(os.path.join(path, filename)): | 349 while not os.path.exists(os.path.join(path, filename)): |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 if exception: | 534 if exception: |
536 self.parent.exceptions.append(exception) | 535 self.parent.exceptions.append(exception) |
537 if self.parent.progress: | 536 if self.parent.progress: |
538 self.parent.progress.update(1) | 537 self.parent.progress.update(1) |
539 assert not self.item.name in self.parent.ran | 538 assert not self.item.name in self.parent.ran |
540 if not self.item.name in self.parent.ran: | 539 if not self.item.name in self.parent.ran: |
541 self.parent.ran.append(self.item.name) | 540 self.parent.ran.append(self.item.name) |
542 finally: | 541 finally: |
543 self.parent.ready_cond.notifyAll() | 542 self.parent.ready_cond.notifyAll() |
544 self.parent.ready_cond.release() | 543 self.parent.ready_cond.release() |
OLD | NEW |