| 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 |