Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: tools/bisect-perf-regression.py

Issue 16023021: Try to expand the revision range to include a change to .DEPS.git if the script detects a change to… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changes from review. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Performance Test Bisect Tool 6 """Performance Test Bisect Tool
7 7
8 This script bisects a series of changelists using binary search. It starts at 8 This script bisects a series of changelists using binary search. It starts at
9 a bad revision where a performance metric has regressed, and asks for a last 9 a bad revision where a performance metric has regressed, and asks for a last
10 known-good revision. It will then binary search across this revision range by 10 known-good revision. It will then binary search across this revision range by
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 command: A list containing the args to git. 244 command: A list containing the args to git.
245 245
246 Returns: 246 Returns:
247 A tuple of the output and return code. 247 A tuple of the output and return code.
248 """ 248 """
249 command = ['git'] + command 249 command = ['git'] + command
250 250
251 return RunProcess(command) 251 return RunProcess(command)
252 252
253 253
254 def CheckRunGit(command):
255 """Run a git subcommand, returning its output and return code. Asserts if
256 the return code of the call is non-zero.
257
258 Args:
259 command: A list containing the args to git.
260
261 Returns:
262 A tuple of the output and return code.
263 """
264 (output, return_code) = RunGit(command)
265
266 assert not return_code, 'An error occurred while running'\
267 ' "git %s"' % ' '.join(command)
268 return (output, return_code)
tonyg 2013/05/28 23:45:06 Since we know return_code is 0 at this point, I'd
shatch 2013/05/29 16:25:28 Done.
269
270
254 def BuildWithMake(threads, targets, print_output): 271 def BuildWithMake(threads, targets, print_output):
255 cmd = ['make', 'BUILDTYPE=Release', '-j%d' % threads] + targets 272 cmd = ['make', 'BUILDTYPE=Release', '-j%d' % threads] + targets
256 273
257 (output, return_code) = RunProcess(cmd, print_output) 274 (output, return_code) = RunProcess(cmd, print_output)
258 275
259 return not return_code 276 return not return_code
260 277
261 278
262 def BuildWithNinja(threads, targets, print_output): 279 def BuildWithNinja(threads, targets, print_output):
263 cmd = ['ninja', '-C', os.path.join('out', 'Release'), 280 cmd = ['ninja', '-C', os.path.join('out', 'Release'),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 Args: 336 Args:
320 revision_range_end: The SHA1 for the end of the range. 337 revision_range_end: The SHA1 for the end of the range.
321 revision_range_start: The SHA1 for the beginning of the range. 338 revision_range_start: The SHA1 for the beginning of the range.
322 339
323 Returns: 340 Returns:
324 A list of the revisions between |revision_range_start| and 341 A list of the revisions between |revision_range_start| and
325 |revision_range_end| (inclusive). 342 |revision_range_end| (inclusive).
326 """ 343 """
327 revision_range = '%s..%s' % (revision_range_start, revision_range_end) 344 revision_range = '%s..%s' % (revision_range_start, revision_range_end)
328 cmd = ['log', '--format=%H', '-10000', '--first-parent', revision_range] 345 cmd = ['log', '--format=%H', '-10000', '--first-parent', revision_range]
329 (log_output, return_code) = RunGit(cmd) 346 (log_output, return_code) = CheckRunGit(cmd)
330
331 assert not return_code, 'An error occurred while running'\
332 ' "git %s"' % ' '.join(cmd)
333 347
334 revision_hash_list = log_output.split() 348 revision_hash_list = log_output.split()
335 revision_hash_list.append(revision_range_start) 349 revision_hash_list.append(revision_range_start)
336 350
337 return revision_hash_list 351 return revision_hash_list
338 352
339 def SyncToRevision(self, revision, use_gclient=True): 353 def SyncToRevision(self, revision, use_gclient=True):
340 """Syncs to the specified revision. 354 """Syncs to the specified revision.
341 355
342 Args: 356 Args:
343 revision: The revision to sync to. 357 revision: The revision to sync to.
344 use_gclient: Specifies whether or not we should sync using gclient or 358 use_gclient: Specifies whether or not we should sync using gclient or
345 just use source control directly. 359 just use source control directly.
346 360
347 Returns: 361 Returns:
348 True if successful. 362 True if successful.
349 """ 363 """
350 364
351 if use_gclient: 365 if use_gclient:
352 results = self.SyncToRevisionWithGClient(revision) 366 results = self.SyncToRevisionWithGClient(revision)
353 else: 367 else:
354 results = RunGit(['checkout', revision])[1] 368 results = RunGit(['checkout', revision])[1]
tonyg 2013/05/28 23:45:06 CheckRunGit?
shatch 2013/05/29 16:25:28 Not sure under which conditions checkout can fail.
355 369
356 return not results 370 return not results
357 371
358 def ResolveToRevision(self, revision_to_check, depot, search): 372 def ResolveToRevision(self, revision_to_check, depot, search):
359 """If an SVN revision is supplied, try to resolve it to a git SHA1. 373 """If an SVN revision is supplied, try to resolve it to a git SHA1.
360 374
361 Args: 375 Args:
362 revision_to_check: The user supplied revision string that may need to be 376 revision_to_check: The user supplied revision string that may need to be
363 resolved to a git SHA1. 377 resolved to a git SHA1.
364 depot: The depot the revision_to_check is from. 378 depot: The depot the revision_to_check is from.
(...skipping 17 matching lines...) Expand all
382 396
383 if search > 0: 397 if search > 0:
384 search_range = xrange(svn_revision, svn_revision + search, 1) 398 search_range = xrange(svn_revision, svn_revision + search, 1)
385 else: 399 else:
386 search_range = xrange(svn_revision, svn_revision + search, -1) 400 search_range = xrange(svn_revision, svn_revision + search, -1)
387 401
388 for i in search_range: 402 for i in search_range:
389 svn_pattern = 'git-svn-id: %s@%d' % (depot_svn, i) 403 svn_pattern = 'git-svn-id: %s@%d' % (depot_svn, i)
390 cmd = ['log', '--format=%H', '-1', '--grep', svn_pattern, 'origin/master'] 404 cmd = ['log', '--format=%H', '-1', '--grep', svn_pattern, 'origin/master']
391 405
392 (log_output, return_code) = RunGit(cmd) 406 (log_output, return_code) = CheckRunGit(cmd)
393
394 assert not return_code, 'An error occurred while running'\
395 ' "git %s"' % ' '.join(cmd)
396 407
397 if not return_code: 408 if not return_code:
398 log_output = log_output.strip() 409 log_output = log_output.strip()
399 410
400 if log_output: 411 if log_output:
401 git_revision = log_output 412 git_revision = log_output
402 413
403 break 414 break
404 415
405 return git_revision 416 return git_revision
406 417
407 def IsInProperBranch(self): 418 def IsInProperBranch(self):
408 """Confirms they're in the master branch for performing the bisection. 419 """Confirms they're in the master branch for performing the bisection.
409 This is needed or gclient will fail to sync properly. 420 This is needed or gclient will fail to sync properly.
410 421
411 Returns: 422 Returns:
412 True if the current branch on src is 'master' 423 True if the current branch on src is 'master'
413 """ 424 """
414 cmd = ['rev-parse', '--abbrev-ref', 'HEAD'] 425 cmd = ['rev-parse', '--abbrev-ref', 'HEAD']
415 (log_output, return_code) = RunGit(cmd) 426 (log_output, return_code) = CheckRunGit(cmd)
416
417 assert not return_code, 'An error occurred while running'\
418 ' "git %s"' % ' '.join(cmd)
419 427
420 log_output = log_output.strip() 428 log_output = log_output.strip()
421 429
422 return log_output == "master" 430 return log_output == "master"
423 431
424 def SVNFindRev(self, revision): 432 def SVNFindRev(self, revision):
425 """Maps directly to the 'git svn find-rev' command. 433 """Maps directly to the 'git svn find-rev' command.
426 434
427 Args: 435 Args:
428 revision: The git SHA1 to use. 436 revision: The git SHA1 to use.
429 437
430 Returns: 438 Returns:
431 An integer changelist #, otherwise None. 439 An integer changelist #, otherwise None.
432 """ 440 """
433 441
434 cmd = ['svn', 'find-rev', revision] 442 cmd = ['svn', 'find-rev', revision]
435 443
436 (output, return_code) = RunGit(cmd) 444 (output, return_code) = CheckRunGit(cmd)
437
438 assert not return_code, 'An error occurred while running'\
439 ' "git %s"' % ' '.join(cmd)
440 445
441 svn_revision = output.strip() 446 svn_revision = output.strip()
442 447
443 if IsStringInt(svn_revision): 448 if IsStringInt(svn_revision):
444 return int(svn_revision) 449 return int(svn_revision)
445 450
446 return None 451 return None
447 452
448 def QueryRevisionInfo(self, revision): 453 def QueryRevisionInfo(self, revision):
449 """Gathers information on a particular revision, such as author's name, 454 """Gathers information on a particular revision, such as author's name,
(...skipping 10 matching lines...) Expand all
460 'subject': %s, 465 'subject': %s,
461 } 466 }
462 """ 467 """
463 commit_info = {} 468 commit_info = {}
464 469
465 formats = ['%cN', '%cE', '%s', '%cD'] 470 formats = ['%cN', '%cE', '%s', '%cD']
466 targets = ['author', 'email', 'subject', 'date'] 471 targets = ['author', 'email', 'subject', 'date']
467 472
468 for i in xrange(len(formats)): 473 for i in xrange(len(formats)):
469 cmd = ['log', '--format=%s' % formats[i], '-1', revision] 474 cmd = ['log', '--format=%s' % formats[i], '-1', revision]
470 (output, return_code) = RunGit(cmd) 475 (output, return_code) = CheckRunGit(cmd)
471 commit_info[targets[i]] = output.rstrip() 476 commit_info[targets[i]] = output.rstrip()
472 477
473 assert not return_code, 'An error occurred while running'\
474 ' "git %s"' % ' '.join(cmd)
475
476 return commit_info 478 return commit_info
477 479
478 def CheckoutFileAtRevision(self, file_name, revision): 480 def CheckoutFileAtRevision(self, file_name, revision):
479 """Performs a checkout on a file at the given revision. 481 """Performs a checkout on a file at the given revision.
480 482
481 Returns: 483 Returns:
482 True if successful. 484 True if successful.
483 """ 485 """
484 return not RunGit(['checkout', revision, file_name])[1] 486 return not RunGit(['checkout', revision, file_name])[1]
485 487
486 def RevertFileToHead(self, file_name): 488 def RevertFileToHead(self, file_name):
487 """Unstages a file and returns it to HEAD. 489 """Unstages a file and returns it to HEAD.
488 490
489 Returns: 491 Returns:
490 True if successful. 492 True if successful.
491 """ 493 """
492 # Reset doesn't seem to return 0 on success. 494 # Reset doesn't seem to return 0 on success.
493 RunGit(['reset', 'HEAD', bisect_utils.FILE_DEPS_GIT]) 495 RunGit(['reset', 'HEAD', bisect_utils.FILE_DEPS_GIT])
494 496
495 return not RunGit(['checkout', bisect_utils.FILE_DEPS_GIT])[1] 497 return not RunGit(['checkout', bisect_utils.FILE_DEPS_GIT])[1]
496 498
499 def QueryFileRevisionHistory(self, filename, revision_start, revision_end):
500 """Returns a list of commits that modified this file.
501
502 Args:
503 filename: Name of file.
504 revision_start: Start of revision range.
505 revision_end: End of revision range.
506
507 Returns:
508 Returns a list of commits that touched this file.
509 """
510 cmd = ['log', '--format=%H', '%s^1..%s' % (revision_start, revision_end),
511 filename]
512 (output, return_code) = CheckRunGit(cmd)
513
514 return [o for o in output.split('\n') if o]
515
497 class BisectPerformanceMetrics(object): 516 class BisectPerformanceMetrics(object):
498 """BisectPerformanceMetrics performs a bisection against a list of range 517 """BisectPerformanceMetrics performs a bisection against a list of range
499 of revisions to narrow down where performance regressions may have 518 of revisions to narrow down where performance regressions may have
500 occurred.""" 519 occurred."""
501 520
502 def __init__(self, source_control, opts): 521 def __init__(self, source_control, opts):
503 super(BisectPerformanceMetrics, self).__init__() 522 super(BisectPerformanceMetrics, self).__init__()
504 523
505 self.opts = opts 524 self.opts = opts
506 self.source_control = source_control 525 self.source_control = source_control
507 self.src_cwd = os.getcwd() 526 self.src_cwd = os.getcwd()
508 self.depot_cwd = {} 527 self.depot_cwd = {}
509 self.cleanup_commands = [] 528 self.cleanup_commands = []
529 self.warnings = []
510 530
511 # This always starts true since the script grabs latest first. 531 # This always starts true since the script grabs latest first.
512 self.was_blink = True 532 self.was_blink = True
513 533
514 for d in DEPOT_NAMES: 534 for d in DEPOT_NAMES:
515 # The working directory of each depot is just the path to the depot, but 535 # The working directory of each depot is just the path to the depot, but
516 # since we're already in 'src', we can skip that part. 536 # since we're already in 'src', we can skip that part.
517 537
518 self.depot_cwd[d] = self.src_cwd + DEPOT_DEPS_NAME[d]['src'][3:] 538 self.depot_cwd[d] = self.src_cwd + DEPOT_DEPS_NAME[d]['src'][3:]
519 539
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 1057
1038 print 1058 print
1039 print 'Revisions to bisect on [%s]:' % depot 1059 print 'Revisions to bisect on [%s]:' % depot
1040 for revision_id in revision_list: 1060 for revision_id in revision_list:
1041 print ' -> %s' % (revision_id, ) 1061 print ' -> %s' % (revision_id, )
1042 print 1062 print
1043 1063
1044 if self.opts.output_buildbot_annotations: 1064 if self.opts.output_buildbot_annotations:
1045 bisect_utils.OutputAnnotationStepClosed() 1065 bisect_utils.OutputAnnotationStepClosed()
1046 1066
1067 def NudgeRevisionsIfDEPSChange(self, bad_revision, good_revision):
1068 """Checks to see if changes to DEPS file occurred, and that the revision
1069 range also includes the change to .DEPS.git. If it doesn't, attempts to
1070 expand the revision range to include it.
1071
1072 Args:
1073 bad_rev: First known bad revision.
1074 good_revision: Last known good revision.
1075
1076 Returns:
1077 A tuple with the new bad and good revisions.
1078 """
1079 if self.source_control.IsGit():
1080 changes_to_deps = self.source_control.QueryFileRevisionHistory(
1081 'DEPS', good_revision, bad_revision)
1082
1083 if changes_to_deps:
1084 # DEPS file was changed, search from the oldest change to DEPS file to
1085 # bad_revision to see if there are matching .DEPS.git changes.
1086 oldest_deps_change = changes_to_deps[-1]
1087 changes_to_gitdeps = self.source_control.QueryFileRevisionHistory(
1088 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision)
1089
1090 if len(changes_to_deps) != len(changes_to_gitdeps):
1091 # Grab the timestamp of the last DEPS change
1092 cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]]
1093 (output, return_code) = CheckRunGit(cmd)
1094
1095 commit_time = int(output)
1096
1097 # Try looking for a commit that touches the .DEPS.git file in the
1098 # next 15 minutes after the DEPS file change.
1099 cmd = ['log', '--format=%H', '-1',
1100 '--before=%d' % (commit_time + 900), '--after=%d' % commit_time,
1101 'origin/master', bisect_utils.FILE_DEPS_GIT]
1102 (output, return_code) = CheckRunGit(cmd)
1103
1104 output = output.strip()
1105 if output:
1106 self.warnings.append('Detected change to DEPS and modified '
1107 'revision range to include change to .DEPS.git')
1108 return (output, good_revision)
1109 else:
1110 self.warnings.append('Detected change to DEPS but couldn\'t find '
1111 'matching change to .DEPS.git')
1112 return (bad_revision, good_revision)
1113
1047 def Run(self, command_to_run, bad_revision_in, good_revision_in, metric): 1114 def Run(self, command_to_run, bad_revision_in, good_revision_in, metric):
1048 """Given known good and bad revisions, run a binary search on all 1115 """Given known good and bad revisions, run a binary search on all
1049 intermediate revisions to determine the CL where the performance regression 1116 intermediate revisions to determine the CL where the performance regression
1050 occurred. 1117 occurred.
1051 1118
1052 Args: 1119 Args:
1053 command_to_run: Specify the command to execute the performance test. 1120 command_to_run: Specify the command to execute the performance test.
1054 good_revision: Number/tag of the known good revision. 1121 good_revision: Number/tag of the known good revision.
1055 bad_revision: Number/tag of the known bad revision. 1122 bad_revision: Number/tag of the known bad revision.
1056 metric: The performance metric to monitor. 1123 metric: The performance metric to monitor.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 'src', -100) 1165 'src', -100)
1099 1166
1100 if bad_revision is None: 1167 if bad_revision is None:
1101 results['error'] = 'Could\'t resolve [%s] to SHA1.' % (bad_revision_in,) 1168 results['error'] = 'Could\'t resolve [%s] to SHA1.' % (bad_revision_in,)
1102 return results 1169 return results
1103 1170
1104 if good_revision is None: 1171 if good_revision is None:
1105 results['error'] = 'Could\'t resolve [%s] to SHA1.' % (good_revision_in,) 1172 results['error'] = 'Could\'t resolve [%s] to SHA1.' % (good_revision_in,)
1106 return results 1173 return results
1107 1174
1175 (bad_revision, good_revision) = self.NudgeRevisionsIfDEPSChange(
1176 bad_revision, good_revision)
1177
1108 if self.opts.output_buildbot_annotations: 1178 if self.opts.output_buildbot_annotations:
1109 bisect_utils.OutputAnnotationStepStart('Gathering Revisions') 1179 bisect_utils.OutputAnnotationStepStart('Gathering Revisions')
1110 1180
1111 print 'Gathering revision range for bisection.' 1181 print 'Gathering revision range for bisection.'
1112 1182
1113 # Retrieve a list of revisions to do bisection on. 1183 # Retrieve a list of revisions to do bisection on.
1114 src_revision_list = self.GetRevisionList(bad_revision, good_revision) 1184 src_revision_list = self.GetRevisionList(bad_revision, good_revision)
1115 1185
1116 if self.opts.output_buildbot_annotations: 1186 if self.opts.output_buildbot_annotations:
1117 bisect_utils.OutputAnnotationStepClosed() 1187 bisect_utils.OutputAnnotationStepClosed()
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 good_std_dev = revision_data[first_working_revision]['value']['std_dev'] 1443 good_std_dev = revision_data[first_working_revision]['value']['std_dev']
1374 good_mean = revision_data[first_working_revision]['value']['mean'] 1444 good_mean = revision_data[first_working_revision]['value']['mean']
1375 bad_mean = revision_data[last_broken_revision]['value']['mean'] 1445 bad_mean = revision_data[last_broken_revision]['value']['mean']
1376 1446
1377 # A standard deviation of 0 could indicate either insufficient runs 1447 # A standard deviation of 0 could indicate either insufficient runs
1378 # or a test that consistently returns the same value. 1448 # or a test that consistently returns the same value.
1379 if good_std_dev > 0: 1449 if good_std_dev > 0:
1380 deviations = math.fabs(bad_mean - good_mean) / good_std_dev 1450 deviations = math.fabs(bad_mean - good_mean) / good_std_dev
1381 1451
1382 if deviations < 1.5: 1452 if deviations < 1.5:
1383 print 'Warning: Regression was less than 1.5 standard deviations '\ 1453 self.warnings.append('Regression was less than 1.5 standard '
1384 'from "good" value. Results may not be accurate.' 1454 'deviations from "good" value. Results may not be accurate.')
1385 print
1386 elif self.opts.repeat_test_count == 1: 1455 elif self.opts.repeat_test_count == 1:
1387 print 'Warning: Tests were only set to run once. This may be '\ 1456 self.warnings.append('Tests were only set to run once. This '
1388 'insufficient to get meaningful results.' 1457 'may be insufficient to get meaningful results.')
1389 print
1390 1458
1391 # Check for any other possible regression ranges 1459 # Check for any other possible regression ranges
1392 prev_revision_data = revision_data_sorted[0][1] 1460 prev_revision_data = revision_data_sorted[0][1]
1393 prev_revision_id = revision_data_sorted[0][0] 1461 prev_revision_id = revision_data_sorted[0][0]
1394 possible_regressions = [] 1462 possible_regressions = []
1395 for current_id, current_data in revision_data_sorted: 1463 for current_id, current_data in revision_data_sorted:
1396 if current_data['value']: 1464 if current_data['value']:
1397 prev_mean = prev_revision_data['value']['mean'] 1465 prev_mean = prev_revision_data['value']['mean']
1398 cur_mean = current_data['value']['mean'] 1466 cur_mean = current_data['value']['mean']
1399 1467
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 if percent_change is None: 1508 if percent_change is None:
1441 percent_change = 0 1509 percent_change = 0
1442 1510
1443 print ' %8s %s [%.2f%%, %s x std.dev]' % ( 1511 print ' %8s %s [%.2f%%, %s x std.dev]' % (
1444 previous_data['depot'], previous_id, 100 * percent_change, 1512 previous_data['depot'], previous_id, 100 * percent_change,
1445 deviations) 1513 deviations)
1446 print ' %8s %s' % ( 1514 print ' %8s %s' % (
1447 current_data['depot'], current_id) 1515 current_data['depot'], current_id)
1448 print 1516 print
1449 1517
1518 if self.warnings:
1519 print
1520 print 'The following warnings were generated:'
1521 print
1522 for w in self.warnings:
1523 print ' - %s' % w
1524 print
1525
1450 if self.opts.output_buildbot_annotations: 1526 if self.opts.output_buildbot_annotations:
1451 bisect_utils.OutputAnnotationStepClosed() 1527 bisect_utils.OutputAnnotationStepClosed()
1452 1528
1453 1529
1454 def DetermineAndCreateSourceControl(): 1530 def DetermineAndCreateSourceControl():
1455 """Attempts to determine the underlying source control workflow and returns 1531 """Attempts to determine the underlying source control workflow and returns
1456 a SourceControl object. 1532 a SourceControl object.
1457 1533
1458 Returns: 1534 Returns:
1459 An instance of a SourceControl object, or None if the current workflow 1535 An instance of a SourceControl object, or None if the current workflow
1460 is unsupported. 1536 is unsupported.
1461 """ 1537 """
1462 1538
1463 (output, return_code) = RunGit(['rev-parse', '--is-inside-work-tree']) 1539 (output, return_code) = RunGit(['rev-parse', '--is-inside-work-tree'])
tonyg 2013/05/28 23:45:06 CheckRunGit?
shatch 2013/05/29 16:25:28 Prefer not to here, since a more descriptive error
1464 1540
1465 if output.strip() == 'true': 1541 if output.strip() == 'true':
1466 return GitSourceControl() 1542 return GitSourceControl()
1467 1543
1468 return None 1544 return None
1469 1545
1470 1546
1471 def SetNinjaBuildSystemDefault(): 1547 def SetNinjaBuildSystemDefault():
1472 """Makes ninja the default build system to be used by 1548 """Makes ninja the default build system to be used by
1473 the bisection script.""" 1549 the bisection script."""
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 1805
1730 if not(bisect_results['error']): 1806 if not(bisect_results['error']):
1731 return 0 1807 return 0
1732 else: 1808 else:
1733 print 'Error: ' + bisect_results['error'] 1809 print 'Error: ' + bisect_results['error']
1734 print 1810 print
1735 return 1 1811 return 1
1736 1812
1737 if __name__ == '__main__': 1813 if __name__ == '__main__':
1738 sys.exit(main()) 1814 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698