blob: 320f8da77167cf4688a2560cdbd7820fc18394e5 [file] [log] [blame]
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +01001# Copyright (C) 2020 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
15"""This file contains macro to run eslint and define a eslint test rule."""
16
17load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test")
18
Ben Rohlfs484ff8c2021-09-16 11:34:21 +020019def plugin_eslint():
20 """ Convenience wrapper macro of eslint() for Gerrit js plugins
21
22 Args:
23 name: name of the rule
24 """
25 eslint(
26 name = "lint",
27 srcs = native.glob(["**/*.ts"]),
28 config = ".eslintrc.js",
29 data = [
30 "tsconfig.json",
31 "//plugins:.eslintrc.js",
32 "//plugins:.prettierrc.js",
33 "//plugins:tsconfig-plugins-base.json",
Chris Poucet8e687ff2022-02-14 16:08:46 +010034 "@npm//typescript",
Ben Rohlfs484ff8c2021-09-16 11:34:21 +020035 ],
36 extensions = [".ts"],
37 ignore = "//plugins:.eslintignore",
38 plugins = [
39 "@npm//eslint-config-google",
40 "@npm//eslint-plugin-html",
41 "@npm//eslint-plugin-import",
42 "@npm//eslint-plugin-jsdoc",
Chris Poucet8e687ff2022-02-14 16:08:46 +010043 "@npm//eslint-plugin-lit",
Ben Rohlfs484ff8c2021-09-16 11:34:21 +020044 "@npm//eslint-plugin-prettier",
Chris Poucet8e687ff2022-02-14 16:08:46 +010045 "@npm//eslint-plugin-regex",
Ben Rohlfs484ff8c2021-09-16 11:34:21 +020046 "@npm//gts",
47 ],
48 )
49
David Ostrovskybde3a9e2022-07-18 14:58:55 +020050def eslint(name, plugins, srcs, config, ignore, size = "large", extensions = [".js"], data = []):
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010051 """ Macro to define eslint rules for files.
52
Tao Zhou74ac76b2020-04-03 10:15:36 +020053 Args:
54 name: name of the rule
55 plugins: list of npm dependencies with plugins, for example "@npm//eslint-config-google"
56 srcs: list of files to be checked (ignored in {name}_bin rule)
57 config: eslint config file
58 ignore: eslint ignore file
David Ostrovskybde3a9e2022-07-18 14:58:55 +020059 size: eslint test size, supported values are: small, medium, large and enormous,
60 with implied timeout labels: short, moderate, long, and eternal
Tao Zhou74ac76b2020-04-03 10:15:36 +020061 extensions: list of file extensions to be checked. This is an additional filter for
62 srcs list. Each extension must start with '.' character.
63 Default: [".js"].
64 data: list of additional dependencies. For example if a config file extends an another
65 file, this other file must be added to data.
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010066
Tao Zhou74ac76b2020-04-03 10:15:36 +020067 Generate: 2 rules:
68 {name}_test rule - runs eslint tests. You can run this rule with
69 'bazel test {name}_test' command. The rule tests all files from srcs with specified
70 extensions inside the package where eslint macro is called.
71 {name}_bin rule - runs eslint with specified settings; ignores srcs. To use this rule
72 you must pass a folder to check, for example:
David Ostrovskyd9e02c62020-04-03 19:56:48 +020073 bazel run {name}_test -- --fix $(pwd)/polygerrit-ui/app
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010074 """
75 entry_point = "@npm//:node_modules/eslint/bin/eslint.js"
Dmitrii Filippovfbb62542020-06-24 12:23:13 +020076
77 # There are custom eslint rules in eslint-rules directory. Eslint loads
78 # custom rules from a directory specified with the --rulesdir argument.
79 # When bazel runs eslint, it places the eslint-rules directory into
80 # some location in the filesystem, and the location is not known in advance.
81 # It is not possible to get the directory location in bazel directly.
82 # Instead, we can use dirname to get a directory for a file in the
83 # eslint-rules directory.
84 # README.md is the most "stable" file in the eslint-rules directory
85 # (i.e. it is unlikely will be removed), and we are using it to calculate
86 # exact directory path in bazel.
87 eslint_rules_toplevel_file = "//tools/js/eslint-rules:README.md"
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010088 bin_data = [
89 "@npm//eslint:eslint",
90 config,
91 ignore,
Dmitrii Filippovfbb62542020-06-24 12:23:13 +020092 "//tools/js/eslint-rules:eslint-rules-srcs",
Dmitrii Filippov3b3d3ab2020-12-22 17:38:50 +010093 "//tools/js:eslint-chdir.js",
Dmitrii Filippovfbb62542020-06-24 12:23:13 +020094 eslint_rules_toplevel_file,
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010095 ] + plugins + data
96 common_templated_args = [
Dmitrii Filippov3b3d3ab2020-12-22 17:38:50 +010097 "--node_options=--require=$$(rlocation $(rootpath //tools/js:eslint-chdir.js))",
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +010098 "--ext",
99 ",".join(extensions),
100 "-c",
101 # Use rlocation/rootpath instead of location.
102 # See note and example here:
103 # https://bazelbuild.github.io/rules_nodejs/Built-ins.html#nodejs_binary
104 "$$(rlocation $(rootpath {}))".format(config),
105 "--ignore-path",
106 "$$(rlocation $(rootpath {}))".format(ignore),
Dmitrii Filippovfbb62542020-06-24 12:23:13 +0200107 # Load custom rules from eslint-rules directory
108 "--rulesdir",
109 "$$(dirname $$(rlocation $(rootpath {})))".format(eslint_rules_toplevel_file),
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +0100110 ]
111 nodejs_test(
112 name = name + "_test",
113 entry_point = entry_point,
114 data = bin_data + srcs,
115 # Bazel generates 2 .js files, where names of the files are generated from the name
116 # of the rule: {name}_test_require_patch.js and {name}_test_loader.js
117 # Ignore these 2 files, for simplicity do not use {name} in the patterns.
118 templated_args = common_templated_args + [
119 "--ignore-pattern",
120 "*_test_require_patch.js",
121 "--ignore-pattern",
122 "*_test_loader.js",
Ben Rohlfs484ff8c2021-09-16 11:34:21 +0200123 "./", # Relative to the config file location
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +0100124 ],
125 # Should not run sandboxed.
126 tags = [
127 "local",
128 "manual",
129 ],
David Ostrovskyea97d162022-07-18 15:39:37 +0200130 size = size,
Dmitrii Filippov3d7ad552020-03-26 12:01:27 +0100131 )
132
133 nodejs_binary(
134 name = name + "_bin",
135 entry_point = "@npm//:node_modules/eslint/bin/eslint.js",
136 data = bin_data,
137 # Bazel generates 2 .js files, where names of the files are generated from the name
138 # of the rule: {name}_bin_require_patch.js and {name}_bin_loader.js
139 # Ignore these 2 files, for simplicity do not use {name} in the patterns.
140 templated_args = common_templated_args + [
141 "--ignore-pattern",
142 "*_bin_require_patch.js",
143 "--ignore-pattern",
144 "*_bin_loader.js",
145 ],
146 )