An easy to configure wrapper for Rust's clippy

Overview

cargo-cranky

I wish that I could check in a file that would specify Rust lints for my entire Cargo workspace, and have that be applied to all the crates, libraries, binaries, and examples.

Doing this with just Rust/Cargo/Clippy can be a bit of a pain. cargo-cranky makes it a little easier!

cargo-cranky is just a wrapper around cargo clippy; it examines your Cranky.toml config file, and constructs the necessary cargo clippy command line. Most arguments are passed through to clippy, so it should work from every context where clippy works (IDEs, CI scripts, etc).

For example, if Cranky.toml contains this:

warn = [
  "clippy::empty_structs_with_brackets",
  "clippy::cast_possible_truncation",
]

and I run cargo cranky, I get those extra lints:

warning: found empty brackets on struct declaration
  --> src/main.rs:11:12
   |
11 | struct Unit {}
   |            ^^^
warning: casting `u64` to `u8` may truncate the value
  --> src/main.rs:23:9
   |
23 |         x as u8

This is exactly the same as manually running cargo clippy with the extra parameters --warn clippy::empty_structs_with_brackets and --warn clippy::cast_possible_truncation.

You may find some useful clippy lints for your project in the clippy documentation. I recommend browsing the "pedantic" and "restriction" groups.

Installing

cargo install cargo-cranky

Configuring

Create a file called Cranky.toml at the top of your project tree. The file can contain keys allow, warn, or deny that contain an array of clippy lint names.

Example:

deny = [
  # My crate should never need unsafe code.
  "unsafe_code",
]

warn = [
  "clippy::empty_structs_with_brackets",
  "clippy::cast_possible_truncation",
]

allow = [
  "clippy::double_comparisons",
]

Note: in the case of overlap, allow will always override warn, which in turn will always override deny. The order of these fields in Cranky.toml has no effect.

FAQ

Can I specify non-clippy lints?

Yes! Try for example unsafe_code or missing_docs.

Note: Clippy lints should be specified using the long syntax, e.g. clippy::some_lint_name. Clippy will issue a warning if the prefix is missing.

Does it work with vscode?

Yes! Just type cranky into the "Check On Save: Command" setting, or drop this into settings.json:

{
    "rust-analyzer.checkOnSave.command": "cranky"
}

Set it back to "check" (or "clippy") to return to the previous behavior.

Is this reckless or non-idiomatic?

That depends on how you use it. If your goal is to enforce a non-idiomatic coding style, that's probably not a great idea.

If you want to suppress lints that are enabled by default, it's probably better to do that using the #[allow(clippy::some_lint)] syntax in the source file, since that gives you a chance to add a comment explaining your reasoning.

The main goal of this tool is to make it easier to enable additional clippy lints, that improve code maintainability or safety (i.e. clippy::cast_possible_truncation).

I have complaints suggestions!

Please file a GitHub issue if you have ideas that could make this tool better.

