blob: dfaa316f083a9bfde227302ff3c7fa6eeb5d39ad [file]
"""Rules for defining lints to apply to various Rust targets"""
load("//rust/private:providers.bzl", "LintsInfo")
def _rust_lint_config(ctx):
"""Implementation of the `rust_lint_config` rule.
Args:
ctx (ctx): The rule's context object.
Returns:
list: The LintsInfo provider.
"""
allowed_levels = ["allow", "warn", "deny", "forbid", "force-warn"]
rustc_flags = []
for lint, level in ctx.attr.rustc.items():
if level not in allowed_levels:
fail("Invalid rustc lint level '{0}'".format(level))
rustc_flags.append("--{LEVEL}={LINT}".format(LEVEL = level, LINT = lint))
for name, values in ctx.attr.rustc_check_cfg.items():
if len(values) != 0:
values_list = ", ".join(["\"{0}\"".format(v) for v in values])
values_arg = ", values({0})".format(values_list)
else:
values_arg = ""
rustc_flags.append("--check-cfg=cfg({NAME}{VALUES})".format(NAME = name, VALUES = values_arg))
clippy_flags = []
for lint, level in ctx.attr.clippy.items():
if level not in allowed_levels:
fail("Invalid clippy lint level '{0}'".format(level))
clippy_flags.append("--{LEVEL}=clippy::{LINT}".format(LEVEL = level, LINT = lint))
rustdoc_flags = []
for lint, level in ctx.attr.rustdoc.items():
if level not in allowed_levels:
fail("Invalid rustdoc lint level '{0}'".format(level))
rustdoc_flags.append("--{LEVEL}=rustdoc::{LINT}".format(LEVEL = level, LINT = lint))
return LintsInfo(
rustc_lint_flags = rustc_flags,
rustc_lint_files = [],
clippy_lint_flags = clippy_flags,
clippy_lint_files = [],
rustdoc_lint_flags = rustdoc_flags,
rustdoc_lint_files = [],
)
# buildifier: disable=unsorted-dict-items
rust_lint_config = rule(
implementation = _rust_lint_config,
attrs = {
"rustc": attr.string_dict(
doc = "Set of 'rustc' lints to 'allow', 'expect', 'warn', 'force-warn', 'deny', or 'forbid'.",
),
"rustc_check_cfg": attr.string_list_dict(
doc = "Set of 'cfg' names and list of values to expect.",
),
"clippy": attr.string_dict(
doc = "Set of 'clippy' lints to 'allow', 'expect', 'warn', 'force-warn', 'deny', or 'forbid'.",
),
"rustdoc": attr.string_dict(
doc = "Set of 'rustdoc' lints to 'allow', 'expect', 'warn', 'force-warn', 'deny', or 'forbid'.",
),
},
doc = """\
Defines a group of lints that can be applied when building Rust targets.
For example, you can define a single group of lints:
```python
load("@rules_rust//rust:defs.bzl", "rust_lint_config")
rust_lint_config(
name = "workspace_lints",
rustc = {
"unknown_lints": "allow",
"unexpected_cfgs": "warn",
},
rustc_check_cfg = {
"bazel": [],
"fuzzing": [],
"mz_featutres": ["laser", "rocket"],
},
clippy = {
"box_default": "allow",
"todo": "warn",
"unused_async": "warn",
},
rustdoc = {
"unportable_markdown": "allow",
},
)
```
""",
)