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.""" |
| 16 |
15 import errno | 17 import errno |
16 import os | 18 import os |
17 import re | 19 import re |
18 import stat | 20 import stat |
19 import subprocess | 21 import subprocess |
20 import sys | 22 import sys |
21 import time | 23 import time |
22 import xml.dom.minidom | 24 import xml.dom.minidom |
23 import xml.parsers.expat | 25 import xml.parsers.expat |
24 | 26 |
25 ## Generic utils | |
26 | |
27 | 27 |
28 def SplitUrlRevision(url): | 28 def SplitUrlRevision(url): |
29 """Splits url and returns a two-tuple: url, rev""" | 29 """Splits url and returns a two-tuple: url, rev""" |
30 if url.startswith('ssh:'): | 30 if url.startswith('ssh:'): |
31 # Make sure ssh://test@example.com/test.git@stable works | 31 # Make sure ssh://test@example.com/test.git@stable works |
32 regex = r"(ssh://(?:[\w]+@)?[-\w:\.]+/[-\w\.]+)(?:@([\w/]+))?" | 32 regex = r"(ssh://(?:[\w]+@)?[-\w:\.]+/[-\w\.]+)(?:@([\w/]+))?" |
33 components = re.search(regex, url).groups() | 33 components = re.search(regex, url).groups() |
34 else: | 34 else: |
35 components = url.split("@") | 35 components = url.split("@") |
36 if len(components) == 1: | 36 if len(components) == 1: |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 class PrintableObject(object): | 69 class PrintableObject(object): |
70 def __str__(self): | 70 def __str__(self): |
71 output = '' | 71 output = '' |
72 for i in dir(self): | 72 for i in dir(self): |
73 if i.startswith('__'): | 73 if i.startswith('__'): |
74 continue | 74 continue |
75 output += '%s = %s\n' % (i, str(getattr(self, i, ''))) | 75 output += '%s = %s\n' % (i, str(getattr(self, i, ''))) |
76 return output | 76 return output |
77 | 77 |
78 | 78 |
79 def FileRead(filename): | 79 def FileRead(filename, mode='rU'): |
80 content = None | 80 content = None |
81 f = open(filename, "rU") | 81 f = open(filename, mode) |
82 try: | 82 try: |
83 content = f.read() | 83 content = f.read() |
84 finally: | 84 finally: |
85 f.close() | 85 f.close() |
86 return content | 86 return content |
87 | 87 |
88 | 88 |
89 def FileWrite(filename, content): | 89 def FileWrite(filename, content, mode='w'): |
90 f = open(filename, "w") | 90 f = open(filename, mode) |
91 try: | 91 try: |
92 f.write(content) | 92 f.write(content) |
93 finally: | 93 finally: |
94 f.close() | 94 f.close() |
95 | 95 |
96 | 96 |
97 def RemoveDirectory(*path): | 97 def RemoveDirectory(*path): |
98 """Recursively removes a directory, even if it's marked read-only. | 98 """Recursively removes a directory, even if it's marked read-only. |
99 | 99 |
100 Remove the directory located at *path, if it exists. | 100 Remove the directory located at *path, if it exists. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 print_messages, | 194 print_messages, |
195 print_stdout, | 195 print_stdout, |
196 fail_status=None, filter=None): | 196 fail_status=None, filter=None): |
197 """Runs command, a list, in directory in_directory. | 197 """Runs command, a list, in directory in_directory. |
198 | 198 |
199 If print_messages is true, a message indicating what is being done | 199 If print_messages is true, a message indicating what is being done |
200 is printed to stdout. If print_messages is false, the message is printed | 200 is printed to stdout. If print_messages is false, the message is printed |
201 only if we actually need to print something else as well, so you can | 201 only if we actually need to print something else as well, so you can |
202 get the context of the output. If print_messages is false and print_stdout | 202 get the context of the output. If print_messages is false and print_stdout |
203 is false, no output at all is generated. | 203 is false, no output at all is generated. |
204 | 204 |
205 Also, if print_stdout is true, the command's stdout is also forwarded | 205 Also, if print_stdout is true, the command's stdout is also forwarded |
206 to stdout. | 206 to stdout. |
207 | 207 |
208 If a filter function is specified, it is expected to take a single | 208 If a filter function is specified, it is expected to take a single |
209 string argument, and it will be called with each line of the | 209 string argument, and it will be called with each line of the |
210 subprocess's output. Each line has had the trailing newline character | 210 subprocess's output. Each line has had the trailing newline character |
211 trimmed. | 211 trimmed. |
212 | 212 |
213 If the command fails, as indicated by a nonzero exit status, gclient will | 213 If the command fails, as indicated by a nonzero exit status, gclient will |
214 exit with an exit status of fail_status. If fail_status is None (the | 214 exit with an exit status of fail_status. If fail_status is None (the |
215 default), gclient will raise an Error exception. | 215 default), gclient will raise an Error exception. |
216 """ | 216 """ |
217 | 217 |
218 if print_messages: | 218 if print_messages: |
219 print("\n________ running \'%s\' in \'%s\'" | 219 print("\n________ running \'%s\' in \'%s\'" |
220 % (' '.join(command), in_directory)) | 220 % (' '.join(command), in_directory)) |
221 | 221 |
222 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the | 222 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the |
223 # executable, but shell=True makes subprocess on Linux fail when it's called | 223 # executable, but shell=True makes subprocess on Linux fail when it's called |
224 # with a list because it only tries to execute the first item in the list. | 224 # with a list because it only tries to execute the first item in the list. |
225 kid = subprocess.Popen(command, bufsize=0, cwd=in_directory, | 225 kid = subprocess.Popen(command, bufsize=0, cwd=in_directory, |
226 shell=(sys.platform == 'win32'), stdout=subprocess.PIPE, | 226 shell=(sys.platform == 'win32'), stdout=subprocess.PIPE, |
227 stderr=subprocess.STDOUT) | 227 stderr=subprocess.STDOUT) |
228 | 228 |
229 # Also, we need to forward stdout to prevent weird re-ordering of output. | 229 # Also, we need to forward stdout to prevent weird re-ordering of output. |
230 # This has to be done on a per byte basis to make sure it is not buffered: | 230 # This has to be done on a per byte basis to make sure it is not buffered: |
231 # normally buffering is done for each line, but if svn requests input, no | 231 # normally buffering is done for each line, but if svn requests input, no |
232 # end-of-line character is output after the prompt and it would not show up. | 232 # end-of-line character is output after the prompt and it would not show up. |
233 in_byte = kid.stdout.read(1) | 233 in_byte = kid.stdout.read(1) |
234 in_line = "" | 234 in_line = "" |
235 while in_byte: | 235 while in_byte: |
236 if in_byte != "\r": | 236 if in_byte != "\r": |
237 if print_stdout: | 237 if print_stdout: |
238 if not print_messages: | 238 if not print_messages: |
239 print("\n________ running \'%s\' in \'%s\'" | 239 print("\n________ running \'%s\' in \'%s\'" |
240 % (' '.join(command), in_directory)) | 240 % (' '.join(command), in_directory)) |
241 print_messages = True | 241 print_messages = True |
242 sys.stdout.write(in_byte) | 242 sys.stdout.write(in_byte) |
243 if in_byte != "\n": | 243 if in_byte != "\n": |
244 in_line += in_byte | 244 in_line += in_byte |
245 if in_byte == "\n" and filter: | 245 if in_byte == "\n" and filter: |
246 filter(in_line) | 246 filter(in_line) |
247 in_line = "" | 247 in_line = "" |
248 in_byte = kid.stdout.read(1) | 248 in_byte = kid.stdout.read(1) |
249 rv = kid.wait() | 249 rv = kid.wait() |
250 | 250 |
251 if rv: | 251 if rv: |
252 msg = "failed to run command: %s" % " ".join(command) | 252 msg = "failed to run command: %s" % " ".join(command) |
253 | 253 |
254 if fail_status != None: | 254 if fail_status != None: |
255 print >>sys.stderr, msg | 255 print >>sys.stderr, msg |
256 sys.exit(fail_status) | 256 sys.exit(fail_status) |
257 | 257 |
258 raise Error(msg) | 258 raise Error(msg) |
259 | 259 |
260 | 260 |
261 def IsUsingGit(root, paths): | 261 def IsUsingGit(root, paths): |
262 """Returns True if we're using git to manage any of our checkouts. | 262 """Returns True if we're using git to manage any of our checkouts. |
263 |entries| is a list of paths to check.""" | 263 |entries| is a list of paths to check.""" |
264 for path in paths: | 264 for path in paths: |
265 if os.path.exists(os.path.join(root, path, '.git')): | 265 if os.path.exists(os.path.join(root, path, '.git')): |
266 return True | 266 return True |
267 return False | 267 return False |
OLD | NEW |