rules_eslint
Hermetic eslint runner — lint a workspace's @npm eslint binary under Bazel
| Latest | 0.1.0 |
|---|---|
| Versions | 1 |
| Category | Bazel rules |
| Maintainers | Matt Marshall |
| Registry | https://registry.tbzl.dev/modules/rules_eslint/ |
| Source | github.com/tomato-bazel/rules_eslint |
bazel_dep(name = "rules_eslint", version = "0.1.0")
View source & releases on GitHub ↗
Hermetic eslint runner — lint a workspace’s @npm eslint binary under Bazel.
eslint is a Node tool whose binary + plugin/config closure live in your
pnpm-lock.yaml. So rules_eslint does not fetch eslint. It gives you a
small eslint_test macro that runs your own aspect_rules_js-linked eslint
binary over a set of sources as a Bazel test — the same “consumer supplies the
binary” shape as rules_storybook
and rules_nextjs.
Status: v0.1.0
eslint_test(name, srcs, eslint_bin, config, ...)— alint-taggedsh_testthat runseslint_bin --config <config> <srcs>.
Install
.bazelrc:
common --registry=https://registry.fastverk.com/
common --registry=https://bcr.bazel.build/
MODULE.bazel:
bazel_dep(name = "rules_eslint", version = "0.1.0")
Use
You already have eslint in your pnpm-lock.yaml and an @npm repo from
aspect_rules_js’s npm_translate_lock. Materialize the eslint binary with the
bin factory, then point eslint_test at it:
load("@npm//:eslint/package_json.bzl", eslint_bin = "bin")
load("@rules_eslint//eslint:defs.bzl", "eslint_test")
eslint_bin.eslint_binary(name = "eslint")
eslint_test(
name = "lint",
srcs = glob(["**/*.ts", "**/*.tsx"]),
eslint_bin = ":eslint",
config = "//:eslint.config.mjs",
)
Run one target, or fan out across the repo:
bazel test //:lint
bazel test //... --test_tag_filters=lint
Because eslint, its plugins, and the flat config all come from your own
@npm closure + sources, the test is hermetic and reproducible — no reliance
on a node_modules/.bin/eslint on the CI runner.
See examples/smoke for a complete, self-contained workspace.
Usage#
Real usage, taken from the module’s examples/.
examples/smoke/BUILD.bazel
load("@rules_eslint//eslint:defs.bzl", "eslint_test")
load("@smoke_npm//:defs.bzl", "npm_link_all_packages")
load("@smoke_npm//examples/smoke:eslint/package_json.bzl", eslint_bin = "bin")
package(default_visibility = ["//visibility:public"])
npm_link_all_packages(name = "node_modules")
exports_files(["pnpm-lock.yaml"])
# The consumer's own @npm eslint binary — what a real workspace passes to
# `eslint_test`. Here it comes from the pinned smoke npm workspace.
eslint_bin.eslint_binary(name = "eslint_cli")
# Release gate: a real `eslint_test` over a clean source, exercising the
# macro (binary + config + srcs → runfiles → eslint) end-to-end. Runs in
# `bazel test //...` on every CI OS.
eslint_test(
name = "smoke_test",
srcs = ["clean.js"],
config = "eslint.config.mjs",
eslint_bin = ":eslint_cli",
)Conformance#
No gate findings. 17 contested atoms. See how gating works or the full report.
Contested atoms
Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.
| Atom | Resolved here | Elsewhere |
|---|---|---|
apple_support | 1.24.2 | 2.2.0 ×1 |
aspect_bazel_lib | 2.22.5 | 2.8.1 ×1 |
aspect_rules_js | 3.1.2 | 2.1.3 ×1 |
bazel_lib | 3.2.2 | 3.0.0 ×12 |
bazel_skylib | 1.8.2 | 1.9.0 ×2 |
gawk | 5.3.2.bcr.3 | 5.3.2.bcr.1 ×12 |
jq.bzl | 0.4.0 | 0.1.0 ×12 |
nlohmann_json | 3.6.1 | 3.12.0.bcr.1 ×1 |
package_metadata | 0.0.2 | 0.0.5 ×3 |
protobuf | 33.4 | 34.0.bcr.1 ×2 |
rules_jvm_external | 6.7 | 6.8 ×4 |
rules_nodejs | 6.7.4 | 6.3.0 ×16.7.3 ×1 |
rules_python | 1.7.0 | 2.0.1 ×1 |
rules_swift | 3.1.2 | 3.6.1 ×1 |
tar.bzl | 0.10.4 | 0.5.1 ×110.6.0 ×1 |
upb | 0.0.0-20220923-a547704 | 0.0.0-20230516-61a97ef ×1 |
yq.bzl | 0.3.4 | 0.1.1 ×12 |
Dependencies#
Depends on
Versions#
1 published version, newest first. Each resolves to an immutable, integrity-checked archive.
| Version | Integrity (sha256) | Source archive |
|---|---|---|
0.1.0 latest | IQcBOfAWvyCdPZ71… | tag archive ↗ |
Changelog#
All notable changes to rules_eslint. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.
0.1.0
eslint_test(name, srcs, eslint_bin, config, tags = None, **kwargs)in//eslint:defs.bzl— alint-taggedsh_testthat runs a consumer-supplied@npmeslint binary (eslint_bin) oversrcsagainst a flatconfig. eslint + plugins + config all come from the consumer’s ownpnpm-lock.yaml/@npmclosure; the ruleset fetches nothing. The launcher (//eslint/private:run_eslint.sh) resolves the binary + config via the bazel runfiles library and forwards the sources toeslint --config <config>.//examples/smoke— a self-contained workspace pinning a real@npmeslint, used as the release gate.
0.0.1 — scaffold
- Initial scaffold via
rels scaffold. No public API yet.