| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Fetches a copy of the latest state of a W3C test repository and commits. | 5 """Fetches a copy of the latest state of a W3C test repository and commits. |
| 6 | 6 |
| 7 If this script is given the argument --auto-update, it will also: | 7 If this script is given the argument --auto-update, it will also: |
| 8 1. Upload a CL. | 8 1. Upload a CL. |
| 9 2. Trigger try jobs and wait for them to complete. | 9 2. Trigger try jobs and wait for them to complete. |
| 10 3. Make any changes that are required for new failing tests. | 10 3. Make any changes that are required for new failing tests. |
| 11 4. Commit the CL. | 11 4. Commit the CL. |
| 12 | 12 |
| 13 If this script is given the argument --auto-update, it will also attempt to | 13 If this script is given the argument --auto-update, it will also attempt to |
| 14 upload a CL, trigger try jobs, and make any changes that are required for | 14 upload a CL, trigger try jobs, and make any changes that are required for |
| 15 new failing tests before committing. | 15 new failing tests before committing. |
| 16 """ | 16 """ |
| 17 | 17 |
| 18 import argparse | 18 import argparse |
| 19 import json | 19 import json |
| 20 import logging | 20 import logging |
| 21 import re | 21 import re |
| 22 | 22 |
| 23 from webkitpy.common.net.git_cl import GitCL | 23 from webkitpy.common.net.git_cl import GitCL |
| 24 from webkitpy.common.webkit_finder import WebKitFinder | 24 from webkitpy.common.webkit_finder import WebKitFinder |
| 25 from webkitpy.layout_tests.models.test_expectations import TestExpectations, Tes
tExpectationParser | 25 from webkitpy.layout_tests.models.test_expectations import TestExpectations, Tes
tExpectationParser |
| 26 from webkitpy.w3c.common import WPT_REPO_URL, CSS_REPO_URL, WPT_DEST_NAME, CSS_D
EST_NAME |
| 27 from webkitpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor |
| 28 from webkitpy.w3c.test_importer import TestImporter |
| 26 from webkitpy.w3c.update_w3c_test_expectations import W3CExpectationsLineAdder | 29 from webkitpy.w3c.update_w3c_test_expectations import W3CExpectationsLineAdder |
| 27 from webkitpy.w3c.test_importer import TestImporter | 30 |
| 28 from webkitpy.w3c.common import WPT_REPO_URL, CSS_REPO_URL, WPT_DEST_NAME, CSS_D
EST_NAME | |
| 29 | 31 |
| 30 # Settings for how often to check try job results and how long to wait. | 32 # Settings for how often to check try job results and how long to wait. |
| 31 POLL_DELAY_SECONDS = 2 * 60 | 33 POLL_DELAY_SECONDS = 2 * 60 |
| 32 TIMEOUT_SECONDS = 180 * 60 | 34 TIMEOUT_SECONDS = 180 * 60 |
| 33 | 35 |
| 34 _log = logging.getLogger(__file__) | 36 _log = logging.getLogger(__file__) |
| 35 | 37 |
| 36 | 38 |
| 37 class DepsUpdater(object): | 39 class DepsUpdater(object): |
| 38 | 40 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if self.git_cl.has_failing_try_results(try_results): | 319 if self.git_cl.has_failing_try_results(try_results): |
| 318 _log.info('CQ failed; aborting.') | 320 _log.info('CQ failed; aborting.') |
| 319 self.git_cl.run(['set-close']) | 321 self.git_cl.run(['set-close']) |
| 320 return False | 322 return False |
| 321 | 323 |
| 322 _log.info('Update completed.') | 324 _log.info('Update completed.') |
| 323 return True | 325 return True |
| 324 | 326 |
| 325 def _upload_cl(self): | 327 def _upload_cl(self): |
| 326 _log.info('Uploading change list.') | 328 _log.info('Uploading change list.') |
| 327 cc_list = self.get_directory_owners_to_cc() | 329 cc_list = self.get_directory_owners() |
| 328 description = self._cl_description() | 330 description = self._cl_description() |
| 329 self.git_cl.run([ | 331 self.git_cl.run([ |
| 330 'upload', | 332 'upload', |
| 331 '-f', | 333 '-f', |
| 332 '--rietveld', | 334 '--rietveld', |
| 333 '-m', | 335 '-m', |
| 334 description, | 336 description, |
| 335 ] + ['--cc=' + email for email in cc_list]) | 337 ] + ['--cc=' + email for email in cc_list]) |
| 336 | 338 |
| 339 def get_directory_owners(self): |
| 340 """Returns a list of email addresses of owners of changed tests.""" |
| 341 _log.info('Gathering directory owners emails to CC.') |
| 342 changed_files = self.host.cwd().changed_files() |
| 343 extractor = DirectoryOwnersExtractor(self.fs) |
| 344 extractor.read_owner_map() |
| 345 return extractor.list_owners(changed_files) |
| 346 |
| 337 def _cl_description(self): | 347 def _cl_description(self): |
| 338 description = self.check_run(['git', 'log', '-1', '--format=%B']) | 348 description = self.check_run(['git', 'log', '-1', '--format=%B']) |
| 339 build_link = self._build_link() | 349 build_link = self._build_link() |
| 340 if build_link: | 350 if build_link: |
| 341 description += 'Build: %s\n\n' % build_link | 351 description += 'Build: %s\n\n' % build_link |
| 342 description += 'TBR=qyearsley@chromium.org\n' | 352 description += 'TBR=qyearsley@chromium.org\n' |
| 343 # Move any NOEXPORT tag to the end of the description. | 353 # Move any NOEXPORT tag to the end of the description. |
| 344 description = description.replace('NOEXPORT=true', '') | 354 description = description.replace('NOEXPORT=true', '') |
| 345 description = description.replace('\n\n\n\n', '\n\n') | 355 description = description.replace('\n\n\n\n', '\n\n') |
| 346 description += 'NOEXPORT=true' | 356 description += 'NOEXPORT=true' |
| 347 return description | 357 return description |
| 348 | 358 |
| 349 def _build_link(self): | 359 def _build_link(self): |
| 350 """Returns a link to a job, if running on buildbot.""" | 360 """Returns a link to a job, if running on buildbot.""" |
| 351 master_name = self.host.environ.get('BUILDBOT_MASTERNAME') | 361 master_name = self.host.environ.get('BUILDBOT_MASTERNAME') |
| 352 builder_name = self.host.environ.get('BUILDBOT_BUILDERNAME') | 362 builder_name = self.host.environ.get('BUILDBOT_BUILDERNAME') |
| 353 build_number = self.host.environ.get('BUILDBOT_BUILDNUMBER') | 363 build_number = self.host.environ.get('BUILDBOT_BUILDNUMBER') |
| 354 if not (master_name and builder_name and build_number): | 364 if not (master_name and builder_name and build_number): |
| 355 return None | 365 return None |
| 356 return 'https://build.chromium.org/p/%s/builders/%s/builds/%s' % (master
_name, builder_name, build_number) | 366 return 'https://build.chromium.org/p/%s/builders/%s/builds/%s' % (master
_name, builder_name, build_number) |
| 357 | 367 |
| 358 def get_directory_owners_to_cc(self): | |
| 359 """Returns a list of email addresses to CC for the current import.""" | |
| 360 _log.info('Gathering directory owners emails to CC.') | |
| 361 directory_owners_file_path = self.finder.path_from_webkit_base( | |
| 362 'Tools', 'Scripts', 'webkitpy', 'w3c', 'directory_owners.json') | |
| 363 with open(directory_owners_file_path) as data_file: | |
| 364 directory_to_owner = self.parse_directory_owners(json.load(data_file
)) | |
| 365 out = self.check_run(['git', 'diff', 'origin/master', '--name-only']) | |
| 366 changed_files = out.splitlines() | |
| 367 return self.generate_email_list(changed_files, directory_to_owner) | |
| 368 | |
| 369 @staticmethod | 368 @staticmethod |
| 370 def parse_directory_owners(decoded_data_file): | 369 def parse_directory_owners(decoded_data_file): |
| 371 directory_dict = {} | 370 directory_dict = {} |
| 372 for dict_set in decoded_data_file: | 371 for dict_set in decoded_data_file: |
| 373 if dict_set['notification-email']: | 372 if dict_set['notification-email']: |
| 374 directory_dict[dict_set['directory']] = dict_set['notification-e
mail'] | 373 directory_dict[dict_set['directory']] = dict_set['notification-e
mail'] |
| 375 return directory_dict | 374 return directory_dict |
| 376 | 375 |
| 377 def generate_email_list(self, changed_files, directory_to_owner): | 376 def generate_email_list(self, changed_files, directory_to_owner): |
| 378 """Returns a list of email addresses based on the given file list and | 377 """Returns a list of email addresses based on the given file list and |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 """Returns a dict mapping source to dest name for layout tests that have
been renamed.""" | 450 """Returns a dict mapping source to dest name for layout tests that have
been renamed.""" |
| 452 out = self.check_run(['git', 'diff', 'origin/master', '-M100%', '--diff-
filter=R', '--name-status']) | 451 out = self.check_run(['git', 'diff', 'origin/master', '-M100%', '--diff-
filter=R', '--name-status']) |
| 453 renamed_tests = {} | 452 renamed_tests = {} |
| 454 for line in out.splitlines(): | 453 for line in out.splitlines(): |
| 455 _, source_path, dest_path = line.split() | 454 _, source_path, dest_path = line.split() |
| 456 source_test = self.finder.layout_test_name(source_path) | 455 source_test = self.finder.layout_test_name(source_path) |
| 457 dest_test = self.finder.layout_test_name(dest_path) | 456 dest_test = self.finder.layout_test_name(dest_path) |
| 458 if source_test and dest_test: | 457 if source_test and dest_test: |
| 459 renamed_tests[source_test] = dest_test | 458 renamed_tests[source_test] = dest_test |
| 460 return renamed_tests | 459 return renamed_tests |
| OLD | NEW |