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 |