Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: gclient_utils.py

Issue 6689023: Revert r80216 "Reapply r79779: "Removed gclient_utils.Popen() and use subprocess2's ..."" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | subprocess2.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Generic utils.""" 5 """Generic utils."""
6 6
7 import errno 7 import errno
8 import logging 8 import logging
9 import os 9 import os
10 import Queue 10 import Queue
11 import re 11 import re
12 import stat 12 import stat
13 import subprocess 13 import subprocess
14 import sys 14 import sys
15 import threading 15 import threading
16 import time 16 import time
17 import xml.dom.minidom 17 import xml.dom.minidom
18 import xml.parsers.expat 18 import xml.parsers.expat
19 19
20 import subprocess2
21 20
22 # Keep an alias for now. 21 def hack_subprocess():
23 Popen = subprocess2.Popen 22 """subprocess functions may throw exceptions when used in multiple threads.
23
24 See http://bugs.python.org/issue1731717 for more information.
25 """
26 subprocess._cleanup = lambda: None
24 27
25 28
26 class Error(Exception): 29 class Error(Exception):
27 """gclient exception class.""" 30 """gclient exception class."""
28 pass 31 pass
29 32
30 33
31 class CheckCallError(OSError, Error): 34 class CheckCallError(OSError, Error):
32 """CheckCall() returned non-0.""" 35 """CheckCall() returned non-0."""
33 def __init__(self, command, cwd, returncode, stdout, stderr=None): 36 def __init__(self, command, cwd, returncode, stdout, stderr=None):
(...skipping 11 matching lines...) Expand all
45 out += ' in ' + self.cwd 48 out += ' in ' + self.cwd
46 if self.returncode is not None: 49 if self.returncode is not None:
47 out += ' returned %d' % self.returncode 50 out += ' returned %d' % self.returncode
48 if self.stdout is not None: 51 if self.stdout is not None:
49 out += '\nstdout: %s\n' % self.stdout 52 out += '\nstdout: %s\n' % self.stdout
50 if self.stderr is not None: 53 if self.stderr is not None:
51 out += '\nstderr: %s\n' % self.stderr 54 out += '\nstderr: %s\n' % self.stderr
52 return out 55 return out
53 56
54 57
58 def Popen(args, **kwargs):
59 """Calls subprocess.Popen() with hacks to work around certain behaviors.
60
61 Ensure English outpout for svn and make it work reliably on Windows.
62 """
63 logging.debug(u'%s, cwd=%s' % (u' '.join(args), kwargs.get('cwd', '')))
64 if not 'env' in kwargs:
65 # It's easier to parse the stdout if it is always in English.
66 kwargs['env'] = os.environ.copy()
67 kwargs['env']['LANGUAGE'] = 'en'
68 if not 'shell' in kwargs:
69 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the
70 # executable, but shell=True makes subprocess on Linux fail when it's called
71 # with a list because it only tries to execute the first item in the list.
72 kwargs['shell'] = (sys.platform=='win32')
73 try:
74 return subprocess.Popen(args, **kwargs)
75 except OSError, e:
76 if e.errno == errno.EAGAIN and sys.platform == 'cygwin':
77 raise Error(
78 'Visit '
79 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to '
80 'learn how to fix this error; you need to rebase your cygwin dlls')
81 raise
82
83
55 def CheckCall(command, print_error=True, **kwargs): 84 def CheckCall(command, print_error=True, **kwargs):
56 """Similar subprocess.check_call() but redirects stdout and 85 """Similar subprocess.check_call() but redirects stdout and
57 returns (stdout, stderr). 86 returns (stdout, stderr).
58 87
59 Works on python 2.4 88 Works on python 2.4
60 """ 89 """
61 try: 90 try:
62 stderr = None 91 stderr = None
63 if not print_error: 92 if not print_error:
64 stderr = subprocess.PIPE 93 stderr = subprocess.PIPE
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 559
531 In gclient's case, Dependencies sometime needs to be run out of order due to 560 In gclient's case, Dependencies sometime needs to be run out of order due to
532 From() keyword. This class manages that all the required dependencies are run 561 From() keyword. This class manages that all the required dependencies are run
533 before running each one. 562 before running each one.
534 563
535 Methods of this class are thread safe. 564 Methods of this class are thread safe.
536 """ 565 """
537 def __init__(self, jobs, progress): 566 def __init__(self, jobs, progress):
538 """jobs specifies the number of concurrent tasks to allow. progress is a 567 """jobs specifies the number of concurrent tasks to allow. progress is a
539 Progress instance.""" 568 Progress instance."""
569 hack_subprocess()
540 # Set when a thread is done or a new item is enqueued. 570 # Set when a thread is done or a new item is enqueued.
541 self.ready_cond = threading.Condition() 571 self.ready_cond = threading.Condition()
542 # Maximum number of concurrent tasks. 572 # Maximum number of concurrent tasks.
543 self.jobs = jobs 573 self.jobs = jobs
544 # List of WorkItem, for gclient, these are Dependency instances. 574 # List of WorkItem, for gclient, these are Dependency instances.
545 self.queued = [] 575 self.queued = []
546 # List of strings representing each Dependency.name that was run. 576 # List of strings representing each Dependency.name that was run.
547 self.ran = [] 577 self.ran = []
548 # List of items currently running. 578 # List of items currently running.
549 self.running = [] 579 self.running = []
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 logging.info('Caught exception in thread %s' % self.item.name) 703 logging.info('Caught exception in thread %s' % self.item.name)
674 logging.info(str(sys.exc_info())) 704 logging.info(str(sys.exc_info()))
675 work_queue.exceptions.put(sys.exc_info()) 705 work_queue.exceptions.put(sys.exc_info())
676 logging.info('Task %s done' % self.item.name) 706 logging.info('Task %s done' % self.item.name)
677 707
678 work_queue.ready_cond.acquire() 708 work_queue.ready_cond.acquire()
679 try: 709 try:
680 work_queue.ready_cond.notifyAll() 710 work_queue.ready_cond.notifyAll()
681 finally: 711 finally:
682 work_queue.ready_cond.release() 712 work_queue.ready_cond.release()
OLDNEW
« no previous file with comments | « no previous file | subprocess2.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698