| OLD | NEW |
| 1 # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 1 # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions | 4 # modification, are permitted provided that the following conditions |
| 5 # are met: | 5 # are met: |
| 6 # | 6 # |
| 7 # 1. Redistributions of source code must retain the above | 7 # 1. Redistributions of source code must retain the above |
| 8 # copyright notice, this list of conditions and the following | 8 # copyright notice, this list of conditions and the following |
| 9 # disclaimer. | 9 # disclaimer. |
| 10 # 2. Redistributions in binary form must reproduce the above | 10 # 2. Redistributions in binary form must reproduce the above |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 self.top_of_repo = top_of_repo | 159 self.top_of_repo = top_of_repo |
| 160 self.options = options | 160 self.options = options |
| 161 | 161 |
| 162 self.filesystem = self.host.filesystem | 162 self.filesystem = self.host.filesystem |
| 163 self.webkit_finder = WebKitFinder(self.filesystem) | 163 self.webkit_finder = WebKitFinder(self.filesystem) |
| 164 self._webkit_root = self.webkit_finder.webkit_base() | 164 self._webkit_root = self.webkit_finder.webkit_base() |
| 165 self.layout_tests_dir = self.webkit_finder.path_from_webkit_base('Layout
Tests') | 165 self.layout_tests_dir = self.webkit_finder.path_from_webkit_base('Layout
Tests') |
| 166 self.destination_directory = self.filesystem.normpath(self.filesystem.jo
in(self.layout_tests_dir, options.destination, | 166 self.destination_directory = self.filesystem.normpath(self.filesystem.jo
in(self.layout_tests_dir, options.destination, |
| 167
self.filesystem.basename(self.top_of_repo))) | 167
self.filesystem.basename(self.top_of_repo))) |
| 168 self.import_in_place = (self.dir_to_import == self.destination_directory
) | 168 self.import_in_place = (self.dir_to_import == self.destination_directory
) |
| 169 self.dir_above_repo = self.filesystem.dirname(self.top_of_repo) |
| 169 | 170 |
| 170 self.changeset = CHANGESET_NOT_AVAILABLE | 171 self.changeset = CHANGESET_NOT_AVAILABLE |
| 171 | 172 |
| 172 self.import_list = [] | 173 self.import_list = [] |
| 173 | 174 |
| 174 def do_import(self): | 175 def do_import(self): |
| 175 _log.info("Importing %s into %s", self.dir_to_import, self.destination_d
irectory) | 176 _log.info("Importing %s into %s", self.dir_to_import, self.destination_d
irectory) |
| 176 self.find_importable_tests(self.dir_to_import) | 177 self.find_importable_tests(self.dir_to_import) |
| 177 self.load_changeset() | 178 self.load_changeset() |
| 178 self.import_tests() | 179 self.import_tests() |
| 179 | 180 |
| 180 def load_changeset(self): | 181 def load_changeset(self): |
| 181 """Returns the current changeset from mercurial or "Not Available".""" | 182 """Returns the current changeset from mercurial or "Not Available".""" |
| 182 try: | 183 try: |
| 183 self.changeset = self.host.executive.run_command(['hg', 'tip']).spli
t('changeset:')[1] | 184 self.changeset = self.host.executive.run_command(['hg', 'tip']).spli
t('changeset:')[1] |
| 184 except (OSError, ScriptError): | 185 except (OSError, ScriptError): |
| 185 self.changeset = CHANGESET_NOT_AVAILABLE | 186 self.changeset = CHANGESET_NOT_AVAILABLE |
| 186 | 187 |
| 187 def find_importable_tests(self, directory): | 188 def find_importable_tests(self, directory): |
| 188 # FIXME: use filesystem | 189 # FIXME: use filesystem |
| 189 paths_to_skip = self.find_paths_to_skip() | 190 paths_to_skip = self.find_paths_to_skip() |
| 190 | 191 |
| 191 for root, dirs, files in os.walk(directory): | 192 for root, dirs, files in os.walk(directory): |
| 192 cur_dir = root.replace(self.layout_tests_dir + '/', '') + '/' | 193 cur_dir = root.replace(self.dir_above_repo + '/', '') + '/' |
| 193 _log.info(' scanning ' + cur_dir + '...') | 194 _log.info(' scanning ' + cur_dir + '...') |
| 194 total_tests = 0 | 195 total_tests = 0 |
| 195 reftests = 0 | 196 reftests = 0 |
| 196 jstests = 0 | 197 jstests = 0 |
| 197 | 198 |
| 198 DIRS_TO_SKIP = ('.git', '.hg') | 199 DIRS_TO_SKIP = ('.git', '.hg') |
| 199 if dirs: | 200 if dirs: |
| 200 for d in DIRS_TO_SKIP: | 201 for d in DIRS_TO_SKIP: |
| 201 if d in dirs: | 202 if d in dirs: |
| 202 dirs.remove(d) | 203 dirs.remove(d) |
| 203 | 204 |
| 204 for path in paths_to_skip: | 205 for path in paths_to_skip: |
| 205 path_base = path.replace(cur_dir, '') | 206 path_base = path.replace(self.options.destination + '/', '') |
| 207 path_base = path_base.replace(cur_dir, '') |
| 206 path_full = self.filesystem.join(root, path_base) | 208 path_full = self.filesystem.join(root, path_base) |
| 207 if path_base in dirs: | 209 if path_base in dirs: |
| 208 dirs.remove(path_base) | 210 dirs.remove(path_base) |
| 209 if not self.options.dry_run and self.import_in_place: | 211 if not self.options.dry_run and self.import_in_place: |
| 210 _log.info(" pruning %s" % path_base) | 212 _log.info(" pruning %s" % path_base) |
| 211 self.filesystem.rmtree(path_full) | 213 self.filesystem.rmtree(path_full) |
| 214 else: |
| 215 _log.info(" skipping %s" % path_base) |
| 216 |
| 212 | 217 |
| 213 copy_list = [] | 218 copy_list = [] |
| 214 | 219 |
| 215 for filename in files: | 220 for filename in files: |
| 216 path_full = self.filesystem.join(root, filename) | 221 path_full = self.filesystem.join(root, filename) |
| 217 path_base = path_full.replace(self.layout_tests_dir + '/', '') | 222 path_base = path_full.replace(self.layout_tests_dir + '/', '') |
| 218 if path_base in paths_to_skip: | 223 if path_base in paths_to_skip: |
| 219 if not self.options.dry_run and self.import_in_place: | 224 if not self.options.dry_run and self.import_in_place: |
| 220 _log.info(" pruning %s" % path_base) | 225 _log.info(" pruning %s" % path_base) |
| 221 self.filesystem.remove(path_full) | 226 self.filesystem.remove(path_full) |
| 222 continue | 227 continue |
| 228 else: |
| 229 continue |
| 223 # FIXME: This block should really be a separate function, but th
e early-continues make that difficult. | 230 # FIXME: This block should really be a separate function, but th
e early-continues make that difficult. |
| 224 | 231 |
| 225 if filename.startswith('.') or filename.endswith('.pl'): | 232 if filename.startswith('.') or filename.endswith('.pl'): |
| 226 continue # For some reason the w3c repo contains random per
l scripts we don't care about. | 233 continue # For some reason the w3c repo contains random per
l scripts we don't care about. |
| 227 | 234 |
| 228 fullpath = os.path.join(root, filename) | 235 fullpath = os.path.join(root, filename) |
| 229 | 236 |
| 230 mimetype = mimetypes.guess_type(fullpath) | 237 mimetype = mimetypes.guess_type(fullpath) |
| 231 if not 'html' in str(mimetype[0]) and not 'application/xhtml+xml
' in str(mimetype[0]) and not 'application/xml' in str(mimetype[0]): | 238 if not 'html' in str(mimetype[0]) and not 'application/xhtml+xml
' in str(mimetype[0]) and not 'application/xml' in str(mimetype[0]): |
| 232 copy_list.append({'src': fullpath, 'dest': filename}) | 239 copy_list.append({'src': fullpath, 'dest': filename}) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 if not(os.path.exists(orig_filepath)): | 350 if not(os.path.exists(orig_filepath)): |
| 344 _log.warning('%s not found. Possible error in the test.', or
ig_filepath) | 351 _log.warning('%s not found. Possible error in the test.', or
ig_filepath) |
| 345 continue | 352 continue |
| 346 | 353 |
| 347 new_filepath = os.path.join(new_path, file_to_copy['dest']) | 354 new_filepath = os.path.join(new_path, file_to_copy['dest']) |
| 348 | 355 |
| 349 if not(os.path.exists(os.path.dirname(new_filepath))): | 356 if not(os.path.exists(os.path.dirname(new_filepath))): |
| 350 if not self.import_in_place and not self.options.dry_run: | 357 if not self.import_in_place and not self.options.dry_run: |
| 351 os.makedirs(os.path.dirname(new_filepath)) | 358 os.makedirs(os.path.dirname(new_filepath)) |
| 352 | 359 |
| 360 relpath = os.path.relpath(new_filepath, self.layout_tests_dir) |
| 353 if not self.options.overwrite and os.path.exists(new_filepath): | 361 if not self.options.overwrite and os.path.exists(new_filepath): |
| 354 _log.info(' skipping import of existing file ' + new_filepa
th) | 362 _log.info(' skipping %s' % relpath) |
| 355 else: | 363 else: |
| 356 # FIXME: Maybe doing a file diff is in order here for existi
ng files? | 364 # FIXME: Maybe doing a file diff is in order here for existi
ng files? |
| 357 # In other words, there's no sense in overwriting identical
files, but | 365 # In other words, there's no sense in overwriting identical
files, but |
| 358 # there's no harm in copying the identical thing. | 366 # there's no harm in copying the identical thing. |
| 359 _log.info(' importing %s', os.path.relpath(new_filepath, se
lf.layout_tests_dir)) | 367 _log.info(' %s' % relpath) |
| 360 | 368 |
| 361 # Only html, xml, or css should be converted | 369 # Only html, xml, or css should be converted |
| 362 # FIXME: Eventually, so should js when support is added for this
type of conversion | 370 # FIXME: Eventually, so should js when support is added for this
type of conversion |
| 363 mimetype = mimetypes.guess_type(orig_filepath) | 371 mimetype = mimetypes.guess_type(orig_filepath) |
| 364 if 'html' in str(mimetype[0]) or 'xml' in str(mimetype[0]) or '
css' in str(mimetype[0]): | 372 if 'html' in str(mimetype[0]) or 'xml' in str(mimetype[0]) or '
css' in str(mimetype[0]): |
| 365 converted_file = convert_for_webkit(new_path, filename=orig_
filepath) | 373 converted_file = convert_for_webkit(new_path, filename=orig_
filepath) |
| 366 | 374 |
| 367 if not converted_file: | 375 if not converted_file: |
| 368 if not self.import_in_place and not self.options.dry_run
: | 376 if not self.import_in_place and not self.options.dry_run
: |
| 369 shutil.copyfile(orig_filepath, new_filepath) # The
file was unmodified. | 377 shutil.copyfile(orig_filepath, new_filepath) # The
file was unmodified. |
| 370 else: | 378 else: |
| 371 for prefixed_property in converted_file[0]: | 379 for prefixed_property in converted_file[0]: |
| 372 total_prefixed_properties.setdefault(prefixed_proper
ty, 0) | 380 total_prefixed_properties.setdefault(prefixed_proper
ty, 0) |
| 373 total_prefixed_properties[prefixed_property] += 1 | 381 total_prefixed_properties[prefixed_property] += 1 |
| 374 | 382 |
| 375 prefixed_properties.extend(set(converted_file[0]) - set(
prefixed_properties)) | 383 prefixed_properties.extend(set(converted_file[0]) - set(
prefixed_properties)) |
| 376 if not self.options.dry_run: | 384 if not self.options.dry_run: |
| 377 outfile = open(new_filepath, 'wb') | 385 outfile = open(new_filepath, 'wb') |
| 378 outfile.write(converted_file[1]) | 386 outfile.write(converted_file[1]) |
| 379 outfile.close() | 387 outfile.close() |
| 380 else: | 388 else: |
| 381 if not self.import_in_place and not self.options.dry_run: | 389 if not self.import_in_place and not self.options.dry_run: |
| 382 shutil.copyfile(orig_filepath, new_filepath) | 390 shutil.copyfile(orig_filepath, new_filepath) |
| 383 | 391 |
| 384 copied_files.append(new_filepath.replace(self._webkit_root, '')) | 392 copied_files.append(new_filepath.replace(self._webkit_root, '')) |
| 385 | 393 |
| 386 if not self.import_in_place and not self.options.dry_run: | |
| 387 self.remove_deleted_files(new_path, copied_files) | |
| 388 self.write_import_log(new_path, copied_files, prefixed_propertie
s) | |
| 389 | |
| 390 _log.info('') | 394 _log.info('') |
| 391 _log.info('Import complete') | 395 _log.info('Import complete') |
| 392 _log.info('') | 396 _log.info('') |
| 393 _log.info('IMPORTED %d TOTAL TESTS', total_imported_tests) | 397 _log.info('IMPORTED %d TOTAL TESTS', total_imported_tests) |
| 394 _log.info('Imported %d reftests', total_imported_reftests) | 398 _log.info('Imported %d reftests', total_imported_reftests) |
| 395 _log.info('Imported %d JS tests', total_imported_jstests) | 399 _log.info('Imported %d JS tests', total_imported_jstests) |
| 396 _log.info('Imported %d pixel/manual tests', total_imported_tests - total
_imported_jstests - total_imported_reftests) | 400 _log.info('Imported %d pixel/manual tests', total_imported_tests - total
_imported_jstests - total_imported_reftests) |
| 397 _log.info('') | 401 _log.info('') |
| 398 _log.info('Properties needing prefixes (by count):') | 402 |
| 399 for prefixed_property in sorted(total_prefixed_properties, key=lambda p:
total_prefixed_properties[p]): | 403 if total_prefixed_properties: |
| 400 _log.info(' %s: %s', prefixed_property, total_prefixed_properties[p
refixed_property]) | 404 _log.info('Properties needing prefixes (by count):') |
| 405 for prefixed_property in sorted(total_prefixed_properties, key=lambd
a p: total_prefixed_properties[p]): |
| 406 _log.info(' %s: %s', prefixed_property, total_prefixed_properti
es[prefixed_property]) |
| 401 | 407 |
| 402 def setup_destination_directory(self): | 408 def setup_destination_directory(self): |
| 403 """ Creates a destination directory that mirrors that of the source dire
ctory """ | 409 """ Creates a destination directory that mirrors that of the source dire
ctory """ |
| 404 | 410 |
| 405 new_subpath = self.dir_to_import[len(self.top_of_repo):] | 411 new_subpath = self.dir_to_import[len(self.top_of_repo):] |
| 406 | 412 |
| 407 destination_directory = os.path.join(self.destination_directory, new_sub
path) | 413 destination_directory = os.path.join(self.destination_directory, new_sub
path) |
| 408 | 414 |
| 409 if not os.path.exists(destination_directory): | 415 if not os.path.exists(destination_directory): |
| 410 os.makedirs(destination_directory) | 416 os.makedirs(destination_directory) |
| 411 | 417 |
| 412 _log.info('Tests will be imported into: %s', destination_directory) | 418 _log.info('Tests will be imported into: %s', destination_directory) |
| 413 | |
| 414 def remove_deleted_files(self, dir_to_import, new_file_list): | |
| 415 previous_file_list = [] | |
| 416 | |
| 417 import_log_file = os.path.join(dir_to_import, 'w3c-import.log') | |
| 418 if not os.path.exists(import_log_file): | |
| 419 return | |
| 420 | |
| 421 import_log = open(import_log_file, 'r') | |
| 422 contents = import_log.readlines() | |
| 423 | |
| 424 if 'List of files\n' in contents: | |
| 425 list_index = contents.index('List of files:\n') + 1 | |
| 426 previous_file_list = [filename.strip() for filename in contents[list
_index:]] | |
| 427 | |
| 428 deleted_files = set(previous_file_list) - set(new_file_list) | |
| 429 for deleted_file in deleted_files: | |
| 430 _log.info('Deleting file removed from the W3C repo: %s', deleted_fil
e) | |
| 431 deleted_file = os.path.join(self._webkit_root, deleted_file) | |
| 432 os.remove(deleted_file) | |
| 433 | |
| 434 import_log.close() | |
| 435 | |
| 436 def write_import_log(self, dir_to_import, file_list, prop_list): | |
| 437 now = datetime.datetime.now() | |
| 438 | |
| 439 import_log = open(os.path.join(dir_to_import, 'w3c-import.log'), 'w') | |
| 440 import_log.write('The tests in this directory were imported from the W3C
repository.\n') | |
| 441 import_log.write('Do NOT modify these tests directly in Webkit. Instead,
push changes to the W3C CSS repo:\n\n') | |
| 442 import_log.write('http://hg.csswg.org/test\n\n') | |
| 443 import_log.write('Then run the Tools/Scripts/import-w3c-tests in Webkit
to reimport\n\n') | |
| 444 import_log.write('Do NOT modify or remove this file\n\n') | |
| 445 import_log.write('------------------------------------------------------
------------------\n') | |
| 446 import_log.write('Last Import: ' + now.strftime('%Y-%m-%d %H:%M') + '\n'
) | |
| 447 import_log.write('W3C Mercurial changeset: ' + self.changeset + '\n') | |
| 448 import_log.write('------------------------------------------------------
------------------\n') | |
| 449 import_log.write('Properties requiring vendor prefixes:\n') | |
| 450 if prop_list: | |
| 451 for prop in prop_list: | |
| 452 import_log.write(prop + '\n') | |
| 453 else: | |
| 454 import_log.write('None\n') | |
| 455 import_log.write('------------------------------------------------------
------------------\n') | |
| 456 import_log.write('List of files:\n') | |
| 457 for item in file_list: | |
| 458 import_log.write(item + '\n') | |
| 459 | |
| 460 import_log.close() | |
| OLD | NEW |