| 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 |
| 11 # copyright notice, this list of conditions and the following | 11 # copyright notice, this list of conditions and the following |
| 12 # disclaimer in the documentation and/or other materials | 12 # disclaimer in the documentation and/or other materials |
| 13 # provided with the distribution. | 13 # provided with the distribution. |
| 14 # | 14 # |
| 15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY | 15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY |
| 16 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE | 18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE |
| 19 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | 19 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
| 20 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 21 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 22 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 22 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | 23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |
| 24 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | 24 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF |
| 25 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 # SUCH DAMAGE. | 26 # SUCH DAMAGE. |
| 27 | 27 |
| 28 """This script imports a directory of W3C tests into Blink. | 28 """Logic for converting and copying files from a W3C repo. |
| 29 | 29 |
| 30 This script takes a source repository directory, which it searches for files, | 30 This module is responsible for modifying and copying a subset of the tests from |
| 31 then converts and copies files over to a destination directory. | 31 a local W3C repository source directory into a destination directory. |
| 32 | |
| 33 Rules for importing: | |
| 34 | |
| 35 * By default, only reference tests and JS tests are imported, (because pixel | |
| 36 tests take longer to run). This can be overridden with the --all flag. | |
| 37 | |
| 38 * By default, if test files by the same name already exist in the destination | |
| 39 directory, they are overwritten. This is because this script is used to | |
| 40 refresh files periodically. This can be overridden with the --no-overwrite fl
ag. | |
| 41 | |
| 42 * All files are converted to work in Blink: | |
| 43 1. All CSS properties requiring the -webkit- vendor prefix are prefixed | |
| 44 (the list of what needs prefixes is read from Source/core/css/CSSPropert
ies.in). | |
| 45 2. Each reftest has its own copy of its reference file following | |
| 46 the naming conventions new-run-webkit-tests expects. | |
| 47 3. If a reference files lives outside the directory of the test that | |
| 48 uses it, it is checked for paths to support files as it will be | |
| 49 imported into a different relative position to the test file | |
| 50 (in the same directory). | |
| 51 4. Any tags with the class "instructions" have style="display:none" added | |
| 52 to them. Some w3c tests contain instructions to manual testers which we | |
| 53 want to strip out (the test result parser only recognizes pure testharne
ss.js | |
| 54 output and not those instructions). | |
| 55 | |
| 56 * Upon completion, script outputs the total number tests imported, | |
| 57 broken down by test type. | |
| 58 | |
| 59 * Also upon completion, if we are not importing the files in place, each | |
| 60 directory where files are imported will have a w3c-import.log file written wi
th | |
| 61 a timestamp, the list of CSS properties used that require prefixes, the list | |
| 62 of imported files, and guidance for future test modification and maintenance. | |
| 63 On subsequent imports, this file is read to determine if files have been | |
| 64 removed in the newer changesets. The script removes these files accordingly. | |
| 65 """ | 32 """ |
| 66 | 33 |
| 67 import logging | 34 import logging |
| 68 import mimetypes | 35 import mimetypes |
| 36 import os |
| 69 import re | 37 import re |
| 70 import optparse | |
| 71 import os | |
| 72 import sys | |
| 73 | 38 |
| 74 from webkitpy.common.host import Host | |
| 75 from webkitpy.common.webkit_finder import WebKitFinder | 39 from webkitpy.common.webkit_finder import WebKitFinder |
| 76 from webkitpy.layout_tests.models.test_expectations import TestExpectationParser | 40 from webkitpy.layout_tests.models.test_expectations import TestExpectationParser |
| 77 from webkitpy.w3c.test_parser import TestParser | 41 from webkitpy.w3c.test_parser import TestParser |
| 78 from webkitpy.w3c.test_converter import convert_for_webkit | 42 from webkitpy.w3c.test_converter import convert_for_webkit |
| 79 | 43 |
| 80 | |
| 81 # Maximum length of import path starting from top of source repository. | 44 # Maximum length of import path starting from top of source repository. |
| 82 # This limit is here because the Windows builders cannot create paths that are | 45 # This limit is here because the Windows builders cannot create paths that are |
| 83 # longer than the Windows max path length (260). See http://crbug.com/609871. | 46 # longer than the Windows max path length (260). See http://crbug.com/609871. |
| 84 MAX_PATH_LENGTH = 125 | 47 MAX_PATH_LENGTH = 125 |
| 85 | 48 |
| 86 | |
| 87 _log = logging.getLogger(__name__) | 49 _log = logging.getLogger(__name__) |
| 88 | 50 |
| 89 | 51 |
| 90 def main(_argv, _stdout, _stderr): | |
| 91 options, args = parse_args() | |
| 92 host = Host() | |
| 93 source_repo_path = host.filesystem.normpath(os.path.abspath(args[0])) | |
| 94 | |
| 95 if not host.filesystem.exists(source_repo_path): | |
| 96 sys.exit('Repository directory %s not found!' % source_repo_path) | |
| 97 | |
| 98 configure_logging() | |
| 99 test_importer = TestImporter(host, source_repo_path, options) | |
| 100 test_importer.do_import() | |
| 101 | |
| 102 | |
| 103 def configure_logging(): | |
| 104 class LogHandler(logging.StreamHandler): | |
| 105 | |
| 106 def format(self, record): | |
| 107 if record.levelno > logging.INFO: | |
| 108 return "%s: %s" % (record.levelname, record.getMessage()) | |
| 109 return record.getMessage() | |
| 110 | |
| 111 logger = logging.getLogger() | |
| 112 logger.setLevel(logging.INFO) | |
| 113 handler = LogHandler() | |
| 114 handler.setLevel(logging.INFO) | |
| 115 logger.addHandler(handler) | |
| 116 return handler | |
| 117 | |
| 118 | |
| 119 def parse_args(): | |
| 120 parser = optparse.OptionParser(usage='usage: %prog [options] source_repo_pat
h') | |
| 121 parser.add_option('-n', '--no-overwrite', dest='overwrite', action='store_fa
lse', default=True, | |
| 122 help=('Flag to prevent duplicate test files from overwriti
ng existing tests. ' | |
| 123 'By default, they will be overwritten.')) | |
| 124 parser.add_option('-a', '--all', action='store_true', default=False, | |
| 125 help=('Import all tests including reftests, JS tests, and
manual/pixel tests. ' | |
| 126 'By default, only reftests and JS tests are imported
.')) | |
| 127 parser.add_option('-d', '--dest-dir', dest='destination', default='w3c', | |
| 128 help=('Import into a specified directory relative to the L
ayoutTests root. ' | |
| 129 'By default, files are imported under LayoutTests/w3
c.')) | |
| 130 parser.add_option('--ignore-expectations', action='store_true', default=Fals
e, | |
| 131 help='Ignore the W3CImportExpectations file and import eve
rything.') | |
| 132 parser.add_option('--dry-run', action='store_true', default=False, | |
| 133 help='Dry run only (don\'t actually write any results).') | |
| 134 | |
| 135 options, args = parser.parse_args() | |
| 136 if len(args) != 1: | |
| 137 parser.error('Incorrect number of arguments; source repo path is require
d.') | |
| 138 return options, args | |
| 139 | |
| 140 | |
| 141 class TestImporter(object): | 52 class TestImporter(object): |
| 142 | 53 |
| 143 def __init__(self, host, source_repo_path, options): | 54 def __init__(self, host, source_repo_path, dest_dir_name='external'): |
| 55 """Initializes variables to prepare for copying and converting files. |
| 56 |
| 57 Args: |
| 58 source_repo_path: Path to the local checkout of a WPT |
| 59 """ |
| 144 self.host = host | 60 self.host = host |
| 61 |
| 62 assert self.host.filesystem.exists(source_repo_path) |
| 145 self.source_repo_path = source_repo_path | 63 self.source_repo_path = source_repo_path |
| 146 self.options = options | 64 self.dest_dir_name = dest_dir_name |
| 147 | 65 |
| 148 self.filesystem = self.host.filesystem | 66 self.filesystem = self.host.filesystem |
| 149 self.webkit_finder = WebKitFinder(self.filesystem) | 67 self.webkit_finder = WebKitFinder(self.filesystem) |
| 150 self._webkit_root = self.webkit_finder.webkit_base() | 68 self._webkit_root = self.webkit_finder.webkit_base() |
| 151 self.layout_tests_dir = self.webkit_finder.path_from_webkit_base('Layout
Tests') | 69 self.layout_tests_dir = self.webkit_finder.path_from_webkit_base('Layout
Tests') |
| 152 self.destination_directory = self.filesystem.normpath( | 70 self.destination_directory = self.filesystem.normpath( |
| 153 self.filesystem.join( | 71 self.filesystem.join( |
| 154 self.layout_tests_dir, | 72 self.layout_tests_dir, |
| 155 options.destination, | 73 dest_dir_name, |
| 156 self.filesystem.basename(self.source_repo_path))) | 74 self.filesystem.basename(self.source_repo_path))) |
| 157 self.import_in_place = (self.source_repo_path == self.destination_direct
ory) | 75 self.import_in_place = (self.source_repo_path == self.destination_direct
ory) |
| 158 self.dir_above_repo = self.filesystem.dirname(self.source_repo_path) | 76 self.dir_above_repo = self.filesystem.dirname(self.source_repo_path) |
| 159 | 77 |
| 160 self.import_list = [] | 78 self.import_list = [] |
| 161 | 79 |
| 162 # This is just a FYI list of CSS properties that still need to be prefix
ed, | 80 # This is just a FYI list of CSS properties that still need to be prefix
ed, |
| 163 # which may be output after importing. | 81 # which may be output after importing. |
| 164 self._prefixed_properties = {} | 82 self._prefixed_properties = {} |
| 165 | 83 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 190 # We copy all files in 'support', including HTML without metadata. | 108 # We copy all files in 'support', including HTML without metadata. |
| 191 # See: http://testthewebforward.org/docs/test-format-guidelines.html
#support-files | 109 # See: http://testthewebforward.org/docs/test-format-guidelines.html
#support-files |
| 192 dirs_to_include = ('resources', 'support') | 110 dirs_to_include = ('resources', 'support') |
| 193 | 111 |
| 194 if dirs: | 112 if dirs: |
| 195 for name in dirs_to_skip: | 113 for name in dirs_to_skip: |
| 196 if name in dirs: | 114 if name in dirs: |
| 197 dirs.remove(name) | 115 dirs.remove(name) |
| 198 | 116 |
| 199 for path in paths_to_skip: | 117 for path in paths_to_skip: |
| 200 path_base = path.replace(self.options.destination + '/', '') | 118 path_base = path.replace(self.dest_dir_name + '/', '') |
| 201 path_base = path_base.replace(cur_dir, '') | 119 path_base = path_base.replace(cur_dir, '') |
| 202 path_full = self.filesystem.join(root, path_base) | 120 path_full = self.filesystem.join(root, path_base) |
| 203 if path_base in dirs: | 121 if path_base in dirs: |
| 204 dirs.remove(path_base) | 122 dirs.remove(path_base) |
| 205 if not self.options.dry_run and self.import_in_place: | 123 if self.import_in_place: |
| 206 _log.info(" pruning %s", path_base) | 124 _log.info(" pruning %s", path_base) |
| 207 self.filesystem.rmtree(path_full) | 125 self.filesystem.rmtree(path_full) |
| 208 else: | 126 else: |
| 209 _log.info(" skipping %s", path_base) | 127 _log.info(" skipping %s", path_base) |
| 210 | 128 |
| 211 copy_list = [] | 129 copy_list = [] |
| 212 | 130 |
| 213 for filename in files: | 131 for filename in files: |
| 214 path_full = self.filesystem.join(root, filename) | 132 path_full = self.filesystem.join(root, filename) |
| 215 path_base = path_full.replace(self.source_repo_path + '/', '') | 133 path_base = path_full.replace(self.source_repo_path + '/', '') |
| 216 path_base = self.destination_directory.replace(self.layout_tests
_dir + '/', '') + '/' + path_base | 134 path_base = self.destination_directory.replace(self.layout_tests
_dir + '/', '') + '/' + path_base |
| 217 if path_base in paths_to_skip: | 135 if path_base in paths_to_skip: |
| 218 if not self.options.dry_run and self.import_in_place: | 136 if self.import_in_place: |
| 219 _log.info(" pruning %s", path_base) | 137 _log.info(" pruning %s", path_base) |
| 220 self.filesystem.remove(path_full) | 138 self.filesystem.remove(path_full) |
| 221 continue | 139 continue |
| 222 else: | 140 else: |
| 223 continue | 141 continue |
| 224 # FIXME: This block should really be a separate function, but th
e early-continues make that difficult. | 142 # FIXME: This block should really be a separate function, but th
e early-continues make that difficult. |
| 225 | 143 |
| 226 if filename.startswith('.') or filename.endswith('.pl'): | 144 if filename.startswith('.') or filename.endswith('.pl'): |
| 227 # The w3cs repos may contain perl scripts, which we don't ca
re about. | 145 # The w3cs repos may contain perl scripts, which we don't ca
re about. |
| 228 continue | 146 continue |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 total_tests += 1 | 202 total_tests += 1 |
| 285 copy_list.append({'src': test_info['reference'], 'dest': ref
_file, | 203 copy_list.append({'src': test_info['reference'], 'dest': ref
_file, |
| 286 'reference_support_info': test_info['refer
ence_support_info']}) | 204 'reference_support_info': test_info['refer
ence_support_info']}) |
| 287 copy_list.append({'src': test_info['test'], 'dest': filename
}) | 205 copy_list.append({'src': test_info['test'], 'dest': filename
}) |
| 288 | 206 |
| 289 elif 'jstest' in test_info.keys(): | 207 elif 'jstest' in test_info.keys(): |
| 290 jstests += 1 | 208 jstests += 1 |
| 291 total_tests += 1 | 209 total_tests += 1 |
| 292 copy_list.append({'src': fullpath, 'dest': filename, 'is_jst
est': True}) | 210 copy_list.append({'src': fullpath, 'dest': filename, 'is_jst
est': True}) |
| 293 | 211 |
| 294 elif self.options.all: | |
| 295 total_tests += 1 | |
| 296 copy_list.append({'src': fullpath, 'dest': filename}) | |
| 297 | |
| 298 if copy_list: | 212 if copy_list: |
| 299 # Only add this directory to the list if there's something to im
port | 213 # Only add this directory to the list if there's something to im
port |
| 300 self.import_list.append({'dirname': root, 'copy_list': copy_list
, | 214 self.import_list.append({'dirname': root, 'copy_list': copy_list
, |
| 301 'reftests': reftests, 'jstests': jstest
s, 'total_tests': total_tests}) | 215 'reftests': reftests, 'jstests': jstest
s, 'total_tests': total_tests}) |
| 302 | 216 |
| 303 def find_paths_to_skip(self): | 217 def find_paths_to_skip(self): |
| 304 if self.options.ignore_expectations: | |
| 305 return set() | |
| 306 | |
| 307 paths_to_skip = set() | 218 paths_to_skip = set() |
| 308 port = self.host.port_factory.get() | 219 port = self.host.port_factory.get() |
| 309 w3c_import_expectations_path = self.webkit_finder.path_from_webkit_base(
'LayoutTests', 'W3CImportExpectations') | 220 w3c_import_expectations_path = self.webkit_finder.path_from_webkit_base(
'LayoutTests', 'W3CImportExpectations') |
| 310 w3c_import_expectations = self.filesystem.read_text_file(w3c_import_expe
ctations_path) | 221 w3c_import_expectations = self.filesystem.read_text_file(w3c_import_expe
ctations_path) |
| 311 parser = TestExpectationParser(port, all_tests=(), is_lint_mode=False) | 222 parser = TestExpectationParser(port, all_tests=(), is_lint_mode=False) |
| 312 expectation_lines = parser.parse(w3c_import_expectations_path, w3c_impor
t_expectations) | 223 expectation_lines = parser.parse(w3c_import_expectations_path, w3c_impor
t_expectations) |
| 313 for line in expectation_lines: | 224 for line in expectation_lines: |
| 314 if 'SKIP' in line.expectations: | 225 if 'SKIP' in line.expectations: |
| 315 if line.specifiers: | 226 if line.specifiers: |
| 316 _log.warning("W3CImportExpectations:%s should not have any s
pecifiers", line.line_numbers) | 227 _log.warning("W3CImportExpectations:%s should not have any s
pecifiers", line.line_numbers) |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 dest_path = self.filesystem.join(dest_dir, file_to_copy['dest']) | 291 dest_path = self.filesystem.join(dest_dir, file_to_copy['dest']) |
| 381 | 292 |
| 382 if self.filesystem.isdir(source_path): | 293 if self.filesystem.isdir(source_path): |
| 383 _log.error('%s refers to a directory', source_path) | 294 _log.error('%s refers to a directory', source_path) |
| 384 return None | 295 return None |
| 385 | 296 |
| 386 if not self.filesystem.exists(source_path): | 297 if not self.filesystem.exists(source_path): |
| 387 _log.error('%s not found. Possible error in the test.', source_path) | 298 _log.error('%s not found. Possible error in the test.', source_path) |
| 388 return None | 299 return None |
| 389 | 300 |
| 390 if file_to_copy.get('reference_support_info'): | 301 reference_support_info = file_to_copy.get('reference_support_info') or N
one |
| 391 reference_support_info = file_to_copy['reference_support_info'] | |
| 392 else: | |
| 393 reference_support_info = None | |
| 394 | 302 |
| 395 if not self.filesystem.exists(self.filesystem.dirname(dest_path)): | 303 if not self.filesystem.exists(self.filesystem.dirname(dest_path)): |
| 396 if not self.import_in_place and not self.options.dry_run: | 304 if not self.import_in_place: |
| 397 self.filesystem.maybe_make_directory(self.filesystem.dirname(des
t_path)) | 305 self.filesystem.maybe_make_directory(self.filesystem.dirname(des
t_path)) |
| 398 | 306 |
| 399 relpath = self.filesystem.relpath(dest_path, self.layout_tests_dir) | 307 relpath = self.filesystem.relpath(dest_path, self.layout_tests_dir) |
| 400 if not self.options.overwrite and self.filesystem.exists(dest_path): | 308 # FIXME: Maybe doing a file diff is in order here for existing files? |
| 401 _log.info(' skipping %s', relpath) | 309 # In other words, there's no sense in overwriting identical files, but |
| 402 else: | 310 # there's no harm in copying the identical thing. |
| 403 # FIXME: Maybe doing a file diff is in order here for existing files
? | 311 _log.info(' %s', relpath) |
| 404 # In other words, there's no sense in overwriting identical files, b
ut | |
| 405 # there's no harm in copying the identical thing. | |
| 406 _log.info(' %s', relpath) | |
| 407 | 312 |
| 408 if self.should_try_to_convert(file_to_copy, source_path, dest_dir): | 313 if self.should_try_to_convert(file_to_copy, source_path, dest_dir): |
| 409 converted_file = convert_for_webkit( | 314 converted_file = convert_for_webkit( |
| 410 dest_dir, filename=source_path, | 315 dest_dir, filename=source_path, |
| 411 reference_support_info=reference_support_info, | 316 reference_support_info=reference_support_info, |
| 412 host=self.host) | 317 host=self.host) |
| 413 for prefixed_property in converted_file[0]: | 318 for prefixed_property in converted_file[0]: |
| 414 self._prefixed_properties.setdefault(prefixed_property, 0) | 319 self._prefixed_properties.setdefault(prefixed_property, 0) |
| 415 self._prefixed_properties[prefixed_property] += 1 | 320 self._prefixed_properties[prefixed_property] += 1 |
| 416 | 321 |
| 417 if not self.options.dry_run: | 322 self.filesystem.write_text_file(dest_path, converted_file[1]) |
| 418 self.filesystem.write_text_file(dest_path, converted_file[1]) | |
| 419 else: | 323 else: |
| 420 if not self.import_in_place and not self.options.dry_run: | 324 if not self.import_in_place: |
| 421 self.filesystem.copyfile(source_path, dest_path) | 325 self.filesystem.copyfile(source_path, dest_path) |
| 422 if self.filesystem.read_binary_file(source_path)[:2] == '#!': | 326 if self.filesystem.read_binary_file(source_path)[:2] == '#!': |
| 423 self.filesystem.make_executable(dest_path) | 327 self.filesystem.make_executable(dest_path) |
| 424 | 328 |
| 425 return dest_path.replace(self._webkit_root, '') | 329 return dest_path.replace(self._webkit_root, '') |
| 426 | 330 |
| 427 @staticmethod | 331 @staticmethod |
| 428 def should_try_to_convert(file_to_copy, source_path, dest_dir): | 332 def should_try_to_convert(file_to_copy, source_path, dest_dir): |
| 429 """Checks whether we should try to modify the file when importing.""" | 333 """Checks whether we should try to modify the file when importing.""" |
| 430 if file_to_copy.get('is_jstest', False): | 334 if file_to_copy.get('is_jstest', False): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 443 """Checks whether a source path is too long to import. | 347 """Checks whether a source path is too long to import. |
| 444 | 348 |
| 445 Args: | 349 Args: |
| 446 Absolute path of file to be imported. | 350 Absolute path of file to be imported. |
| 447 | 351 |
| 448 Returns: | 352 Returns: |
| 449 True if the path is too long to import, False if it's OK. | 353 True if the path is too long to import, False if it's OK. |
| 450 """ | 354 """ |
| 451 path_from_repo_base = os.path.relpath(source_path, self.source_repo_path
) | 355 path_from_repo_base = os.path.relpath(source_path, self.source_repo_path
) |
| 452 return len(path_from_repo_base) > MAX_PATH_LENGTH | 356 return len(path_from_repo_base) > MAX_PATH_LENGTH |
| OLD | NEW |