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 20 matching lines...) Expand all Loading... |
31 """CheckCall() returned non-0.""" | 31 """CheckCall() returned non-0.""" |
32 def __init__(self, command, cwd, retcode, stdout, stderr=None): | 32 def __init__(self, command, cwd, retcode, stdout, stderr=None): |
33 OSError.__init__(self, command, cwd, retcode, stdout, stderr) | 33 OSError.__init__(self, command, cwd, retcode, stdout, stderr) |
34 self.command = command | 34 self.command = command |
35 self.cwd = cwd | 35 self.cwd = cwd |
36 self.retcode = retcode | 36 self.retcode = retcode |
37 self.stdout = stdout | 37 self.stdout = stdout |
38 self.stderr = stderr | 38 self.stderr = stderr |
39 | 39 |
40 | 40 |
41 def Popen(*args, **kwargs): | 41 def Popen(args, **kwargs): |
42 """Calls subprocess.Popen() with hacks to work around certain behaviors. | 42 """Calls subprocess.Popen() with hacks to work around certain behaviors. |
43 | 43 |
44 Ensure English outpout for svn and make it work reliably on Windows. | 44 Ensure English outpout for svn and make it work reliably on Windows. |
45 """ | 45 """ |
46 copied = False | 46 logging.debug(u'%s, cwd=%s' % (u' '.join(args), kwargs.get('cwd', ''))) |
47 if not 'env' in kwargs: | 47 if not 'env' in kwargs: |
48 copied = True | |
49 kwargs = kwargs.copy() | |
50 # It's easier to parse the stdout if it is always in English. | 48 # It's easier to parse the stdout if it is always in English. |
51 kwargs['env'] = os.environ.copy() | 49 kwargs['env'] = os.environ.copy() |
52 kwargs['env']['LANGUAGE'] = 'en' | 50 kwargs['env']['LANGUAGE'] = 'en' |
53 if not 'shell' in kwargs: | 51 if not 'shell' in kwargs: |
54 if not copied: | |
55 kwargs = kwargs.copy() | |
56 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the | 52 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the |
57 # executable, but shell=True makes subprocess on Linux fail when it's called | 53 # executable, but shell=True makes subprocess on Linux fail when it's called |
58 # with a list because it only tries to execute the first item in the list. | 54 # with a list because it only tries to execute the first item in the list. |
59 kwargs['shell'] = (sys.platform=='win32') | 55 kwargs['shell'] = (sys.platform=='win32') |
60 return subprocess.Popen(*args, **kwargs) | 56 return subprocess.Popen(args, **kwargs) |
61 | 57 |
62 | 58 |
63 def CheckCall(command, cwd=None, print_error=True): | 59 def CheckCall(command, cwd=None, print_error=True): |
64 """Similar subprocess.check_call() but redirects stdout and | 60 """Similar subprocess.check_call() but redirects stdout and |
65 returns (stdout, stderr). | 61 returns (stdout, stderr). |
66 | 62 |
67 Works on python 2.4 | 63 Works on python 2.4 |
68 """ | 64 """ |
69 logging.debug('%s, cwd=%s' % (str(command), str(cwd))) | |
70 try: | 65 try: |
71 stderr = None | 66 stderr = None |
72 if not print_error: | 67 if not print_error: |
73 stderr = subprocess.PIPE | 68 stderr = subprocess.PIPE |
74 process = Popen(command, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr) | 69 process = Popen(command, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr) |
75 std_out, std_err = process.communicate() | 70 std_out, std_err = process.communicate() |
76 except OSError, e: | 71 except OSError, e: |
77 raise CheckCallError(command, cwd, e.errno, None) | 72 raise CheckCallError(command, cwd, e.errno, None) |
78 if process.returncode: | 73 if process.returncode: |
79 raise CheckCallError(command, cwd, process.returncode, std_out, std_err) | 74 raise CheckCallError(command, cwd, process.returncode, std_out, std_err) |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 of the subprocess's output. Each line has the trailing newline | 284 of the subprocess's output. Each line has the trailing newline |
290 character trimmed. | 285 character trimmed. |
291 stdout: Can be any bufferable output. | 286 stdout: Can be any bufferable output. |
292 | 287 |
293 stderr is always redirected to stdout. | 288 stderr is always redirected to stdout. |
294 """ | 289 """ |
295 assert print_stdout or filter_fn | 290 assert print_stdout or filter_fn |
296 stdout = stdout or sys.stdout | 291 stdout = stdout or sys.stdout |
297 filter_fn = filter_fn or (lambda x: None) | 292 filter_fn = filter_fn or (lambda x: None) |
298 assert not 'stderr' in kwargs | 293 assert not 'stderr' in kwargs |
299 logging.debug(args) | |
300 kid = Popen(args, bufsize=0, | 294 kid = Popen(args, bufsize=0, |
301 stdout=subprocess.PIPE, stderr=subprocess.STDOUT, | 295 stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
302 **kwargs) | 296 **kwargs) |
303 | 297 |
304 # Do a flush of stdout before we begin reading from the subprocess's stdout | 298 # Do a flush of stdout before we begin reading from the subprocess's stdout |
305 last_flushed_at = time.time() | 299 last_flushed_at = time.time() |
306 stdout.flush() | 300 stdout.flush() |
307 | 301 |
308 # Also, we need to forward stdout to prevent weird re-ordering of output. | 302 # Also, we need to forward stdout to prevent weird re-ordering of output. |
309 # This has to be done on a per byte basis to make sure it is not buffered: | 303 # This has to be done on a per byte basis to make sure it is not buffered: |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 if exception: | 525 if exception: |
532 self.parent.exceptions.append(exception) | 526 self.parent.exceptions.append(exception) |
533 if self.parent.progress: | 527 if self.parent.progress: |
534 self.parent.progress.update(1) | 528 self.parent.progress.update(1) |
535 assert not self.item.name in self.parent.ran | 529 assert not self.item.name in self.parent.ran |
536 if not self.item.name in self.parent.ran: | 530 if not self.item.name in self.parent.ran: |
537 self.parent.ran.append(self.item.name) | 531 self.parent.ran.append(self.item.name) |
538 finally: | 532 finally: |
539 self.parent.ready_cond.notifyAll() | 533 self.parent.ready_cond.notifyAll() |
540 self.parent.ready_cond.release() | 534 self.parent.ready_cond.release() |
OLD | NEW |