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

Side by Side Diff: gclient_utils.py

Issue 3126020: Remove code duplication and improve style. (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 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the
43 # executable, but shell=True makes subprocess on Linux fail when it's called
44 # with a list because it only tries to execute the first item in the list.
45 if not 'env' in kwargs:
46 # It's easier to parse the stdout if it is always in English.
47 kwargs['env'] = os.environ.copy()
48 kwargs['env']['LANGUAGE'] = 'en'
49 return subprocess.Popen(*args, shell=(sys.platform=='win32'), **kwargs)
50
51
42 def CheckCall(command, cwd=None, print_error=True): 52 def CheckCall(command, cwd=None, print_error=True):
43 """Like subprocess.check_call() but returns stdout. 53 """Similar subprocess.check_call() but redirects stdout and
54 returns (stdout, stderr).
44 55
45 Works on python 2.4 56 Works on python 2.4
46 """ 57 """
47 logging.debug('%s, cwd=%s' % (str(command), str(cwd))) 58 logging.debug('%s, cwd=%s' % (str(command), str(cwd)))
48 try: 59 try:
49 stderr = None 60 stderr = None
50 if not print_error: 61 if not print_error:
51 stderr = subprocess.PIPE 62 stderr = subprocess.PIPE
52 env = os.environ.copy() 63 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() 64 std_out, std_err = process.communicate()
60 except OSError, e: 65 except OSError, e:
61 raise CheckCallError(command, cwd, e.errno, None) 66 raise CheckCallError(command, cwd, e.errno, None)
62 if process.returncode: 67 if process.returncode:
63 raise CheckCallError(command, cwd, process.returncode, std_out, std_err) 68 raise CheckCallError(command, cwd, process.returncode, std_out, std_err)
64 return std_out, std_err 69 return std_out, std_err
65 70
66 71
67 def SplitUrlRevision(url): 72 def SplitUrlRevision(url):
68 """Splits url and returns a two-tuple: url, rev""" 73 """Splits url and returns a two-tuple: url, rev"""
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 trimmed. 273 trimmed.
269 274
270 If the command fails, as indicated by a nonzero exit status, gclient will 275 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 276 exit with an exit status of fail_status. If fail_status is None (the
272 default), gclient will raise an Error exception. 277 default), gclient will raise an Error exception.
273 """ 278 """
274 logging.debug(command) 279 logging.debug(command)
275 if print_messages: 280 if print_messages:
276 print('\n________ running \'%s\' in \'%s\'' 281 print('\n________ running \'%s\' in \'%s\''
277 % (' '.join(command), in_directory)) 282 % (' '.join(command), in_directory))
278 env = os.environ.copy()
279 env['LANGUAGE'] = 'en'
280 283
281 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the 284 kid = Popen(command, bufsize=0, cwd=in_directory,
282 # executable, but shell=True makes subprocess on Linux fail when it's called 285 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 286
288 # Do a flush of sys.stdout before we begin reading from the subprocess's 287 # Do a flush of sys.stdout before we begin reading from the subprocess's
289 # stdout. 288 # stdout.
290 last_flushed_at = time.time() 289 last_flushed_at = time.time()
291 sys.stdout.flush() 290 sys.stdout.flush()
292 291
293 # Also, we need to forward stdout to prevent weird re-ordering of output. 292 # 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: 293 # 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 294 # 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. 295 # 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: 315 if (time.time() - last_flushed_at) > 10:
317 last_flushed_at = time.time() 316 last_flushed_at = time.time()
318 sys.stdout.flush() 317 sys.stdout.flush()
319 in_byte = kid.stdout.read(1) 318 in_byte = kid.stdout.read(1)
320 rv = kid.wait() 319 rv = kid.wait()
321 320
322 if rv: 321 if rv:
323 msg = 'failed to run command: %s' % ' '.join(command) 322 msg = 'failed to run command: %s' % ' '.join(command)
324 323
325 if fail_status != None: 324 if fail_status != None:
326 print >>sys.stderr, msg 325 print >> sys.stderr, msg
327 sys.exit(fail_status) 326 sys.exit(fail_status)
328 327
329 raise Error(msg) 328 raise Error(msg)
330 329
331 330
332 def FindGclientRoot(from_dir, filename='.gclient'): 331 def FindGclientRoot(from_dir, filename='.gclient'):
333 """Tries to find the gclient root.""" 332 """Tries to find the gclient root."""
334 path = os.path.realpath(from_dir) 333 path = os.path.realpath(from_dir)
335 while not os.path.exists(os.path.join(path, filename)): 334 while not os.path.exists(os.path.join(path, filename)):
336 next = os.path.split(path) 335 split_path = os.path.split(path)
337 if not next[1]: 336 if not split_path[1]:
338 return None 337 return None
339 path = next[0] 338 path = split_path[0]
340 logging.info('Found gclient root at ' + path) 339 logging.info('Found gclient root at ' + path)
341 return path 340 return path
342 341
343 342
344 def PathDifference(root, subpath): 343 def PathDifference(root, subpath):
345 """Returns the difference subpath minus root.""" 344 """Returns the difference subpath minus root."""
346 root = os.path.realpath(root) 345 root = os.path.realpath(root)
347 subpath = os.path.realpath(subpath) 346 subpath = os.path.realpath(subpath)
348 if not subpath.startswith(root): 347 if not subpath.startswith(root):
349 return None 348 return None
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 if exception: 519 if exception:
521 self.parent.exceptions.append(exception) 520 self.parent.exceptions.append(exception)
522 if self.parent.progress: 521 if self.parent.progress:
523 self.parent.progress.update(1) 522 self.parent.progress.update(1)
524 assert not self.item.name in self.parent.ran 523 assert not self.item.name in self.parent.ran
525 if not self.item.name in self.parent.ran: 524 if not self.item.name in self.parent.ran:
526 self.parent.ran.append(self.item.name) 525 self.parent.ran.append(self.item.name)
527 finally: 526 finally:
528 self.parent.ready_cond.notifyAll() 527 self.parent.ready_cond.notifyAll()
529 self.parent.ready_cond.release() 528 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