blob: eb4d37a720c179dbbacc82ca654cfb0723e92021 [file] [log] [blame]
# Copyright (C) 2020 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains macro to run eslint and define a eslint test rule."""
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test")
def plugin_eslint():
""" Convenience wrapper macro of eslint() for Gerrit js plugins
Args:
name: name of the rule
"""
eslint(
name = "lint",
srcs = native.glob(["**/*.ts"]),
config = ".eslintrc.js",
data = [
"tsconfig.json",
"//plugins:.eslintrc.js",
"//plugins:.prettierrc.js",
"//plugins:tsconfig-plugins-base.json",
],
extensions = [".ts"],
ignore = "//plugins:.eslintignore",
plugins = [
"@npm//eslint-config-google",
"@npm//eslint-plugin-html",
"@npm//eslint-plugin-import",
"@npm//eslint-plugin-jsdoc",
"@npm//eslint-plugin-prettier",
"@npm//gts",
],
)
def eslint(name, plugins, srcs, config, ignore, extensions = [".js"], data = []):
""" Macro to define eslint rules for files.
Args:
name: name of the rule
plugins: list of npm dependencies with plugins, for example "@npm//eslint-config-google"
srcs: list of files to be checked (ignored in {name}_bin rule)
config: eslint config file
ignore: eslint ignore file
extensions: list of file extensions to be checked. This is an additional filter for
srcs list. Each extension must start with '.' character.
Default: [".js"].
data: list of additional dependencies. For example if a config file extends an another
file, this other file must be added to data.
Generate: 2 rules:
{name}_test rule - runs eslint tests. You can run this rule with
'bazel test {name}_test' command. The rule tests all files from srcs with specified
extensions inside the package where eslint macro is called.
{name}_bin rule - runs eslint with specified settings; ignores srcs. To use this rule
you must pass a folder to check, for example:
bazel run {name}_test -- --fix $(pwd)/polygerrit-ui/app
"""
entry_point = "@npm//:node_modules/eslint/bin/eslint.js"
# There are custom eslint rules in eslint-rules directory. Eslint loads
# custom rules from a directory specified with the --rulesdir argument.
# When bazel runs eslint, it places the eslint-rules directory into
# some location in the filesystem, and the location is not known in advance.
# It is not possible to get the directory location in bazel directly.
# Instead, we can use dirname to get a directory for a file in the
# eslint-rules directory.
# README.md is the most "stable" file in the eslint-rules directory
# (i.e. it is unlikely will be removed), and we are using it to calculate
# exact directory path in bazel.
eslint_rules_toplevel_file = "//tools/js/eslint-rules:README.md"
bin_data = [
"@npm//eslint:eslint",
config,
ignore,
"//tools/js/eslint-rules:eslint-rules-srcs",
"//tools/js:eslint-chdir.js",
eslint_rules_toplevel_file,
] + plugins + data
common_templated_args = [
"--node_options=--require=$$(rlocation $(rootpath //tools/js:eslint-chdir.js))",
"--ext",
",".join(extensions),
"-c",
# Use rlocation/rootpath instead of location.
# See note and example here:
# https://bazelbuild.github.io/rules_nodejs/Built-ins.html#nodejs_binary
"$$(rlocation $(rootpath {}))".format(config),
"--ignore-path",
"$$(rlocation $(rootpath {}))".format(ignore),
# Load custom rules from eslint-rules directory
"--rulesdir",
"$$(dirname $$(rlocation $(rootpath {})))".format(eslint_rules_toplevel_file),
]
nodejs_test(
name = name + "_test",
entry_point = entry_point,
data = bin_data + srcs,
# Bazel generates 2 .js files, where names of the files are generated from the name
# of the rule: {name}_test_require_patch.js and {name}_test_loader.js
# Ignore these 2 files, for simplicity do not use {name} in the patterns.
templated_args = common_templated_args + [
"--ignore-pattern",
"*_test_require_patch.js",
"--ignore-pattern",
"*_test_loader.js",
"./", # Relative to the config file location
],
# Should not run sandboxed.
tags = [
"local",
"manual",
],
)
nodejs_binary(
name = name + "_bin",
entry_point = "@npm//:node_modules/eslint/bin/eslint.js",
data = bin_data,
# Bazel generates 2 .js files, where names of the files are generated from the name
# of the rule: {name}_bin_require_patch.js and {name}_bin_loader.js
# Ignore these 2 files, for simplicity do not use {name} in the patterns.
templated_args = common_templated_args + [
"--ignore-pattern",
"*_bin_require_patch.js",
"--ignore-pattern",
"*_bin_loader.js",
],
)