Index: Tools/Scripts/webkitpy/bindings/main.py
|
diff --git a/Tools/Scripts/webkitpy/bindings/main.py b/Tools/Scripts/webkitpy/bindings/main.py
|
index 1a715b988b3e667e46eb8a362062350f3e6ed9b3..7a16b561d0c259d1f81b15684c8f980f28a149e7 100644
|
--- a/Tools/Scripts/webkitpy/bindings/main.py
|
+++ b/Tools/Scripts/webkitpy/bindings/main.py
|
@@ -29,8 +29,7 @@ import shutil
|
import sys
|
import tempfile
|
|
-from webkitpy.common.checkout.scm.detection import detect_scm_system
|
-from webkitpy.common.system import executive
|
+from webkitpy.common.system.executive import Executive
|
|
# Add Source path to PYTHONPATH to support function calls to bindings/scripts
|
# for compute_interfaces_info and idl_compiler
|
@@ -64,11 +63,11 @@ DEPENDENCY_IDL_FILES = frozenset([
|
])
|
|
|
-EXTENDED_ATTRIBUTES_FILE = 'bindings/IDLExtendedAttributes.txt'
|
+EXTENDED_ATTRIBUTES_FILE = os.path.join(source_path,
|
+ 'bindings/IDLExtendedAttributes.txt')
|
|
-all_input_directory = '.' # Relative to Source/
|
-test_input_directory = os.path.join('bindings', 'tests', 'idls')
|
-reference_directory = os.path.join('bindings', 'tests', 'results')
|
+test_input_directory = os.path.join(source_path, 'bindings', 'tests', 'idls')
|
+reference_directory = os.path.join(source_path, 'bindings', 'tests', 'results')
|
|
|
class ScopedTempDir(object):
|
@@ -85,82 +84,79 @@ class ScopedTempDir(object):
|
shutil.rmtree(self.dir_path)
|
|
|
-
|
-class BindingsTests(object):
|
- def __init__(self, output_directory, verbose):
|
- self.verbose = verbose
|
- self.executive = executive.Executive()
|
- self.idl_compiler = None
|
- self.output_directory = output_directory
|
-
|
- def diff(self, filename1, filename2):
|
+def generate_interface_dependencies():
|
+ def idl_paths_recursive(directory):
|
+ # This is slow, especially on Windows, due to os.walk making
|
+ # excess stat() calls. Faster versions may appear in future
|
+ # versions of Python:
|
+ # https://github.com/benhoyt/scandir
|
+ # http://bugs.python.org/issue11406
|
+ idl_paths = []
|
+ for dirpath, _, files in os.walk(directory):
|
+ idl_paths.extend(os.path.join(dirpath, filename)
|
+ for filename in fnmatch.filter(files, '*.idl'))
|
+ return idl_paths
|
+
|
+ # We compute interfaces info for *all* IDL files, not just test IDL
|
+ # files, as code generator output depends on inheritance (both ancestor
|
+ # chain and inherited extended attributes), and some real interfaces
|
+ # are special-cased, such as Node.
|
+ #
|
+ # For example, when testing the behavior of interfaces that inherit
|
+ # from Node, we also need to know that these inherit from EventTarget,
|
+ # since this is also special-cased and Node inherits from EventTarget,
|
+ # but this inheritance information requires computing dependencies for
|
+ # the real Node.idl file.
|
+ compute_interfaces_info(idl_paths_recursive(source_path))
|
+
|
+
|
+def bindings_tests(output_directory, verbose):
|
+ executive = Executive()
|
+
|
+ def diff(filename1, filename2):
|
# Python's difflib module is too slow, especially on long output, so
|
# run external diff(1) command
|
cmd = ['diff',
|
- '-u',
|
- '-N',
|
+ '-u', # unified format
|
+ '-N', # treat absent files as empty
|
filename1,
|
filename2]
|
# Return output and don't raise exception, even though diff(1) has
|
# non-zero exit if files differ.
|
- return self.executive.run_command(cmd, error_handler=lambda x: None)
|
-
|
- def generate_from_idl(self, idl_file):
|
- idl_file_fullpath = os.path.realpath(idl_file)
|
- self.idl_compiler.compile_file(idl_file_fullpath)
|
-
|
- def generate_interface_dependencies(self):
|
- def idl_paths_recursive(directory):
|
- idl_paths = []
|
- for dirpath, _, files in os.walk(directory):
|
- idl_paths.extend(os.path.join(dirpath, filename)
|
- for filename in fnmatch.filter(files, '*.idl'))
|
- return idl_paths
|
-
|
- # We compute interfaces info for *all* IDL files, not just test IDL
|
- # files, as code generator output depends on inheritance (both ancestor
|
- # chain and inherited extended attributes), and some real interfaces
|
- # are special-cased, such as Node.
|
- #
|
- # For example, when testing the behavior of interfaces that inherit
|
- # from Node, we also need to know that these inherit from EventTarget,
|
- # since this is also special-cased and Node inherits from EventTarget,
|
- # but this inheritance information requires computing dependencies for
|
- # the real Node.idl file.
|
- compute_interfaces_info(idl_paths_recursive(all_input_directory))
|
-
|
- def delete_cache_files(self):
|
+ return executive.run_command(cmd, error_handler=lambda x: None)
|
+
|
+ def delete_cache_files():
|
# FIXME: Instead of deleting cache files, don't generate them.
|
- cache_files = [os.path.join(self.output_directory, output_file)
|
- for output_file in os.listdir(self.output_directory)
|
+ cache_files = [os.path.join(output_directory, output_file)
|
+ for output_file in os.listdir(output_directory)
|
if (output_file in ('lextab.py', # PLY lex
|
'lextab.pyc',
|
'parsetab.pickle') or # PLY yacc
|
- output_file.endswith('.cache'))] # Jinja
|
+ output_file.endswith('.cache'))] # Jinja
|
for cache_file in cache_files:
|
os.remove(cache_file)
|
|
- def identical_file(self, reference_filename, output_filename):
|
+ def identical_file(reference_filename, output_filename):
|
reference_basename = os.path.basename(reference_filename)
|
|
if not filecmp.cmp(reference_filename, output_filename):
|
print 'FAIL: %s' % reference_basename
|
- print self.diff(reference_filename, output_filename)
|
+ print diff(reference_filename, output_filename)
|
return False
|
|
- if self.verbose:
|
+ if verbose:
|
print 'PASS: %s' % reference_basename
|
return True
|
|
- def identical_output_files(self):
|
+ def identical_output_files():
|
file_pairs = [(os.path.join(reference_directory, output_file),
|
- os.path.join(self.output_directory, output_file))
|
- for output_file in os.listdir(self.output_directory)]
|
- return all([self.identical_file(reference_filename, output_filename)
|
+ os.path.join(output_directory, output_file))
|
+ for output_file in os.listdir(output_directory)]
|
+ return all([identical_file(reference_filename, output_filename)
|
for (reference_filename, output_filename) in file_pairs])
|
|
- def no_excess_files(self):
|
- generated_files = set(os.listdir(self.output_directory))
|
+ def no_excess_files():
|
+ generated_files = set(os.listdir(output_directory))
|
generated_files.add('.svn') # Subversion working copy directory
|
excess_files = [output_file
|
for output_file in os.listdir(reference_directory)
|
@@ -172,47 +168,39 @@ class BindingsTests(object):
|
return False
|
return True
|
|
- def run_tests(self):
|
- self.generate_interface_dependencies()
|
- self.idl_compiler = IdlCompilerV8(self.output_directory,
|
- EXTENDED_ATTRIBUTES_FILE,
|
- interfaces_info=interfaces_info,
|
- only_if_changed=True)
|
-
|
- for input_filename in os.listdir(test_input_directory):
|
- if not input_filename.endswith('.idl'):
|
- continue
|
- if input_filename in DEPENDENCY_IDL_FILES:
|
- # Dependencies aren't built (they are used by the dependent)
|
- if self.verbose:
|
- print 'DEPENDENCY: %s' % input_filename
|
- continue
|
-
|
- idl_path = os.path.join(test_input_directory, input_filename)
|
- self.generate_from_idl(idl_path)
|
- if self.verbose:
|
- print 'Compiled: %s' % input_filename
|
-
|
- self.delete_cache_files()
|
-
|
- # Detect all changes
|
- passed = self.identical_output_files()
|
- passed &= self.no_excess_files()
|
- return passed
|
-
|
- def main(self):
|
- current_scm = detect_scm_system(os.curdir)
|
- os.chdir(os.path.join(current_scm.checkout_root, 'Source'))
|
-
|
- all_tests_passed = self.run_tests()
|
- if all_tests_passed:
|
- if self.verbose:
|
- print
|
- print PASS_MESSAGE
|
- return 0
|
- print
|
- print FAIL_MESSAGE
|
- return 1
|
+ generate_interface_dependencies()
|
+ idl_compiler = IdlCompilerV8(output_directory,
|
+ EXTENDED_ATTRIBUTES_FILE,
|
+ interfaces_info=interfaces_info,
|
+ only_if_changed=True)
|
+
|
+ idl_basenames = [filename
|
+ for filename in os.listdir(test_input_directory)
|
+ if (filename.endswith('.idl') and
|
+ # Dependencies aren't built
|
+ # (they are used by the dependent)
|
+ filename not in DEPENDENCY_IDL_FILES)]
|
+ for idl_basename in idl_basenames:
|
+ idl_path = os.path.realpath(
|
+ os.path.join(test_input_directory, idl_basename))
|
+ idl_compiler.compile_file(idl_path)
|
+ if verbose:
|
+ print 'Compiled: %s' % filename
|
+
|
+ delete_cache_files()
|
+
|
+ # Detect all changes
|
+ passed = identical_output_files()
|
+ passed &= no_excess_files()
|
+
|
+ if passed:
|
+ if verbose:
|
+ print
|
+ print PASS_MESSAGE
|
+ return 0
|
+ print
|
+ print FAIL_MESSAGE
|
+ return 1
|
|
|
def run_bindings_tests(reset_results, verbose):
|
@@ -220,6 +208,6 @@ def run_bindings_tests(reset_results, verbose):
|
# a temp directory if not.
|
if reset_results:
|
print 'Resetting results'
|
- return BindingsTests(reference_directory, verbose).main()
|
+ return bindings_tests(reference_directory, verbose)
|
with ScopedTempDir() as temp_dir:
|
- return BindingsTests(temp_dir, verbose).main()
|
+ return bindings_tests(temp_dir, verbose)
|
|