Comments
  • Non-clippy lints

    Non-clippy lints

    Thanks for cargo cranky!

    There are lints outside of clippy that I often enable, for instance:

        "-Dunsafe_code",
        "-Wfuture_incompatible",
        "-Wnonstandard_style",
        "-Wrust_2018_idioms",
        "-Wrustdoc::missing_crate_level_docs",
        "-Wsemicolon_in_expressions_from_macros",
        "-Wtrivial_casts",
        "-Wtrivial_numeric_casts",
        "-Wunused_extern_crates",
        "-Wunused_import_braces",
    

    It would be wonderful if Cranky could handle these non-clippy lints as well, as then it would be a very good solution to https://github.com/rust-lang/cargo/issues/5034


    Currently I enable clippy and non-clippy lints in .cargo/config.toml (https://github.com/emilk/egui/blob/e76c919c7e70c208c9a6209b9fe3369e7b6db99d/.cargo/config.toml) but it is a bit of a hack and has some problems (https://github.com/emilk/egui/issues/1439).

    opened by emilk 3
  • Fix severity ordering, allow non-clippy lints, use short-form args

    Fix severity ordering, allow non-clippy lints, use short-form args

    wrt severity ordering, the allow section would do nothing if the warn/deny section was smth like clippy::all

    all lints would have to be specified as clippy::xxxx but otherwise you need special-case handling if you want to configure non-clippy lints

    opened by Awpteamoose 2
  • Integrating configuration into `Cargo.toml`

    Integrating configuration into `Cargo.toml`

    Recently I was getting annoyed at how many metadata files are in the root of my workspace. To combat this issue it feels like tooling that is completely cargo-focused like this should really be storing its configuration in the Cargo.toml. The example from the readme could look like:

    [workspace.metadata.lints]
    warn = [
      "clippy::empty_structs_with_brackets",
      "clippy::cast_possible_truncation",
    ]
    

    This could also support some of the usecases from #3 easily. The lints could be merged from workspace.metadata.lints and package.metadata.lints to support crate-specific overrides.

    opened by Nemo157 1
  • Support `rustdoc::` lints

    Support `rustdoc::` lints

    Currently if I put "rustdoc::missing_crate_level_docs" in warn in Cranky.toml it does nothing.

    …though honestly I don't understand the rustdoc lints. cargo clippy -- -D rustdoc::missing_crate_level_docs runs without warnings when there are missing crate level docs.

    opened by emilk 4
  • Somehow specify rules for #![doc(test(attr( ... )))] ?

    Somehow specify rules for #![doc(test(attr( ... )))] ?

    I don't know if it is possible but all my projects maintain slightly adjusted lint rules for doc-tests, specifically:

    #![doc(test(attr(deny(future_incompatible, rust_2018_idioms, warnings))))]
    #![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
    

    Ideally this tool would be able to provide that as well but I feel like that is probably not possible.

    opened by Fishrock123 0
  • Override global rules from in-source attributes?

    Override global rules from in-source attributes?

    Similar to what was mentioned in https://github.com/ericseppanen/cargo-cranky/issues/3#issue-1298199372, but a little different. Perhaps that issue exists because this is just impossible.

    I'd like to be able to use this tool, but with a blanket set of fairly "aggressive" rules across an entire organization.

    Sometimes, like in the case of clippy::print_stdout this is appropriate for most projects (encourage folks to use the log crate), but I may want to disable it fro a CLI tool. Ideally I'd like to not have to adjust the project or workspace level Cranky.toml (since it may be automated). So, i'm hoping there would be a way to set an override from an in-code attribute, since that seems the most reasonable place to have such a thing...

    See also https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Have.20in-code.20lint.20attributes.20have.20higher.20precidence.20than.20.2E.2E.2E/near/291373867

    opened by Fishrock123 4
  • idea: support for multiple config files

    idea: support for multiple config files

    "Multiple config files" might be a can of worms, but I could see a few different ways this could be useful:

    • I have a set of aggressive lints I usually use, but I have one crate that needs to disable a few of those because they're just not appropriate for this crate.
    • I have a standard set of lints I use for everything, but my projects don't share a common filesystem tree so I'd like my Cranky.toml file to live in my home directory.

    Maybe this could be supported by having a "fall_through = true" config flag in Cranky.toml; when found we keep searching for additional Cranky.toml files (and merge their contents intelligently). And then when we reach the filesystem root we check in ~/.Cranky.toml also.

    opened by ericseppanen 2
  • idea: smart handling of new lints

    idea: smart handling of new lints

    If I use a new clippy lint in Cranky.toml, but someone else hasn't moved to that Rust version yet, they will get an "unknown lint" error.

    If I don't want to bump the crate's minimum supported Rust version, I should be able to add that lint anyway-- and cargo cranky should be able to observe what stable release I'm on and disable lints that are too new.

    Would this require hardcoding a list of clippy lints and the version when they landed? That sounds a bit hard to keep up with.

    opened by ericseppanen 0
Releases(v0.3.0)
  • v0.3.0(Jul 8, 2022)

    • Fix severity ordering so allow always overrides warn or deny.
    • Support non-clippy lints; requires full lint names, e.g. clippy::lint_name.
    Source code(tar.gz)
    Source code(zip)
Owner
Eric Seppanen
Rust Engineer. Refugee from memory corruption bugs.
Eric Seppanen
Shell Of A New Machine: Quickly configure new environments

Shell Of A New Machine soanm is a dead-simple tool for easily configuring new UNIX machines, with almost zero prerequisites on the target machine. All

Ben Weinstein-Raun 41 Dec 22, 2022
custom Rust clippy lints

How to use my_lints to static analysis other rust project export MY_LINTS_PATH=/home/w/repos/my_repos/my_lints method_1: In my_lints dir cd $MY_LINTS_

Wu Aoxiang 3 Oct 2, 2021
custom rustc/clippy lint framwork

custom rustc lints How to run first need to install binary form source code: cargo install --path . and then in rust project directory you want to ana

Wu Aoxiang 4 Apr 1, 2022
fail CI on rustc and clippy warnings without breakage

A crate + github actions template that fails CI on rustc and clippy warnings without breakage.

Lucas Kent 1 Jan 2, 2022
Rust-clippy - A bunch of lints to catch common mistakes and improve your Rust code

Clippy A collection of lints to catch common mistakes and improve your Rust code. There are over 450 lints included in this crate! Lints are divided i

The Rust Programming Language 8.7k Dec 31, 2022
Converts cargo check (and clippy) JSON output to the GitHub Action error format

cargo-action-fmt Takes JSON-formatted cargo check (and cargo clippy) output and formats it for GitHub actions. Examples This tool can be used with a v

Oliver Gould 8 Oct 12, 2022
Easy-to-use wrapper for WebRTC DataChannels peer-to-peer connections written in Rust and compiling to WASM.

Easy-to-use wrapper for WebRTC DataChannels peer-to-peer connections written in Rust and compiling to WASM.

null 58 Dec 11, 2022
Trulang is an interpreted language that is designed to be a simple, easy to learn, and easy to use programming language.

Trulang is an interpreted language that is designed to be a simple, easy to learn, and easy to use programming language.

Bunch-of-cells 2 Nov 23, 2022
A parallel universal-ctags wrapper for git repository

ptags A parallel universal-ctags wrapper for git repository Description ptags is a universal-ctags wrapper to have the following features. Search git

null 107 Dec 30, 2022
Zero-cost high-level lua 5.3 wrapper for Rust

td_rlua This library is a high-level binding for Lua 5.3. You don't have access to the Lua stack, all you can do is read/write variables (including ca

null 47 May 4, 2022
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
A low-level ncurses wrapper for Rust

ncurses-rs This is a very thin wrapper around the ncurses TUI lib. NOTE: The ncurses lib is terribly unsafe and ncurses-rs is only the lightest wrappe

Jeaye Wilkerson 628 Jan 7, 2023
Rust wrapper for ArrayFire

Arrayfire Rust Bindings ArrayFire is a high performance library for parallel computing with an easy-to-use API. It enables users to write scientific c

ArrayFire 696 Dec 30, 2022
rust wrapper for rocksdb

rust-rocksdb Requirements Clang and LLVM Contributing Feedback and pull requests welcome! If a particular feature of RocksDB is important to you, plea

null 1.3k Dec 30, 2022
UnQLite wrapper 1.0 is avaliable for Rust

unqlite A high-level UnQLite database engine wrapper. NOTE: Some of the documents is stolen from UnQLite Official Website. What is UnQLite? UnQLite is

Huo Linhe 101 Dec 12, 2022
libhdfs binding and wrapper APIs for Rust

hdfs-rs libhdfs binding library and rust APIs which safely wraps libhdfs binding APIs Current Status Alpha Status (Rust wrapping APIs can be changed)

Hyunsik Choi 32 Dec 1, 2022
A Rust wrapper and bindings of Allegro 5 game programming library

RustAllegro A thin Rust wrapper of Allegro 5. Game loop example extern crate allegro; extern crate allegro_font; use allegro::*; use allegro_font::*;

null 80 Dec 31, 2022
Safe OpenGL wrapper for the Rust language.

glium Note to current and future Glium users: Glium is no longer actively developed by its original author. That said, PRs are still welcome and maint

null 3.1k Jan 1, 2023
GLFW3 bindings and idiomatic wrapper for Rust.

glfw-rs GLFW bindings and wrapper for The Rust Programming Language. Example extern crate glfw; use glfw::{Action, Context, Key}; fn main() { le

PistonDevelopers 546 Jan 3, 2023
Safe and rich Rust wrapper around the Vulkan API

Vulkano See also vulkano.rs. Vulkano is a Rust wrapper around the Vulkan graphics API. It follows the Rust philosophy, which is that as long as you do

null 3.6k Jan 3, 2023