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

Side by Side Diff: gclient_utils.py

Issue 517005: After much refactory, finally add significant functionalities to trychanges.py (Closed)
Patch Set: Created 11 years 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 | « gcl.py ('k') | tests/trychange_unittest.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 os 19 import os
19 import re 20 import re
20 import stat 21 import stat
21 import subprocess 22 import subprocess
22 import sys 23 import sys
23 import time 24 import time
24 import xml.dom.minidom 25 import xml.dom.minidom
25 import xml.parsers.expat 26 import xml.parsers.expat
26 27
27 28
28 class CheckCallError(OSError): 29 class CheckCallError(OSError):
29 """CheckCall() returned non-0.""" 30 """CheckCall() returned non-0."""
30 def __init__(self, command, cwd, retcode, stdout): 31 def __init__(self, command, cwd, retcode, stdout):
31 OSError.__init__(self, command, cwd, retcode, stdout) 32 OSError.__init__(self, command, cwd, retcode, stdout)
32 self.command = command 33 self.command = command
33 self.cwd = cwd 34 self.cwd = cwd
34 self.retcode = retcode 35 self.retcode = retcode
35 self.stdout = stdout 36 self.stdout = stdout
36 37
37 38
38 def CheckCall(command, cwd=None, print_error=True): 39 def CheckCall(command, cwd=None, print_error=True):
39 """Like subprocess.check_call() but returns stdout. 40 """Like subprocess.check_call() but returns stdout.
40 41
41 Works on python 2.4 42 Works on python 2.4
42 """ 43 """
44 logging.debug(command)
bradn 2009/12/23 17:30:25 Did you want to make this more verbose? running 'b
43 try: 45 try:
44 stderr = None 46 stderr = None
45 if not print_error: 47 if not print_error:
46 stderr = subprocess.PIPE 48 stderr = subprocess.PIPE
47 process = subprocess.Popen(command, cwd=cwd, 49 process = subprocess.Popen(command, cwd=cwd,
48 shell=sys.platform.startswith('win'), 50 shell=sys.platform.startswith('win'),
49 stdout=subprocess.PIPE, 51 stdout=subprocess.PIPE,
50 stderr=stderr) 52 stderr=stderr)
51 output = process.communicate()[0] 53 output = process.communicate()[0]
52 except OSError, e: 54 except OSError, e:
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 On POSIX systems, things are a little bit simpler. The modes of the files 157 On POSIX systems, things are a little bit simpler. The modes of the files
156 to be deleted doesn't matter, only the modes of the directories containing 158 to be deleted doesn't matter, only the modes of the directories containing
157 them are significant. As the directory tree is traversed, each directory 159 them are significant. As the directory tree is traversed, each directory
158 has its mode set appropriately before descending into it. This should 160 has its mode set appropriately before descending into it. This should
159 result in the entire tree being removed, with the possible exception of 161 result in the entire tree being removed, with the possible exception of
160 *path itself, because nothing attempts to change the mode of its parent. 162 *path itself, because nothing attempts to change the mode of its parent.
161 Doing so would be hazardous, as it's not a directory slated for removal. 163 Doing so would be hazardous, as it's not a directory slated for removal.
162 In the ordinary case, this is not a problem: for our purposes, the user 164 In the ordinary case, this is not a problem: for our purposes, the user
163 will never lack write permission on *path's parent. 165 will never lack write permission on *path's parent.
164 """ 166 """
167 logging.debug(path)
bradn 2009/12/23 17:30:25 Or particularly here: removing directory 'blah'
165 file_path = os.path.join(*path) 168 file_path = os.path.join(*path)
166 if not os.path.exists(file_path): 169 if not os.path.exists(file_path):
167 return 170 return
168 171
169 if os.path.islink(file_path) or not os.path.isdir(file_path): 172 if os.path.islink(file_path) or not os.path.isdir(file_path):
170 raise Error("RemoveDirectory asked to remove non-directory %s" % file_path) 173 raise Error("RemoveDirectory asked to remove non-directory %s" % file_path)
171 174
172 has_win32api = False 175 has_win32api = False
173 if sys.platform == 'win32': 176 if sys.platform == 'win32':
174 has_win32api = True 177 has_win32api = True
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 252
250 If a filter function is specified, it is expected to take a single 253 If a filter function is specified, it is expected to take a single
251 string argument, and it will be called with each line of the 254 string argument, and it will be called with each line of the
252 subprocess's output. Each line has had the trailing newline character 255 subprocess's output. Each line has had the trailing newline character
253 trimmed. 256 trimmed.
254 257
255 If the command fails, as indicated by a nonzero exit status, gclient will 258 If the command fails, as indicated by a nonzero exit status, gclient will
256 exit with an exit status of fail_status. If fail_status is None (the 259 exit with an exit status of fail_status. If fail_status is None (the
257 default), gclient will raise an Error exception. 260 default), gclient will raise an Error exception.
258 """ 261 """
259 262 logging.debug(command)
260 if print_messages: 263 if print_messages:
261 print("\n________ running \'%s\' in \'%s\'" 264 print("\n________ running \'%s\' in \'%s\'"
262 % (' '.join(command), in_directory)) 265 % (' '.join(command), in_directory))
263 266
264 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the 267 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the
265 # executable, but shell=True makes subprocess on Linux fail when it's called 268 # executable, but shell=True makes subprocess on Linux fail when it's called
266 # with a list because it only tries to execute the first item in the list. 269 # with a list because it only tries to execute the first item in the list.
267 kid = subprocess.Popen(command, bufsize=0, cwd=in_directory, 270 kid = subprocess.Popen(command, bufsize=0, cwd=in_directory,
268 shell=(sys.platform == 'win32'), stdout=subprocess.PIPE, 271 shell=(sys.platform == 'win32'), stdout=subprocess.PIPE,
269 stderr=subprocess.STDOUT) 272 stderr=subprocess.STDOUT)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 return False 312 return False
310 313
311 def FindGclientRoot(from_dir): 314 def FindGclientRoot(from_dir):
312 """Tries to find the gclient root.""" 315 """Tries to find the gclient root."""
313 path = os.path.realpath(from_dir) 316 path = os.path.realpath(from_dir)
314 while not os.path.exists(os.path.join(path, '.gclient')): 317 while not os.path.exists(os.path.join(path, '.gclient')):
315 next = os.path.split(path) 318 next = os.path.split(path)
316 if not next[1]: 319 if not next[1]:
317 return None 320 return None
318 path = next[0] 321 path = next[0]
322 logging.info('Found gclient root at ' + path)
319 return path 323 return path
320 324
321 def PathDifference(root, subpath): 325 def PathDifference(root, subpath):
322 """Returns the difference subpath minus root.""" 326 """Returns the difference subpath minus root."""
323 root = os.path.realpath(root) 327 root = os.path.realpath(root)
324 subpath = os.path.realpath(subpath) 328 subpath = os.path.realpath(subpath)
325 if not subpath.startswith(root): 329 if not subpath.startswith(root):
326 return None 330 return None
327 # If the root does not have a trailing \ or /, we add it so the returned 331 # If the root does not have a trailing \ or /, we add it so the returned
328 # path starts immediately after the seperator regardless of whether it is 332 # path starts immediately after the seperator regardless of whether it is
329 # provided. 333 # provided.
330 root = os.path.join(root, '') 334 root = os.path.join(root, '')
331 return subpath[len(root):] 335 return subpath[len(root):]
OLDNEW
« no previous file with comments | « gcl.py ('k') | tests/trychange_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698