diff --git a/.gitignore b/.gitignore index ffbf9ce355..77543b2892 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ .cproject .gclient_entries .gdb_history +.jslint-cache .landmines .project .pydevproject diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 9b03f631c5..2333cd7ef6 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -78,6 +78,7 @@ def _V8PresubmitChecks(input_api, output_api): sys.path.append(input_api.os_path.join( input_api.PresubmitLocalPath(), 'tools')) from v8_presubmit import CppLintProcessor + from v8_presubmit import JSLintProcessor from v8_presubmit import TorqueLintProcessor from v8_presubmit import SourceProcessor from v8_presubmit import StatusFilesProcessor @@ -93,6 +94,11 @@ def _V8PresubmitChecks(input_api, output_api): affected_file, white_list=(r'.+\.tq')) + def FilterJSFile(affected_file): + return input_api.FilterSourceFile( + affected_file, + white_list=(r'.+\.m?js')) + results = [] if not CppLintProcessor().RunOnFiles( input_api.AffectedFiles(file_filter=FilterFile, include_deletes=False)): @@ -101,6 +107,10 @@ def _V8PresubmitChecks(input_api, output_api): input_api.AffectedFiles(file_filter=FilterTorqueFile, include_deletes=False)): results.append(output_api.PresubmitError("Torque format check failed")) + if not JSLintProcessor().RunOnFiles( + input_api.AffectedFiles(file_filter=FilterJSFile, + include_deletes=False)): + results.append(output_api.PresubmitError("JS format check failed")) if not SourceProcessor().RunOnFiles( input_api.AffectedFiles(include_deletes=False)): results.append(output_api.PresubmitError( diff --git a/tools/v8_presubmit.py b/tools/v8_presubmit.py index 6fbc3ad2ed..5f94be6568 100755 --- a/tools/v8_presubmit.py +++ b/tools/v8_presubmit.py @@ -131,6 +131,31 @@ def TorqueLintWorker(command): print('Error running format-torque.py') process.kill() +def JSLintWorker(command): + try: + file_name = command[-1] + with open(file_name, "r") as file_handle: + contents = file_handle.read() + + process = subprocess.Popen(command, stdout=PIPE, stderr=subprocess.PIPE) + output, err = process.communicate() + rc = process.returncode + if rc != 0: + sys.stdout.write("error code " + str(rc) + " running clang-format.\n") + return rc + + if output != contents: + sys.stdout.write(file_name + " requires formatting.\n") + return 1 + + return 0 + except KeyboardInterrupt: + process.kill() + except Exception: + print('Error running clang-format. Please make sure you have depot_tools' + + ' in your $PATH. Lint check skipped.') + process.kill() + class FileContentsCache(object): def __init__(self, sums_file_name): @@ -392,6 +417,33 @@ class TorqueLintProcessor(CacheableSourceFileProcessor): return None, arguments +class JSLintProcessor(CacheableSourceFileProcessor): + """ + Check .{m}js file to verify they follow the JS Style guide. + """ + def __init__(self, use_cache=True): + super(JSLintProcessor, self).__init__( + use_cache=use_cache, cache_file_path='.jslint-cache', + file_type='JavaScript') + + def IsRelevant(self, name): + return name.endswith('.js') or name.endswith('.mjs') + + def GetPathsToSearch(self): + return ['tools/system-analyzer'] + + def GetProcessorWorker(self): + return JSLintWorker + + def GetProcessorScript(self): + for path in [TOOLS_PATH] + os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + clang_format = os.path.join(path, 'clang_format.py') + if os.path.isfile(clang_format): + return clang_format, [] + + return None, [] + COPYRIGHT_HEADER_PATTERN = re.compile( r'Copyright [\d-]*20[0-2][0-9] the V8 project authors. All rights reserved.') @@ -708,6 +760,9 @@ def Main(): print("Running Torque formatting check...") success &= TorqueLintProcessor(use_cache=use_linter_cache).RunOnPath( workspace) + print("Running JavaScript formatting check...") + success &= JSLintProcessor(use_cache=use_linter_cache).RunOnPath( + workspace) print("Running copyright header, trailing whitespaces and " \ "two empty lines between declarations check...") success &= SourceProcessor().RunOnPath(workspace)