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

Side by Side Diff: gclient_utils.py

Issue 6770028: Removed gclient_utils.Popen() and use subprocess2's version instead. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: updated test 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
20 21
21 def hack_subprocess(): 22 # Keep an alias for now.
22 """subprocess functions may throw exceptions when used in multiple threads. 23 Popen = subprocess2.Popen
23
24 See http://bugs.python.org/issue1731717 for more information.
25 """
26 subprocess._cleanup = lambda: None
27 24
28 25
29 class Error(Exception): 26 class Error(Exception):
30 """gclient exception class.""" 27 """gclient exception class."""
31 pass 28 pass
32 29
33 30
34 class CheckCallError(OSError, Error): 31 class CheckCallError(OSError, Error):
35 """CheckCall() returned non-0.""" 32 """CheckCall() returned non-0."""
36 def __init__(self, command, cwd, returncode, stdout, stderr=None): 33 def __init__(self, command, cwd, returncode, stdout, stderr=None):
(...skipping 11 matching lines...) Expand all
48 out += ' in ' + self.cwd 45 out += ' in ' + self.cwd
49 if self.returncode is not None: 46 if self.returncode is not None:
50 out += ' returned %d' % self.returncode 47 out += ' returned %d' % self.returncode
51 if self.stdout is not None: 48 if self.stdout is not None:
52 out += '\nstdout: %s\n' % self.stdout 49 out += '\nstdout: %s\n' % self.stdout
53 if self.stderr is not None: 50 if self.stderr is not None:
54 out += '\nstderr: %s\n' % self.stderr 51 out += '\nstderr: %s\n' % self.stderr
55 return out 52 return out
56 53
57 54
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
84 def CheckCall(command, print_error=True, **kwargs): 55 def CheckCall(command, print_error=True, **kwargs):
85 """Similar subprocess.check_call() but redirects stdout and 56 """Similar subprocess.check_call() but redirects stdout and
86 returns (stdout, stderr). 57 returns (stdout, stderr).
87 58
88 Works on python 2.4 59 Works on python 2.4
89 """ 60 """
90 try: 61 try:
91 stderr = None 62 stderr = None
92 if not print_error: 63 if not print_error:
93 stderr = subprocess.PIPE 64 stderr = subprocess.PIPE
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 530
560 In gclient's case, Dependencies sometime needs to be run out of order due to 531 In gclient's case, Dependencies sometime needs to be run out of order due to
561 From() keyword. This class manages that all the required dependencies are run 532 From() keyword. This class manages that all the required dependencies are run
562 before running each one. 533 before running each one.
563 534
564 Methods of this class are thread safe. 535 Methods of this class are thread safe.
565 """ 536 """
566 def __init__(self, jobs, progress): 537 def __init__(self, jobs, progress):
567 """jobs specifies the number of concurrent tasks to allow. progress is a 538 """jobs specifies the number of concurrent tasks to allow. progress is a
568 Progress instance.""" 539 Progress instance."""
569 hack_subprocess()
570 # Set when a thread is done or a new item is enqueued. 540 # Set when a thread is done or a new item is enqueued.
571 self.ready_cond = threading.Condition() 541 self.ready_cond = threading.Condition()
572 # Maximum number of concurrent tasks. 542 # Maximum number of concurrent tasks.
573 self.jobs = jobs 543 self.jobs = jobs
574 # List of WorkItem, for gclient, these are Dependency instances. 544 # List of WorkItem, for gclient, these are Dependency instances.
575 self.queued = [] 545 self.queued = []
576 # List of strings representing each Dependency.name that was run. 546 # List of strings representing each Dependency.name that was run.
577 self.ran = [] 547 self.ran = []
578 # List of items currently running. 548 # List of items currently running.
579 self.running = [] 549 self.running = []
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 logging.info('Caught exception in thread %s' % self.item.name) 673 logging.info('Caught exception in thread %s' % self.item.name)
704 logging.info(str(sys.exc_info())) 674 logging.info(str(sys.exc_info()))
705 work_queue.exceptions.put(sys.exc_info()) 675 work_queue.exceptions.put(sys.exc_info())
706 logging.info('Task %s done' % self.item.name) 676 logging.info('Task %s done' % self.item.name)
707 677
708 work_queue.ready_cond.acquire() 678 work_queue.ready_cond.acquire()
709 try: 679 try:
710 work_queue.ready_cond.notifyAll() 680 work_queue.ready_cond.notifyAll()
711 finally: 681 finally:
712 work_queue.ready_cond.release() 682 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