Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 1 | # 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 | |
| 17 | load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test") |
| 18 | |
Ben Rohlfs | 484ff8c | 2021-09-16 11:34:21 +0200 | [diff] [blame] | 19 | def 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 Poucet | 8e687ff | 2022-02-14 16:08:46 +0100 | [diff] [blame] | 34 | "@npm//typescript", |
Ben Rohlfs | 484ff8c | 2021-09-16 11:34:21 +0200 | [diff] [blame] | 35 | ], |
| 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 Poucet | 8e687ff | 2022-02-14 16:08:46 +0100 | [diff] [blame] | 43 | "@npm//eslint-plugin-lit", |
Ben Rohlfs | 484ff8c | 2021-09-16 11:34:21 +0200 | [diff] [blame] | 44 | "@npm//eslint-plugin-prettier", |
Chris Poucet | 8e687ff | 2022-02-14 16:08:46 +0100 | [diff] [blame] | 45 | "@npm//eslint-plugin-regex", |
Ben Rohlfs | 484ff8c | 2021-09-16 11:34:21 +0200 | [diff] [blame] | 46 | "@npm//gts", |
| 47 | ], |
| 48 | ) |
| 49 | |
David Ostrovsky | bde3a9e | 2022-07-18 14:58:55 +0200 | [diff] [blame] | 50 | def eslint(name, plugins, srcs, config, ignore, size = "large", extensions = [".js"], data = []): |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 51 | """ Macro to define eslint rules for files. |
| 52 | |
Tao Zhou | 74ac76b | 2020-04-03 10:15:36 +0200 | [diff] [blame] | 53 | 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 Ostrovsky | bde3a9e | 2022-07-18 14:58:55 +0200 | [diff] [blame] | 59 | size: eslint test size, supported values are: small, medium, large and enormous, |
| 60 | with implied timeout labels: short, moderate, long, and eternal |
Tao Zhou | 74ac76b | 2020-04-03 10:15:36 +0200 | [diff] [blame] | 61 | 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 Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 66 | |
Tao Zhou | 74ac76b | 2020-04-03 10:15:36 +0200 | [diff] [blame] | 67 | 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 Ostrovsky | d9e02c6 | 2020-04-03 19:56:48 +0200 | [diff] [blame] | 73 | bazel run {name}_test -- --fix $(pwd)/polygerrit-ui/app |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 74 | """ |
| 75 | entry_point = "@npm//:node_modules/eslint/bin/eslint.js" |
Dmitrii Filippov | fbb6254 | 2020-06-24 12:23:13 +0200 | [diff] [blame] | 76 | |
| 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 Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 88 | bin_data = [ |
| 89 | "@npm//eslint:eslint", |
| 90 | config, |
| 91 | ignore, |
Dmitrii Filippov | fbb6254 | 2020-06-24 12:23:13 +0200 | [diff] [blame] | 92 | "//tools/js/eslint-rules:eslint-rules-srcs", |
Dmitrii Filippov | 3b3d3ab | 2020-12-22 17:38:50 +0100 | [diff] [blame] | 93 | "//tools/js:eslint-chdir.js", |
Dmitrii Filippov | fbb6254 | 2020-06-24 12:23:13 +0200 | [diff] [blame] | 94 | eslint_rules_toplevel_file, |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 95 | ] + plugins + data |
| 96 | common_templated_args = [ |
Dmitrii Filippov | 3b3d3ab | 2020-12-22 17:38:50 +0100 | [diff] [blame] | 97 | "--node_options=--require=$$(rlocation $(rootpath //tools/js:eslint-chdir.js))", |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 98 | "--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 Filippov | fbb6254 | 2020-06-24 12:23:13 +0200 | [diff] [blame] | 107 | # Load custom rules from eslint-rules directory |
| 108 | "--rulesdir", |
| 109 | "$$(dirname $$(rlocation $(rootpath {})))".format(eslint_rules_toplevel_file), |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 110 | ] |
| 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 Rohlfs | 484ff8c | 2021-09-16 11:34:21 +0200 | [diff] [blame] | 123 | "./", # Relative to the config file location |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 124 | ], |
| 125 | # Should not run sandboxed. |
| 126 | tags = [ |
| 127 | "local", |
| 128 | "manual", |
| 129 | ], |
David Ostrovsky | ea97d16 | 2022-07-18 15:39:37 +0200 | [diff] [blame] | 130 | size = size, |
Dmitrii Filippov | 3d7ad55 | 2020-03-26 12:01:27 +0100 | [diff] [blame] | 131 | ) |
| 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 | ) |