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

Side by Side Diff: gclient_utils.py

Issue 3199011: Redo of r56893 with fix to support python 2.5. (Closed)
Patch Set: Created 10 years, 4 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
« no previous file with comments | « gclient_scm.py ('k') | scm.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 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,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 12 # See the License for the specific language governing permissions and
13 # limitations under the License. 13 # limitations under the License.
14 14
15 """Generic utils.""" 15 """Generic utils."""
16 16
17 import errno 17 import errno
18 import logging 18 import logging
19 import os 19 import os
20 import re 20 import re
21 import stat 21 import stat
22 import subprocess 22 import subprocess
23 import sys 23 import sys
24 import threading 24 import threading
25 import time 25 import time
26 import threading
27 import xml.dom.minidom 26 import xml.dom.minidom
28 import xml.parsers.expat 27 import xml.parsers.expat
29 28
30 29
31 class CheckCallError(OSError): 30 class CheckCallError(OSError):
32 """CheckCall() returned non-0.""" 31 """CheckCall() returned non-0."""
33 def __init__(self, command, cwd, retcode, stdout, stderr=None): 32 def __init__(self, command, cwd, retcode, stdout, stderr=None):
34 OSError.__init__(self, command, cwd, retcode, stdout, stderr) 33 OSError.__init__(self, command, cwd, retcode, stdout, stderr)
35 self.command = command 34 self.command = command
36 self.cwd = cwd 35 self.cwd = cwd
37 self.retcode = retcode 36 self.retcode = retcode
38 self.stdout = stdout 37 self.stdout = stdout
39 self.stderr = stderr 38 self.stderr = stderr
40 39
41 40
41 def Popen(*args, **kwargs):
42 """Calls subprocess.Popen() with hacks to work around certain behaviors.
43
44 Ensure English outpout for svn and make it work reliably on Windows.
45 """
46 copied = False
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.
51 kwargs['env'] = os.environ.copy()
52 kwargs['env']['LANGUAGE'] = 'en'
53 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
57 # 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.
59 kwargs['shell'] = (sys.platform=='win32')
60 return subprocess.Popen(*args, **kwargs)
61
62
42 def CheckCall(command, cwd=None, print_error=True): 63 def CheckCall(command, cwd=None, print_error=True):
43 """Like subprocess.check_call() but returns stdout. 64 """Similar subprocess.check_call() but redirects stdout and
65 returns (stdout, stderr).
44 66
45 Works on python 2.4 67 Works on python 2.4
46 """ 68 """
47 logging.debug('%s, cwd=%s' % (str(command), str(cwd))) 69 logging.debug('%s, cwd=%s' % (str(command), str(cwd)))
48 try: 70 try:
49 stderr = None 71 stderr = None
50 if not print_error: 72 if not print_error:
51 stderr = subprocess.PIPE 73 stderr = subprocess.PIPE
52 env = os.environ.copy() 74 process = Popen(command, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr)
53 env['LANGUAGE'] = 'en'
54 process = subprocess.Popen(command, cwd=cwd,
55 shell=sys.platform.startswith('win'),
56 stdout=subprocess.PIPE,
57 stderr=stderr,
58 env=env)
59 std_out, std_err = process.communicate() 75 std_out, std_err = process.communicate()
60 except OSError, e: 76 except OSError, e:
61 raise CheckCallError(command, cwd, e.errno, None) 77 raise CheckCallError(command, cwd, e.errno, None)
62 if process.returncode: 78 if process.returncode:
63 raise CheckCallError(command, cwd, process.returncode, std_out, std_err) 79 raise CheckCallError(command, cwd, process.returncode, std_out, std_err)
64 return std_out, std_err 80 return std_out, std_err
65 81
66 82
67 def SplitUrlRevision(url): 83 def SplitUrlRevision(url):
68 """Splits url and returns a two-tuple: url, rev""" 84 """Splits url and returns a two-tuple: url, rev"""
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 trimmed. 284 trimmed.
269 285
270 If the command fails, as indicated by a nonzero exit status, gclient will 286 If the command fails, as indicated by a nonzero exit status, gclient will
271 exit with an exit status of fail_status. If fail_status is None (the 287 exit with an exit status of fail_status. If fail_status is None (the
272 default), gclient will raise an Error exception. 288 default), gclient will raise an Error exception.
273 """ 289 """
274 logging.debug(command) 290 logging.debug(command)
275 if print_messages: 291 if print_messages:
276 print('\n________ running \'%s\' in \'%s\'' 292 print('\n________ running \'%s\' in \'%s\''
277 % (' '.join(command), in_directory)) 293 % (' '.join(command), in_directory))
278 env = os.environ.copy()
279 env['LANGUAGE'] = 'en'
280 294
281 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the 295 kid = Popen(command, bufsize=0, cwd=in_directory,
282 # executable, but shell=True makes subprocess on Linux fail when it's called 296 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
283 # with a list because it only tries to execute the first item in the list.
284 kid = subprocess.Popen(command, bufsize=0, cwd=in_directory,
285 shell=(sys.platform == 'win32'), stdout=subprocess.PIPE,
286 stderr=subprocess.STDOUT, env=env)
287 297
288 # Do a flush of sys.stdout before we begin reading from the subprocess's 298 # Do a flush of sys.stdout before we begin reading from the subprocess's
289 # stdout. 299 # stdout.
290 last_flushed_at = time.time() 300 last_flushed_at = time.time()
291 sys.stdout.flush() 301 sys.stdout.flush()
292 302
293 # Also, we need to forward stdout to prevent weird re-ordering of output. 303 # Also, we need to forward stdout to prevent weird re-ordering of output.
294 # This has to be done on a per byte basis to make sure it is not buffered: 304 # This has to be done on a per byte basis to make sure it is not buffered:
295 # normally buffering is done for each line, but if svn requests input, no 305 # normally buffering is done for each line, but if svn requests input, no
296 # end-of-line character is output after the prompt and it would not show up. 306 # end-of-line character is output after the prompt and it would not show up.
(...skipping 19 matching lines...) Expand all
316 if (time.time() - last_flushed_at) > 10: 326 if (time.time() - last_flushed_at) > 10:
317 last_flushed_at = time.time() 327 last_flushed_at = time.time()
318 sys.stdout.flush() 328 sys.stdout.flush()
319 in_byte = kid.stdout.read(1) 329 in_byte = kid.stdout.read(1)
320 rv = kid.wait() 330 rv = kid.wait()
321 331
322 if rv: 332 if rv:
323 msg = 'failed to run command: %s' % ' '.join(command) 333 msg = 'failed to run command: %s' % ' '.join(command)
324 334
325 if fail_status != None: 335 if fail_status != None:
326 print >>sys.stderr, msg 336 print >> sys.stderr, msg
327 sys.exit(fail_status) 337 sys.exit(fail_status)
328 338
329 raise Error(msg) 339 raise Error(msg)
330 340
331 341
332 def FindGclientRoot(from_dir, filename='.gclient'): 342 def FindGclientRoot(from_dir, filename='.gclient'):
333 """Tries to find the gclient root.""" 343 """Tries to find the gclient root."""
334 path = os.path.realpath(from_dir) 344 path = os.path.realpath(from_dir)
335 while not os.path.exists(os.path.join(path, filename)): 345 while not os.path.exists(os.path.join(path, filename)):
336 next = os.path.split(path) 346 split_path = os.path.split(path)
337 if not next[1]: 347 if not split_path[1]:
338 return None 348 return None
339 path = next[0] 349 path = split_path[0]
340 logging.info('Found gclient root at ' + path) 350 logging.info('Found gclient root at ' + path)
341 return path 351 return path
342 352
343 353
344 def PathDifference(root, subpath): 354 def PathDifference(root, subpath):
345 """Returns the difference subpath minus root.""" 355 """Returns the difference subpath minus root."""
346 root = os.path.realpath(root) 356 root = os.path.realpath(root)
347 subpath = os.path.realpath(subpath) 357 subpath = os.path.realpath(subpath)
348 if not subpath.startswith(root): 358 if not subpath.startswith(root):
349 return None 359 return None
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 if exception: 530 if exception:
521 self.parent.exceptions.append(exception) 531 self.parent.exceptions.append(exception)
522 if self.parent.progress: 532 if self.parent.progress:
523 self.parent.progress.update(1) 533 self.parent.progress.update(1)
524 assert not self.item.name in self.parent.ran 534 assert not self.item.name in self.parent.ran
525 if not self.item.name in self.parent.ran: 535 if not self.item.name in self.parent.ran:
526 self.parent.ran.append(self.item.name) 536 self.parent.ran.append(self.item.name)
527 finally: 537 finally:
528 self.parent.ready_cond.notifyAll() 538 self.parent.ready_cond.notifyAll()
529 self.parent.ready_cond.release() 539 self.parent.ready_cond.release()
OLDNEW
« no previous file with comments | « gclient_scm.py ('k') | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698