OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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):] |
OLD | NEW |