I have an application split into several crates. I want to deny or allow a specific lint in all crates. For example:
#![deny(clippy::print_stdout)]
It seems I have to add this to lib.rs in each of the crates.
There is an ticket with Cargo to allow configuring this somehow, but it has been open for several years with no clear conclusion.
Is there a workaround to avoid having these allow/deny/warn lines duplicated per crate?
One idea I had was to include! the lines by creating a clippy_config.rs at the workspace root, then in each crate's lib.rs adding
include!("../../clippy_config.rs");
However this fails with
error: an inner attribute is not permitted in this context
--> app/src/../../clippy_config.rs:1:1
|
1 | #![deny(clippy::print_stdout)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
My other thought to use a macro also does not work for much the same reason.
Is there a simple way to do this, except writing an external script to modify the Rust files to automate the duplication? (as mentioned in this comment describing Embark Studio's setup).
From Rust 1.74 onwards
Rust and Clippy lints can be configured:
#[deny(clippy::print_stdout)].-Dclippy::print-stdout.The configuration in
Cargo.tomlcan be done in several ways.For an individual crate, using the
[lints]section:For a workspace crate, using the
[lints]table:Then in each crate in the workspace which wishes to inherit:
Note: when using
cargo newto create a new crate in an existing workspace, the[lints]section is automatically added.When to use which?
Attributes are best used for one-off situations. For example, I regularly use
#[allow(clippy::too_many_arguments)]on internal functions, but I wouldn't want it on public API functions.Cargo.toml is best used for project wide settings which accommodate both the development workflow and CI. For example, I encourage the use of
unsafe_ops_in_unsafe_fn = "forbid"so each unsafe operation safety pre-conditions are clearly documented, rather than a hand-wavy "trust me".Flags are best used for workflow specific settings. For example, I would encourage
-Drust::dead-codein CI, but it would be a pain during development.Prior Versions
(Also works in Rust 1.74 onwards, just possibly less convenient)
Clippy offers 3 configuration modes:
#[deny(clippy::print_stdout)]-Dclippy::print-stdoutclippy.toml, though restricted to a subset of configurable lints.For project-wide configuration, across crates, the configuration file is the best option if it works.
Otherwise, the second best (hacky) option is to use flags indirectly. That is, rather than specifying
RUSTFLAGS=-Dclippy::print-stdoutin front of your compiler invocation, you can let Cargo do it, and configure Cargo project-wide.At the root of your project, create a
.cargo/config.tomlfile with the following content:Cargo will then pass this flag to clippy when it invokes it.
Note: in a workspace setting,
.cargo/config.tomlin individual crate folders is ignored when invoking Cargo from the root of the workspace, so best place this in the.cargoat the root.