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
15import subprocess
16from os.path import relpath
17
18
19def CheckChange(input, output):
20  results = []
21  results += CheckTslint(input, output)
22  return results
23
24
25def CheckChangeOnUpload(input_api, output_api):
26  return CheckChange(input_api, output_api)
27
28
29def CheckChangeOnCommit(input_api, output_api):
30  return CheckChange(input_api, output_api)
31
32
33def CheckTslint(input_api, output_api):
34  path = input_api.os_path
35  ui_path = input_api.PresubmitLocalPath()
36  node = path.join(ui_path, 'node')
37  tslint = path.join(ui_path, 'node_modules', '.bin', 'tslint')
38
39  if not path.exists(tslint):
40    repo_root = input_api.change.RepositoryRoot()
41    install_path = path.join(repo_root, 'tools', 'install-build-deps')
42    return [
43        output_api.PresubmitError("Tslint not found. Please first run\n" +
44                                  "$ {0} --ui".format(install_path))
45    ]
46
47  # Some tslint rules require type information and thus need the whole
48  # project. We therefore call tslint on the whole project instead of only the
49  # changed files. It is possible to break tslint on files that was not
50  # changed by changing the type of an object.
51  if subprocess.call(
52      [node, tslint, '--project', ui_path, '--format', 'codeFrame']):
53    return [
54        output_api.PresubmitError("""\
55There were tslint errors. You may be able to fix some of them using
56$ {} {} --project {} --fix
57
58If this is unexpected: did you remember to do a UI build before running the
59presubmit?""".format(relpath(node), relpath(tslint), ui_path))
60    ]
61  return []
62