| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
| 6 # | 6 # |
| 7 | 7 |
| 8 import optparse | 8 import optparse |
| 9 import os | 9 import os |
| 10 import re | 10 import re |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 'prebuilt', toolchain_dir, 'bin') | 191 'prebuilt', toolchain_dir, 'bin') |
| 192 CheckDirExists(android_toolchain, 'Android toolchain') | 192 CheckDirExists(android_toolchain, 'Android toolchain') |
| 193 | 193 |
| 194 return android_toolchain | 194 return android_toolchain |
| 195 | 195 |
| 196 | 196 |
| 197 def Execute(args): | 197 def Execute(args): |
| 198 process = subprocess.Popen(args) | 198 process = subprocess.Popen(args) |
| 199 process.wait() | 199 process.wait() |
| 200 if process.returncode != 0: | 200 if process.returncode != 0: |
| 201 raise Exception(args[0] + " failed") | 201 raise Exception(args[0] + " failed") |
| 202 | 202 |
| 203 | 203 |
| 204 def CurrentDirectoryBaseName(): | 204 def CurrentDirectoryBaseName(): |
| 205 """Returns the name of the current directory""" | 205 """Returns the name of the current directory""" |
| 206 return os.path.relpath(os.curdir, start=os.pardir) | 206 return os.path.relpath(os.curdir, start=os.pardir) |
| 207 | 207 |
| 208 | 208 |
| 209 def FilterEmptyXcodebuildSections(process): | 209 def FilterEmptyXcodebuildSections(process): |
| 210 """ | 210 """ |
| 211 Filter output from xcodebuild so empty sections are less verbose. | 211 Filter output from xcodebuild so empty sections are less verbose. |
| 212 | 212 |
| 213 The output from xcodebuild looks like this: | 213 The output from xcodebuild looks like this: |
| 214 | 214 |
| 215 Build settings from command line: | 215 Build settings from command line: |
| 216 SYMROOT = .../xcodebuild | 216 SYMROOT = .../xcodebuild |
| 217 | 217 |
| 218 === BUILD AGGREGATE TARGET samples OF PROJECT dart WITH CONFIGURATION ... | 218 === BUILD TARGET samples OF PROJECT dart WITH CONFIGURATION ... |
| 219 |
| 219 Check dependencies | 220 Check dependencies |
| 220 | 221 |
| 222 === BUILD AGGREGATE TARGET upload_sdk OF PROJECT dart WITH CONFIGURATION ... |
| 221 | 223 |
| 222 === BUILD AGGREGATE TARGET upload_sdk OF PROJECT dart WITH CONFIGURATION ... | |
| 223 Check dependencies | 224 Check dependencies |
| 224 | 225 |
| 225 PhaseScriptExecution "Action \"upload_sdk_py\"" xcodebuild/dart.build/... | 226 PhaseScriptExecution "Action \"upload_sdk_py\"" xcodebuild/dart.build/... |
| 226 cd ... | 227 cd ... |
| 227 /bin/sh -c .../xcodebuild/dart.build/ReleaseIA32/upload_sdk.build/... | 228 /bin/sh -c .../xcodebuild/dart.build/ReleaseIA32/upload_sdk.build/... |
| 228 | 229 |
| 229 | 230 |
| 230 ** BUILD SUCCEEDED ** | 231 ** BUILD SUCCEEDED ** |
| 231 | 232 |
| 232 """ | 233 """ |
| 233 | 234 |
| 234 def is_empty_chunk(chunk): | 235 def is_empty_chunk(chunk): |
| 235 empty_chunk = ['Check dependencies', '', ''] | 236 empty_chunk = ['', 'Check dependencies', ''] |
| 236 return not chunk or (len(chunk) == 4 and chunk[1:] == empty_chunk) | 237 return not chunk or (len(chunk) == 4 and chunk[1:] == empty_chunk) |
| 237 | 238 |
| 238 def unbuffered(callable): | 239 def unbuffered(callable): |
| 239 # Use iter to disable buffering in for-in. | 240 # Use iter to disable buffering in for-in. |
| 240 return iter(callable, '') | 241 return iter(callable, '') |
| 241 | 242 |
| 242 section = None | 243 section = None |
| 243 chunk = [] | 244 chunk = [] |
| 244 # Is stdout a terminal which supports colors? | 245 # Is stdout a terminal which supports colors? |
| 245 is_fancy_tty = False | 246 is_fancy_tty = False |
| 246 clr_eol = None | 247 clr_eol = None |
| 247 if sys.stdout.isatty(): | 248 if sys.stdout.isatty(): |
| 248 term = os.getenv('TERM', 'dumb') | 249 term = os.getenv('TERM', 'dumb') |
| 249 # The capability "clr_eol" means clear the line from cursor to end | 250 # The capability "clr_eol" means clear the line from cursor to end |
| 250 # of line. See man pages for tput and terminfo. | 251 # of line. See man pages for tput and terminfo. |
| 251 try: | 252 try: |
| 252 with open('/dev/null', 'a') as dev_null: | 253 with open('/dev/null', 'a') as dev_null: |
| 253 clr_eol = subprocess.check_output(['tput', '-T' + term, 'el'], | 254 clr_eol = subprocess.check_output(['tput', '-T' + term, 'el'], |
| 254 stderr=dev_null) | 255 stderr=dev_null) |
| 255 if clr_eol: | 256 if clr_eol: |
| 256 is_fancy_tty = True | 257 is_fancy_tty = True |
| 257 except subprocess.CalledProcessError: | 258 except subprocess.CalledProcessError: |
| 258 is_fancy_tty = False | 259 is_fancy_tty = False |
| 259 except AttributeError: | 260 except AttributeError: |
| 260 is_fancy_tty = False | 261 is_fancy_tty = False |
| 261 pattern = re.compile(r'=== BUILD .* TARGET (.*) OF PROJECT (.*) WITH ' + | 262 pattern = re.compile(r'=== BUILD.* TARGET (.*) OF PROJECT (.*) WITH ' + |
| 262 r'CONFIGURATION (.*) ===') | 263 r'CONFIGURATION (.*) ===') |
| 263 has_interesting_info = False | 264 has_interesting_info = False |
| 264 for line in unbuffered(process.stdout.readline): | 265 for line in unbuffered(process.stdout.readline): |
| 265 line = line.rstrip() | 266 line = line.rstrip() |
| 266 if line.startswith('=== BUILD ') or line.startswith('** BUILD '): | 267 if line.startswith('=== BUILD ') or line.startswith('** BUILD '): |
| 267 has_interesting_info = False | 268 has_interesting_info = False |
| 268 section = line | 269 section = line |
| 269 if is_fancy_tty: | 270 if is_fancy_tty: |
| 270 match = re.match(pattern, section) | 271 match = re.match(pattern, section) |
| 271 if match: | 272 if match: |
| 272 section = '%s/%s/%s' % ( | 273 section = '%s/%s/%s' % ( |
| 273 match.group(3), match.group(2), match.group(1)) | 274 match.group(3), match.group(2), match.group(1)) |
| 274 # Truncate to avoid extending beyond 80 columns. | 275 # Truncate to avoid extending beyond 80 columns. |
| 275 section = section[:80] | 276 section = section[:80] |
| 276 # If stdout is a terminal, emit "progress" information. The | 277 # If stdout is a terminal, emit "progress" information. The |
| 277 # progress information is the first line of the current chunk. | 278 # progress information is the first line of the current chunk. |
| 278 # After printing the line, move the cursor back to the | 279 # After printing the line, move the cursor back to the |
| 279 # beginning of the line. This has two effects: First, if the | 280 # beginning of the line. This has two effects: First, if the |
| 280 # chunk isn't empty, the first line will be overwritten | 281 # chunk isn't empty, the first line will be overwritten |
| 281 # (avoiding duplication). Second, the next segment line will | 282 # (avoiding duplication). Second, the next segment line will |
| 282 # overwrite it too avoid long scrollback. clr_eol ensures | 283 # overwrite it too avoid long scrollback. clr_eol ensures |
| 283 # that there is no trailing garbage when a shorter line | 284 # that there is no trailing garbage when a shorter line |
| 284 # overwrites a longer line. | 285 # overwrites a longer line. |
| 285 print '%s%s\r' % (clr_eol, section), | 286 print '%s%s\r' % (clr_eol, section), |
| 286 chunk = [] | 287 chunk = [] |
| 287 if not section or has_interesting_info: | 288 if not section or has_interesting_info: |
| 288 print line | 289 print line |
| 289 else: | 290 else: |
| 290 length = len(chunk) | 291 length = len(chunk) |
| 291 if length == 1 and line != 'Check dependencies': | 292 if length == 2 and line != 'Check dependencies': |
| 292 has_interesting_info = True | 293 has_interesting_info = True |
| 293 elif (length == 2 or length == 3) and line: | 294 elif (length == 1 or length == 3) and line: |
| 294 has_interesting_info = True | 295 has_interesting_info = True |
| 295 if has_interesting_info: | 296 if has_interesting_info: |
| 296 print '\n'.join(chunk) | 297 print '\n'.join(chunk) |
| 297 chunk = [] | 298 chunk = [] |
| 298 else: | 299 else: |
| 299 chunk.append(line) | 300 chunk.append(line) |
| 300 if not is_empty_chunk(chunk): | 301 if not is_empty_chunk(chunk): |
| 301 print '\n'.join(chunk) | 302 print '\n'.join(chunk) |
| 302 | 303 |
| 303 | 304 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 process.wait() | 406 process.wait() |
| 406 if process.returncode != 0: | 407 if process.returncode != 0: |
| 407 print "BUILD FAILED" | 408 print "BUILD FAILED" |
| 408 return 1 | 409 return 1 |
| 409 | 410 |
| 410 return 0 | 411 return 0 |
| 411 | 412 |
| 412 | 413 |
| 413 if __name__ == '__main__': | 414 if __name__ == '__main__': |
| 414 sys.exit(Main()) | 415 sys.exit(Main()) |
| OLD | NEW |