• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2018 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from __future__ import print_function
16import time
17import subprocess
18from os.path import relpath, dirname, join
19
20USE_PYTHON3 = True
21
22
23def RunAndReportIfLong(func, *args, **kargs):
24  start = time.time()
25  results = func(*args, **kargs)
26  end = time.time()
27  limit = 0.5  # seconds
28  name = func.__name__
29  runtime = end - start
30  if runtime > limit:
31    print("{} took >{:.2}s ({:.2}s)".format(name, limit, runtime))
32  return results
33
34
35def CheckChange(input, output):
36  results = []
37  results += RunAndReportIfLong(CheckEslint, input, output)
38  results += RunAndReportIfLong(CheckPrettier, input, output)
39  results += RunAndReportIfLong(CheckImports, input, output)
40  results += RunAndReportIfLong(CheckAnyRachet, input, output)
41  return results
42
43
44def CheckChangeOnUpload(input_api, output_api):
45  return CheckChange(input_api, output_api)
46
47
48def CheckChangeOnCommit(input_api, output_api):
49  return CheckChange(input_api, output_api)
50
51
52def CheckEslint(input_api, output_api):
53  path = input_api.os_path
54  ui_path = input_api.PresubmitLocalPath()
55  module_path = path.join(ui_path, 'node_modules', '.bin', 'eslint')
56  lint_path = path.join(ui_path, 'eslint')
57
58  if not path.exists(module_path):
59    repo_root = input_api.change.RepositoryRoot()
60    install_path = path.join(repo_root, 'tools', 'install-build-deps')
61    return [
62        output_api.PresubmitError(
63            f"eslint not found. Please first run\n $ {install_path} --ui")
64    ]
65
66  def file_filter(x):
67    return input_api.FilterSourceFile(
68        x,
69        files_to_check=[r'.*\.ts$', r'.*\.js$'],
70        files_to_skip=[r'.*\.eslintrc\.js'])
71
72  files = input_api.AffectedSourceFiles(file_filter)
73
74  if not files:
75    return []
76  paths = [f.AbsoluteLocalPath() for f in files]
77
78  cmd = [lint_path] + paths
79  if subprocess.call(cmd):
80    s = ' '.join(cmd)
81    return [output_api.PresubmitError(f"eslint errors. Run: $ {s}")]
82  return []
83
84
85def CheckPrettier(input_api, output_api):
86  path = input_api.os_path
87  ui_path = input_api.PresubmitLocalPath()
88  module_path = path.join(ui_path, 'node_modules', '.bin', 'prettier')
89  prettier_path = path.join(ui_path, 'prettier')
90
91  if not path.exists(module_path):
92    repo_root = input_api.change.RepositoryRoot()
93    install_path = path.join(repo_root, 'tools', 'install-build-deps')
94    return [
95        output_api.PresubmitError(
96            f"prettier not found. Please first run\n $ {install_path} --ui")
97    ]
98
99  def file_filter(x):
100    return input_api.FilterSourceFile(
101        x, files_to_check=[r'.*\.ts$', r'.*\.js$', r'.*\.scss$'])
102
103  files = input_api.AffectedSourceFiles(file_filter)
104
105  if not files:
106    return []
107  paths = [f.AbsoluteLocalPath() for f in files]
108
109  cmd = [prettier_path, '--check'] + paths
110  if subprocess.call(cmd):
111    s = ' '.join(cmd)
112    return [
113        output_api.PresubmitError(f"""Prettier errors. To fix, run:
114{prettier_path} -w {'_'.join(paths)}""")
115    ]
116  return []
117
118
119def CheckImports(input_api, output_api):
120  path = input_api.os_path
121  ui_path = input_api.PresubmitLocalPath()
122  check_imports_path = join(dirname(ui_path), 'tools', 'check_imports')
123
124  def file_filter(x):
125    return input_api.FilterSourceFile(
126        x, files_to_check=[r'.*\.ts$', r'.*\.js$'])
127
128  files = input_api.AffectedSourceFiles(file_filter)
129
130  if not files:
131    return []
132
133  if subprocess.call([check_imports_path]):
134    return [output_api.PresubmitError(f"")]
135  return []
136
137
138def CheckAnyRachet(input_api, output_api):
139  path = input_api.os_path
140  ui_path = input_api.PresubmitLocalPath()
141  check_ratchet_path = join(dirname(ui_path), 'tools', 'check_ratchet')
142
143  def file_filter(x):
144    return input_api.FilterSourceFile(x, files_to_check=[r'.*\.ts$'])
145
146  files = input_api.AffectedSourceFiles(file_filter)
147
148  if not files:
149    return []
150
151  if subprocess.call([check_ratchet_path]):
152    return [output_api.PresubmitError(f"")]
153  return []
154