Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 # TODO(hinoka): Use logging. | 6 # TODO(hinoka): Use logging. |
| 7 | 7 |
| 8 import cStringIO | 8 import cStringIO |
| 9 import codecs | 9 import codecs |
| 10 import collections | 10 import collections |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 'src/native_client/': 'got_nacl_revision', | 160 'src/native_client/': 'got_nacl_revision', |
| 161 'src/tools/swarm_client/': 'got_swarm_client_revision', | 161 'src/tools/swarm_client/': 'got_swarm_client_revision', |
| 162 'src/tools/swarming_client/': 'got_swarming_client_revision', | 162 'src/tools/swarming_client/': 'got_swarming_client_revision', |
| 163 'src/third_party/WebKit/': 'got_webkit_revision', | 163 'src/third_party/WebKit/': 'got_webkit_revision', |
| 164 'src/third_party/webrtc/': 'got_webrtc_revision', | 164 'src/third_party/webrtc/': 'got_webrtc_revision', |
| 165 'src/v8/': 'got_v8_revision', | 165 'src/v8/': 'got_v8_revision', |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 BOT_UPDATE_MESSAGE = """ | |
| 171 What is the "Bot Update" step? | |
| 172 ============================== | |
| 173 | |
| 174 This step ensures that the source checkout on the bot (e.g. Chromium's src/ and | |
| 175 its dependencies) is checked out in a consistent state. This means that all of | |
| 176 the necessary repositories are checked out, no extra repositories are checked | |
| 177 out, and no locally modified files are present. | |
| 178 | |
| 179 These actions used to be taken care of by the "gclient revert" and "update" | |
| 180 steps. However, those steps are known to be buggy and occasionally flaky. This | |
| 181 step has two main advantages over them: | |
| 182 * it only operates in Git, so the logic can be clearer and cleaner; and | |
| 183 * it is a slave-side script, so its behavior can be modified without | |
| 184 restarting the master. | |
| 185 | |
| 186 Why Git, you ask? Because that is the direction that the Chromium project is | |
| 187 heading. This step is an integral part of the transition from using the SVN repo | |
| 188 at chrome/trunk/src to using the Git repo src.git. Please pardon the dust while | |
| 189 we fully convert everything to Git. This message will get out of your way | |
| 190 eventually, and the waterfall will be a happier place because of it. | |
| 191 | |
| 192 This step can be activated or deactivated independently on every builder on | |
| 193 every master. When it is active, the "gclient revert" and "update" steps become | |
| 194 no-ops. When it is inactive, it prints this message, cleans up after itself, and | |
| 195 lets everything else continue as though nothing has changed. Eventually, when | |
| 196 everything is stable enough, this step will replace them entirely. | |
| 197 | |
| 198 Debugging information: | |
| 199 (master/builder/slave may be unspecified on recipes) | |
| 200 master: %(master)s | |
| 201 builder: %(builder)s | |
| 202 slave: %(slave)s | |
| 203 forced by recipes: %(recipe)s | |
| 204 CURRENT_DIR: %(CURRENT_DIR)s | |
| 205 BUILDER_DIR: %(BUILDER_DIR)s | |
| 206 SLAVE_DIR: %(SLAVE_DIR)s | |
| 207 THIS_DIR: %(THIS_DIR)s | |
| 208 SCRIPTS_DIR: %(SCRIPTS_DIR)s | |
| 209 BUILD_DIR: %(BUILD_DIR)s | |
| 210 ROOT_DIR: %(ROOT_DIR)s | |
| 211 DEPOT_TOOLS_DIR: %(DEPOT_TOOLS_DIR)s | |
| 212 bot_update.py is:""" | |
| 213 | |
| 214 ACTIVATED_MESSAGE = """ACTIVE. | |
| 215 The bot will perform a Git checkout in this step. | |
| 216 The "gclient revert" and "update" steps are no-ops. | |
| 217 | |
| 218 """ | |
| 219 | |
| 220 NOT_ACTIVATED_MESSAGE = """INACTIVE. | |
| 221 This step does nothing. You actually want to look at the "update" step. | |
| 222 | |
| 223 """ | |
| 224 | |
| 225 | |
| 226 GCLIENT_TEMPLATE = """solutions = %(solutions)s | 170 GCLIENT_TEMPLATE = """solutions = %(solutions)s |
| 227 | 171 |
| 228 cache_dir = r%(cache_dir)s | 172 cache_dir = r%(cache_dir)s |
| 229 %(target_os)s | 173 %(target_os)s |
| 230 %(target_os_only)s | 174 %(target_os_only)s |
| 231 """ | 175 """ |
| 232 | 176 |
| 233 | 177 |
| 234 internal_data = {} | 178 internal_data = {} |
| 235 if BUILD_INTERNAL_DIR: | 179 if BUILD_INTERNAL_DIR: |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 248 # If SVN path matches key, the entire URL is rewritten to the Git url. | 192 # If SVN path matches key, the entire URL is rewritten to the Git url. |
| 249 '/chrome/trunk/src': | 193 '/chrome/trunk/src': |
| 250 CHROMIUM_SRC_URL, | 194 CHROMIUM_SRC_URL, |
| 251 '/chrome/trunk/src/tools/cros.DEPS': | 195 '/chrome/trunk/src/tools/cros.DEPS': |
| 252 CHROMIUM_GIT_HOST + '/chromium/src/tools/cros.DEPS.git', | 196 CHROMIUM_GIT_HOST + '/chromium/src/tools/cros.DEPS.git', |
| 253 '/chrome-internal/trunk/src-internal': | 197 '/chrome-internal/trunk/src-internal': |
| 254 'https://chrome-internal.googlesource.com/chrome/src-internal.git', | 198 'https://chrome-internal.googlesource.com/chrome/src-internal.git', |
| 255 } | 199 } |
| 256 RECOGNIZED_PATHS.update(internal_data.get('RECOGNIZED_PATHS', {})) | 200 RECOGNIZED_PATHS.update(internal_data.get('RECOGNIZED_PATHS', {})) |
| 257 | 201 |
| 258 ENABLED_MASTERS = [ | |
| 259 'bot_update.always_on', | |
| 260 'chromium.android', | |
| 261 'chromium.angle', | |
| 262 'chromium.chrome', | |
| 263 'chromium.chromedriver', | |
| 264 'chromium.chromiumos', | |
| 265 'chromium', | |
| 266 'chromium.fyi', | |
| 267 'chromium.goma', | |
| 268 'chromium.gpu', | |
| 269 'chromium.gpu.fyi', | |
| 270 'chromium.infra', | |
| 271 'chromium.infra.cron', | |
| 272 'chromium.linux', | |
| 273 'chromium.lkgr', | |
| 274 'chromium.mac', | |
| 275 'chromium.memory', | |
| 276 'chromium.memory.fyi', | |
| 277 'chromium.perf', | |
| 278 'chromium.perf.fyi', | |
| 279 'chromium.swarm', | |
| 280 'chromium.webkit', | |
| 281 'chromium.webrtc', | |
| 282 'chromium.webrtc.fyi', | |
| 283 'chromium.win', | |
| 284 'client.catapult', | |
| 285 'client.drmemory', | |
| 286 'client.mojo', | |
| 287 'client.nacl', | |
| 288 'client.nacl.ports', | |
| 289 'client.nacl.sdk', | |
| 290 'client.nacl.toolchain', | |
| 291 'client.pdfium', | |
| 292 'client.skia', | |
| 293 'client.skia.fyi', | |
| 294 'client.v8', | |
| 295 'client.v8.branches', | |
| 296 'client.v8.fyi', | |
| 297 'client.v8.ports', | |
| 298 'client.webrtc', | |
| 299 'client.webrtc.fyi', | |
| 300 'tryserver.blink', | |
| 301 'tryserver.client.catapult', | |
| 302 'tryserver.client.mojo', | |
| 303 'tryserver.chromium.android', | |
| 304 'tryserver.chromium.angle', | |
| 305 'tryserver.chromium.linux', | |
| 306 'tryserver.chromium.mac', | |
| 307 'tryserver.chromium.perf', | |
| 308 'tryserver.chromium.win', | |
| 309 'tryserver.infra', | |
| 310 'tryserver.nacl', | |
| 311 'tryserver.v8', | |
| 312 'tryserver.webrtc', | |
| 313 ] | |
| 314 ENABLED_MASTERS += internal_data.get('ENABLED_MASTERS', []) | |
| 315 | |
| 316 ENABLED_BUILDERS = { | |
| 317 'client.dart.fyi': [ | |
| 318 'v8-linux-release', | |
| 319 'v8-mac-release', | |
| 320 'v8-win-release', | |
| 321 ], | |
| 322 'client.dynamorio': [ | |
| 323 'linux-v8-dr', | |
| 324 ], | |
| 325 } | |
| 326 ENABLED_BUILDERS.update(internal_data.get('ENABLED_BUILDERS', {})) | |
| 327 | |
| 328 ENABLED_SLAVES = {} | |
| 329 ENABLED_SLAVES.update(internal_data.get('ENABLED_SLAVES', {})) | |
| 330 | |
| 331 # Disabled filters get run AFTER enabled filters, so for example if a builder | |
| 332 # config is enabled, but a bot on that builder is disabled, that bot will | |
| 333 # be disabled. | |
| 334 DISABLED_BUILDERS = {} | |
| 335 DISABLED_BUILDERS.update(internal_data.get('DISABLED_BUILDERS', {})) | |
| 336 | |
| 337 DISABLED_SLAVES = {} | |
| 338 DISABLED_SLAVES.update(internal_data.get('DISABLED_SLAVES', {})) | |
| 339 | |
| 340 # These masters work only in Git, meaning for got_revision, always output | |
| 341 # a git hash rather than a SVN rev. | |
| 342 GIT_MASTERS = [ | |
| 343 'client.v8', | |
| 344 'client.v8.branches', | |
| 345 'client.v8.ports', | |
| 346 'tryserver.v8', | |
| 347 ] | |
| 348 GIT_MASTERS += internal_data.get('GIT_MASTERS', []) | |
| 349 | |
| 350 | 202 |
| 351 # How many times to try before giving up. | 203 # How many times to try before giving up. |
| 352 ATTEMPTS = 5 | 204 ATTEMPTS = 5 |
| 353 | 205 |
| 354 GIT_CACHE_PATH = path.join(DEPOT_TOOLS_DIR, 'git_cache.py') | 206 GIT_CACHE_PATH = path.join(DEPOT_TOOLS_DIR, 'git_cache.py') |
| 355 | 207 |
| 356 # Find the patch tool. | 208 # Find the patch tool. |
| 357 if sys.platform.startswith('win'): | 209 if sys.platform.startswith('win'): |
| 358 if not BUILD_INTERNAL_DIR: | 210 if not BUILD_INTERNAL_DIR: |
| 359 print 'Warning: could not find patch tool because there is no ' | 211 print 'Warning: could not find patch tool because there is no ' |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 | 370 |
| 519 def get_gclient_spec(solutions, target_os, target_os_only, git_cache_dir): | 371 def get_gclient_spec(solutions, target_os, target_os_only, git_cache_dir): |
| 520 return GCLIENT_TEMPLATE % { | 372 return GCLIENT_TEMPLATE % { |
| 521 'solutions': pprint.pformat(solutions, indent=4), | 373 'solutions': pprint.pformat(solutions, indent=4), |
| 522 'cache_dir': '"%s"' % git_cache_dir, | 374 'cache_dir': '"%s"' % git_cache_dir, |
| 523 'target_os': ('\ntarget_os=%s' % target_os) if target_os else '', | 375 'target_os': ('\ntarget_os=%s' % target_os) if target_os else '', |
| 524 'target_os_only': '\ntarget_os_only=%s' % target_os_only | 376 'target_os_only': '\ntarget_os_only=%s' % target_os_only |
| 525 } | 377 } |
| 526 | 378 |
| 527 | 379 |
| 528 def check_enabled(master, builder, slave): | |
| 529 if master in ENABLED_MASTERS: | |
| 530 return True | |
| 531 builder_list = ENABLED_BUILDERS.get(master) | |
| 532 if builder_list and builder in builder_list: | |
| 533 return True | |
| 534 slave_list = ENABLED_SLAVES.get(master) | |
| 535 if slave_list and slave in slave_list: | |
| 536 return True | |
| 537 return False | |
| 538 | |
| 539 | |
| 540 def check_disabled(master, builder, slave): | |
| 541 """Returns True if disabled, False if not disabled.""" | |
| 542 builder_list = DISABLED_BUILDERS.get(master) | |
| 543 if builder_list and builder in builder_list: | |
| 544 return True | |
| 545 slave_list = DISABLED_SLAVES.get(master) | |
| 546 if slave_list and slave in slave_list: | |
| 547 return True | |
| 548 return False | |
| 549 | |
| 550 | |
| 551 def check_valid_host(master, builder, slave): | |
| 552 return (check_enabled(master, builder, slave) | |
| 553 and not check_disabled(master, builder, slave)) | |
| 554 | |
| 555 | |
| 556 def maybe_ignore_revision(revision, buildspec): | 380 def maybe_ignore_revision(revision, buildspec): |
| 557 """Handle builders that don't care what buildbot tells them to build. | 381 """Handle builders that don't care what buildbot tells them to build. |
| 558 | 382 |
| 559 This is especially the case with branch builders that build from buildspecs | 383 This is especially the case with branch builders that build from buildspecs |
| 560 and/or trigger off multiple repositories, where the --revision passed in has | 384 and/or trigger off multiple repositories, where the --revision passed in has |
| 561 nothing to do with the solution being built. Clearing the revision in this | 385 nothing to do with the solution being built. Clearing the revision in this |
| 562 case causes bot_update to use HEAD rather that trying to checkout an | 386 case causes bot_update to use HEAD rather that trying to checkout an |
| 563 inappropriate version of the solution. | 387 inappropriate version of the solution. |
| 564 """ | 388 """ |
| 565 if buildspec and buildspec.container == 'branches': | 389 if buildspec and buildspec.container == 'branches': |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1381 default='codereview.chromium.org', | 1205 default='codereview.chromium.org', |
| 1382 help='Rietveld server.') | 1206 help='Rietveld server.') |
| 1383 parse.add_option('--gerrit_repo', | 1207 parse.add_option('--gerrit_repo', |
| 1384 help='Gerrit repository to pull the ref from.') | 1208 help='Gerrit repository to pull the ref from.') |
| 1385 parse.add_option('--gerrit_ref', help='Gerrit ref to apply.') | 1209 parse.add_option('--gerrit_ref', help='Gerrit ref to apply.') |
| 1386 parse.add_option('--gerrit_no_rebase_patch_ref', action='store_true', | 1210 parse.add_option('--gerrit_no_rebase_patch_ref', action='store_true', |
| 1387 help='Bypass rebase of Gerrit patch ref after checkout.') | 1211 help='Bypass rebase of Gerrit patch ref after checkout.') |
| 1388 parse.add_option('--gerrit_no_reset', action='store_true', | 1212 parse.add_option('--gerrit_no_reset', action='store_true', |
| 1389 help='Bypass calling reset after applying a gerrit ref.') | 1213 help='Bypass calling reset after applying a gerrit ref.') |
| 1390 parse.add_option('--specs', help='Gcilent spec.') | 1214 parse.add_option('--specs', help='Gcilent spec.') |
| 1391 parse.add_option('--master', | |
| 1392 help='Master name. If specified and it is not in ' | |
| 1393 'bot_update\'s whitelist, bot_update will be noop.') | |
| 1394 parse.add_option('-f', '--force', action='store_true', | 1215 parse.add_option('-f', '--force', action='store_true', |
| 1395 help='Bypass check to see if we want to be run. ' | 1216 help='Bypass check to see if we want to be run. ' |
| 1396 'Should ONLY be used locally or by smart recipes.') | 1217 'Should ONLY be used locally or by smart recipes.') |
| 1397 parse.add_option('--revision_mapping', | 1218 parse.add_option('--revision_mapping', |
| 1398 help='{"path/to/repo/": "property_name"}') | 1219 help='{"path/to/repo/": "property_name"}') |
| 1399 parse.add_option('--revision_mapping_file', | 1220 parse.add_option('--revision_mapping_file', |
| 1400 help=('Same as revision_mapping, except its a path to a json' | 1221 help=('Same as revision_mapping, except its a path to a json' |
| 1401 ' file containing that format.')) | 1222 ' file containing that format.')) |
| 1402 parse.add_option('--revision', action='append', default=[], | 1223 parse.add_option('--revision', action='append', default=[], |
| 1403 help='Revision to check out. Can be an SVN revision number, ' | 1224 help='Revision to check out. Can be an SVN revision number, ' |
| 1404 'git hash, or any form of git ref. Can prepend ' | 1225 'git hash, or any form of git ref. Can prepend ' |
| 1405 'root@<rev> to specify which repository, where root ' | 1226 'root@<rev> to specify which repository, where root ' |
| 1406 'is either a filesystem path, git https url, or ' | 1227 'is either a filesystem path, git https url, or ' |
| 1407 'svn url. To specify Tip of Tree, set rev to HEAD.' | 1228 'svn url. To specify Tip of Tree, set rev to HEAD.' |
| 1408 'To specify a git branch and an SVN rev, <rev> can be ' | 1229 'To specify a git branch and an SVN rev, <rev> can be ' |
| 1409 'set to <branch>:<revision>.') | 1230 'set to <branch>:<revision>.') |
| 1410 parse.add_option('--output_manifest', action='store_true', | 1231 parse.add_option('--output_manifest', action='store_true', |
| 1411 help=('Add manifest json to the json output.')) | 1232 help=('Add manifest json to the json output.')) |
| 1412 parse.add_option('--slave_name', default=socket.getfqdn().split('.')[0], | 1233 parse.add_option('--slave_name', default=socket.getfqdn().split('.')[0], |
| 1413 help='Hostname of the current machine, ' | 1234 help='Hostname of the current machine, ' |
| 1414 'used for determining whether or not to activate.') | 1235 'used for determining whether or not to activate.') |
| 1415 parse.add_option('--builder_name', help='Name of the builder, ' | |
| 1416 'used for determining whether or not to activate.') | |
| 1417 parse.add_option('--build_dir', default=os.getcwd()) | 1236 parse.add_option('--build_dir', default=os.getcwd()) |
| 1418 parse.add_option('--flag_file', default=path.join(os.getcwd(), | 1237 parse.add_option('--flag_file', default=path.join(os.getcwd(), |
| 1419 'update.flag')) | 1238 'update.flag')) |
| 1420 parse.add_option('--shallow', action='store_true', | 1239 parse.add_option('--shallow', action='store_true', |
| 1421 help='Use shallow clones for cache repositories.') | 1240 help='Use shallow clones for cache repositories.') |
| 1422 parse.add_option('--gyp_env', action='append', default=[], | 1241 parse.add_option('--gyp_env', action='append', default=[], |
| 1423 help='Environment variables to pass into gclient runhooks.') | 1242 help='Environment variables to pass into gclient runhooks.') |
| 1424 parse.add_option('--clobber', action='store_true', | 1243 parse.add_option('--clobber', action='store_true', |
| 1425 help='Delete checkout first, always') | 1244 help='Delete checkout first, always') |
| 1426 parse.add_option('--bot_update_clobber', action='store_true', dest='clobber', | 1245 parse.add_option('--bot_update_clobber', action='store_true', dest='clobber', |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1478 def prepare(options, git_slns, active): | 1297 def prepare(options, git_slns, active): |
| 1479 """Prepares the target folder before we checkout.""" | 1298 """Prepares the target folder before we checkout.""" |
| 1480 dir_names = [sln.get('name') for sln in git_slns if 'name' in sln] | 1299 dir_names = [sln.get('name') for sln in git_slns if 'name' in sln] |
| 1481 # If we're active now, but the flag file doesn't exist (we weren't active | 1300 # If we're active now, but the flag file doesn't exist (we weren't active |
| 1482 # last run) or vice versa, blow away all checkouts. | 1301 # last run) or vice versa, blow away all checkouts. |
| 1483 if bool(active) != bool(check_flag(options.flag_file)): | 1302 if bool(active) != bool(check_flag(options.flag_file)): |
| 1484 ensure_no_checkout(dir_names, '*') | 1303 ensure_no_checkout(dir_names, '*') |
| 1485 if options.output_json: | 1304 if options.output_json: |
| 1486 # Make sure we tell recipes that we didn't run if the script exits here. | 1305 # Make sure we tell recipes that we didn't run if the script exits here. |
| 1487 emit_json(options.output_json, did_run=active) | 1306 emit_json(options.output_json, did_run=active) |
| 1488 if active: | 1307 if active: |
|
Ryan Tseng
2016/09/08 18:34:55
always active
| |
| 1489 if options.clobber: | 1308 if options.clobber: |
| 1490 ensure_no_checkout(dir_names, '*') | 1309 ensure_no_checkout(dir_names, '*') |
| 1491 else: | 1310 else: |
| 1492 ensure_no_checkout(dir_names, '.svn') | 1311 ensure_no_checkout(dir_names, '.svn') |
| 1493 emit_flag(options.flag_file) | 1312 emit_flag(options.flag_file) |
| 1494 else: | 1313 else: |
| 1495 delete_flag(options.flag_file) | 1314 delete_flag(options.flag_file) |
| 1496 raise Inactive # This is caught in main() and we exit cleanly. | 1315 raise Inactive # This is caught in main() and we exit cleanly. |
| 1497 | 1316 |
| 1498 # Do a shallow checkout if the disk is less than 100GB. | 1317 # Do a shallow checkout if the disk is less than 100GB. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1513 # The first solution is where the primary DEPS file resides. | 1332 # The first solution is where the primary DEPS file resides. |
| 1514 first_sln = dir_names[0] | 1333 first_sln = dir_names[0] |
| 1515 | 1334 |
| 1516 # Split all the revision specifications into a nice dict. | 1335 # Split all the revision specifications into a nice dict. |
| 1517 print 'Revisions: %s' % options.revision | 1336 print 'Revisions: %s' % options.revision |
| 1518 revisions = parse_revisions(options.revision, first_sln) | 1337 revisions = parse_revisions(options.revision, first_sln) |
| 1519 print 'Fetching Git checkout at %s@%s' % (first_sln, revisions[first_sln]) | 1338 print 'Fetching Git checkout at %s@%s' % (first_sln, revisions[first_sln]) |
| 1520 return revisions, step_text | 1339 return revisions, step_text |
| 1521 | 1340 |
| 1522 | 1341 |
| 1523 def checkout(options, git_slns, specs, buildspec, master, | 1342 def checkout(options, git_slns, specs, buildspec, |
| 1524 svn_root, revisions, step_text): | 1343 svn_root, revisions, step_text): |
| 1525 first_sln = git_slns[0]['name'] | 1344 first_sln = git_slns[0]['name'] |
| 1526 dir_names = [sln.get('name') for sln in git_slns if 'name' in sln] | 1345 dir_names = [sln.get('name') for sln in git_slns if 'name' in sln] |
| 1527 try: | 1346 try: |
| 1528 # Outer try is for catching patch failures and exiting gracefully. | 1347 # Outer try is for catching patch failures and exiting gracefully. |
| 1529 # Inner try is for catching gclient failures and retrying gracefully. | 1348 # Inner try is for catching gclient failures and retrying gracefully. |
| 1530 try: | 1349 try: |
| 1531 checkout_parameters = dict( | 1350 checkout_parameters = dict( |
| 1532 # First, pass in the base of what we want to check out. | 1351 # First, pass in the base of what we want to check out. |
| 1533 solutions=git_slns, | 1352 solutions=git_slns, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1576 patch_root=options.patch_root, | 1395 patch_root=options.patch_root, |
| 1577 patch_failure=True, | 1396 patch_failure=True, |
| 1578 step_text='%s PATCH FAILED' % step_text, | 1397 step_text='%s PATCH FAILED' % step_text, |
| 1579 fixed_revisions=revisions) | 1398 fixed_revisions=revisions) |
| 1580 else: | 1399 else: |
| 1581 # If we're not on recipes, tell annotator about our got_revisions. | 1400 # If we're not on recipes, tell annotator about our got_revisions. |
| 1582 emit_log_lines('patch error', e.output) | 1401 emit_log_lines('patch error', e.output) |
| 1583 print '@@@STEP_TEXT@%s PATCH FAILED@@@' % step_text | 1402 print '@@@STEP_TEXT@%s PATCH FAILED@@@' % step_text |
| 1584 raise | 1403 raise |
| 1585 | 1404 |
| 1586 # Revision is an svn revision, unless it's a git master. | 1405 use_svn_rev = False |
| 1587 use_svn_rev = master not in GIT_MASTERS | |
| 1588 | 1406 |
| 1589 # Take care of got_revisions outputs. | 1407 # Take care of got_revisions outputs. |
| 1590 revision_mapping = dict(GOT_REVISION_MAPPINGS.get(svn_root, {})) | 1408 revision_mapping = dict(GOT_REVISION_MAPPINGS.get(svn_root, {})) |
| 1591 if options.revision_mapping: | 1409 if options.revision_mapping: |
| 1592 revision_mapping.update(options.revision_mapping) | 1410 revision_mapping.update(options.revision_mapping) |
| 1593 | 1411 |
| 1594 # If the repo is not in the default GOT_REVISION_MAPPINGS and no | 1412 # If the repo is not in the default GOT_REVISION_MAPPINGS and no |
| 1595 # revision_mapping were specified on the command line then | 1413 # revision_mapping were specified on the command line then |
| 1596 # default to setting 'got_revision' based on the first solution. | 1414 # default to setting 'got_revision' based on the first solution. |
| 1597 if not revision_mapping: | 1415 if not revision_mapping: |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1616 patch_root=options.patch_root, | 1434 patch_root=options.patch_root, |
| 1617 step_text=step_text, | 1435 step_text=step_text, |
| 1618 fixed_revisions=revisions, | 1436 fixed_revisions=revisions, |
| 1619 properties=got_revisions, | 1437 properties=got_revisions, |
| 1620 manifest=manifest) | 1438 manifest=manifest) |
| 1621 else: | 1439 else: |
| 1622 # If we're not on recipes, tell annotator about our got_revisions. | 1440 # If we're not on recipes, tell annotator about our got_revisions. |
| 1623 emit_properties(got_revisions) | 1441 emit_properties(got_revisions) |
| 1624 | 1442 |
| 1625 | 1443 |
| 1626 def print_help_text(force, output_json, active, master, builder, slave): | 1444 def print_debug_info(): |
| 1627 """Print helpful messages to tell devs whats going on.""" | 1445 print "Debugging info:" |
| 1628 if force and output_json: | 1446 debug_params = { |
| 1629 recipe_force = 'Forced on by recipes' | |
| 1630 elif active and output_json: | |
| 1631 recipe_force = 'Off by recipes, but forced on by bot update' | |
| 1632 elif not active and output_json: | |
| 1633 recipe_force = 'Forced off by recipes' | |
| 1634 else: | |
| 1635 recipe_force = 'N/A. Was not called by recipes' | |
| 1636 | |
| 1637 print BOT_UPDATE_MESSAGE % { | |
| 1638 'master': master or 'Not specified', | |
| 1639 'builder': builder or 'Not specified', | |
| 1640 'slave': slave or 'Not specified', | |
| 1641 'recipe': recipe_force, | |
| 1642 'CURRENT_DIR': CURRENT_DIR, | 1447 'CURRENT_DIR': CURRENT_DIR, |
| 1643 'BUILDER_DIR': BUILDER_DIR, | 1448 'BUILDER_DIR': BUILDER_DIR, |
| 1644 'SLAVE_DIR': SLAVE_DIR, | 1449 'SLAVE_DIR': SLAVE_DIR, |
| 1645 'THIS_DIR': THIS_DIR, | 1450 'THIS_DIR': THIS_DIR, |
| 1646 'SCRIPTS_DIR': SCRIPTS_DIR, | 1451 'SCRIPTS_DIR': SCRIPTS_DIR, |
| 1647 'BUILD_DIR': BUILD_DIR, | 1452 'BUILD_DIR': BUILD_DIR, |
| 1648 'ROOT_DIR': ROOT_DIR, | 1453 'ROOT_DIR': ROOT_DIR, |
| 1649 'DEPOT_TOOLS_DIR': DEPOT_TOOLS_DIR, | 1454 'DEPOT_TOOLS_DIR': DEPOT_TOOLS_DIR, |
| 1650 }, | 1455 }, |
| 1651 print ACTIVATED_MESSAGE if active else NOT_ACTIVATED_MESSAGE | 1456 for k, v in sorted(debug_params.iteritems()): |
| 1457 print "%s: %r" % (k, v) | |
| 1652 | 1458 |
| 1653 | 1459 |
| 1654 def main(): | 1460 def main(): |
| 1655 # Get inputs. | 1461 # Get inputs. |
| 1656 options, _ = parse_args() | 1462 options, _ = parse_args() |
| 1657 builder = options.builder_name | |
| 1658 slave = options.slave_name | |
| 1659 master = options.master | |
| 1660 | 1463 |
| 1661 # Always run. This option will be removed in a later CL, but for now make sure | 1464 # Always run. This option will be removed in a later CL, but for now make sure |
| 1662 # that bot_update is ALWAYS set to run, no matter what. | 1465 # that bot_update is ALWAYS set to run, no matter what. |
| 1663 options.force = True | 1466 options.force = True |
| 1664 | 1467 |
| 1665 # Check if this script should activate or not. | 1468 # Check if this script should activate or not. |
| 1666 active = options.force or check_valid_host(master, builder, slave) | 1469 active = True |
| 1667 | 1470 |
| 1668 # Print a helpful message to tell developers whats going on with this step. | 1471 # Print a helpful message to tell developers whats going on with this step. |
| 1669 print_help_text( | 1472 print_debug_info() |
| 1670 options.force, options.output_json, active, master, builder, slave) | |
| 1671 | 1473 |
| 1672 # Parse, munipulate, and print the gclient solutions. | 1474 # Parse, munipulate, and print the gclient solutions. |
| 1673 specs = {} | 1475 specs = {} |
| 1674 exec(options.specs, specs) | 1476 exec(options.specs, specs) |
| 1675 svn_solutions = specs.get('solutions', []) | 1477 svn_solutions = specs.get('solutions', []) |
| 1676 git_slns, svn_root, buildspec = solutions_to_git(svn_solutions) | 1478 git_slns, svn_root, buildspec = solutions_to_git(svn_solutions) |
| 1677 options.revision = maybe_ignore_revision(options.revision, buildspec) | 1479 options.revision = maybe_ignore_revision(options.revision, buildspec) |
| 1678 | 1480 |
| 1679 solutions_printer(git_slns) | 1481 solutions_printer(git_slns) |
| 1680 | 1482 |
| 1681 try: | 1483 try: |
| 1682 # Dun dun dun, the main part of bot_update. | 1484 # Dun dun dun, the main part of bot_update. |
| 1683 revisions, step_text = prepare(options, git_slns, active) | 1485 revisions, step_text = prepare(options, git_slns, active) |
| 1684 checkout(options, git_slns, specs, buildspec, master, svn_root, revisions, | 1486 checkout(options, git_slns, specs, buildspec, svn_root, revisions, |
| 1685 step_text) | 1487 step_text) |
| 1686 | 1488 |
| 1687 except Inactive: | 1489 except Inactive: |
|
Ryan Tseng
2016/09/08 18:34:54
not used
iannucci
2016/09/08 18:39:05
Yeah, I want to clean these things up in a future
| |
| 1688 # Not active, should count as passing. | 1490 # Not active, should count as passing. |
| 1689 pass | 1491 pass |
| 1690 except PatchFailed as e: | 1492 except PatchFailed as e: |
| 1691 emit_flag(options.flag_file) | 1493 emit_flag(options.flag_file) |
| 1692 # Return a specific non-zero exit code for patch failure (because it is | 1494 # Return a specific non-zero exit code for patch failure (because it is |
| 1693 # a failure), but make it different than other failures to distinguish | 1495 # a failure), but make it different than other failures to distinguish |
| 1694 # between infra failures (independent from patch author), and patch | 1496 # between infra failures (independent from patch author), and patch |
| 1695 # failures (that patch author can fix). However, PatchFailure due to | 1497 # failures (that patch author can fix). However, PatchFailure due to |
| 1696 # download patch failure is still an infra problem. | 1498 # download patch failure is still an infra problem. |
| 1697 if e.code == 3: | 1499 if e.code == 3: |
| 1698 # Patch download problem. | 1500 # Patch download problem. |
| 1699 return 87 | 1501 return 87 |
| 1700 # Genuine patch problem. | 1502 # Genuine patch problem. |
| 1701 return 88 | 1503 return 88 |
| 1702 except Exception: | 1504 except Exception: |
| 1703 # Unexpected failure. | 1505 # Unexpected failure. |
| 1704 emit_flag(options.flag_file) | 1506 emit_flag(options.flag_file) |
| 1705 raise | 1507 raise |
| 1706 else: | 1508 else: |
| 1707 emit_flag(options.flag_file) | 1509 emit_flag(options.flag_file) |
| 1708 | 1510 |
| 1709 | 1511 |
| 1710 if __name__ == '__main__': | 1512 if __name__ == '__main__': |
| 1711 sys.exit(main()) | 1513 sys.exit(main()) |
| OLD | NEW |