From 37ec89f3fd4741bbc98b8537ec6c7e2375e49e4e Mon Sep 17 00:00:00 2001 From: xFrednet Date: Fri, 26 Jul 2024 09:39:31 +0200 Subject: [PATCH 1/3] Lintcheck: Fix `lintcheck --fix` --- lintcheck/src/config.rs | 9 +++++++-- lintcheck/src/input.rs | 2 +- lintcheck/src/main.rs | 33 +++++++++++++++++++++++++++------ lintcheck/src/recursive.rs | 1 + 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index 6bec1753fc7b..ac82d96da1dd 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -30,8 +30,13 @@ pub(crate) struct LintcheckConfig { /// Only process a single crate on the list #[clap(long, value_name = "CRATE")] pub only: Option, - /// Runs cargo clippy --fix and checks if all suggestions apply - #[clap(long, conflicts_with("max_jobs"))] + /// Runs cargo clippy --fix and checks if all suggestions apply. + #[clap( + long, + conflicts_with("max_jobs"), + conflicts_with("warn_all"), + conflicts_with("recursive") + )] pub fix: bool, /// Apply a filter to only collect specified lints, this also overrides `allow` attributes #[clap(long = "filter", value_name = "clippy_lint_name", use_value_delimiter = true)] diff --git a/lintcheck/src/input.rs b/lintcheck/src/input.rs index 3b263674aa87..14956fe88c22 100644 --- a/lintcheck/src/input.rs +++ b/lintcheck/src/input.rs @@ -180,7 +180,7 @@ impl CrateWithSource { /// copies a local folder #[expect(clippy::too_many_lines)] fn download_and_extract(&self) -> Crate { - #[allow(clippy::result_large_err)] + #[expect(clippy::result_large_err)] fn get(path: &str) -> Result { const MAX_RETRIES: u8 = 4; let mut retries = 0; diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 0dd62ded293c..b414cd17327c 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -116,11 +116,36 @@ impl Crate { clippy_args.extend(lint_levels_args.iter().map(String::as_str)); let mut cmd = Command::new("cargo"); - cmd.arg(if config.fix { "fix" } else { "check" }) - .arg("--quiet") + + if config.fix { + cmd.arg("fix"); + cmd.arg("--allow-no-vcs"); + // Fix should never be run in combination with `--recursive`. This + // should never happen as the CLI flags conflict, but you know life. + assert!( + server.is_none(), + "--fix was combined with `--recursive`. Server: {server:#?}" + ); + } else { + cmd.arg("check"); + cmd.arg("--message-format=json"); + } + + // It turns out that `cargo fix` by default runs all tests, benchmarks, + // and examples. This is different from `cargo check` which only runs the + // main packages. The `--tests` works for both `cargo fix` and `cargo check` + // to indicate that only the main packages and tests should be processed. + // This unifies the behavior between the different lintcheck modes. + // + // It also makes sense to include tests either way, since some Clippy lints + // have custom behavior in test code. + cmd.arg("--tests"); + + cmd.arg("--quiet") .current_dir(&self.path) .env("CLIPPY_ARGS", clippy_args.join("__CLIPPY_HACKERY__")); + // This is only used for `--recursive` if let Some(server) = server { // `cargo clippy` is a wrapper around `cargo check` that mainly sets `RUSTC_WORKSPACE_WRAPPER` to // `clippy-driver`. We do the same thing here with a couple changes: @@ -145,10 +170,6 @@ impl Crate { return Vec::new(); }; - if !config.fix { - cmd.arg("--message-format=json"); - } - let shared_target_dir = shared_target_dir(&format!("_{thread_index:?}")); let all_output = cmd // use the looping index to create individual target dirs diff --git a/lintcheck/src/recursive.rs b/lintcheck/src/recursive.rs index 6a662970ae84..00202a85f8b2 100644 --- a/lintcheck/src/recursive.rs +++ b/lintcheck/src/recursive.rs @@ -79,6 +79,7 @@ fn process_stream( } } +#[derive(Debug)] pub(crate) struct LintcheckServer { pub local_addr: SocketAddr, receiver: Receiver, From 4fabd75e169d8cc57a704e7f78d29da6ce4633a4 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Fri, 26 Jul 2024 13:13:12 +0200 Subject: [PATCH 2/3] Lintcheck: Add `mode` config for crates --- lintcheck/ci_crates.toml | 400 ++++++++++++++++---------------- lintcheck/lintcheck_crates.toml | 50 ++-- lintcheck/src/input.rs | 17 +- lintcheck/src/json.rs | 2 + lintcheck/src/main.rs | 47 +++- 5 files changed, 279 insertions(+), 237 deletions(-) diff --git a/lintcheck/ci_crates.toml b/lintcheck/ci_crates.toml index 9e3dbef6a9e7..7675fa574990 100644 --- a/lintcheck/ci_crates.toml +++ b/lintcheck/ci_crates.toml @@ -1,208 +1,208 @@ [crates] # Binaries projects -cargo = {name = "cargo", version = '0.64.0', online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}'} -ripgrep = {name = "ripgrep", version = '14.1.0'} -bat = {name = "bat", version = '0.24.0'} -fend = {name = "fend", version = '1.5.0'} -mdbook = {name = "mdbook", version = '0.4.40'} +cargo = { name = 'cargo', version = '0.64.0', mode = 'bin', online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}' } +ripgrep = { name = 'ripgrep', version = '14.1.0', mode = 'bin' } +bat = { name = 'bat', version = '0.24.0', mode = 'bin' } +fend = { name = 'fend', version = '1.5.0', mode = 'bin' } +mdbook = { name = 'mdbook', version = '0.4.40', mode = 'bin' } # Bigger crates from ICE issues: -wasmi = {name = "wasmi", version = '0.35.0'} -wgpu = {name = "wgpu", version = '0.20.1'} -bytes = {name = "bytes", version = '1.6.1'} -skrifa = {name = "skrifa", version = '0.19.3'} +wasmi = { name = 'wasmi', version = '0.35.0', mode = 'lib' } +wgpu = { name = 'wgpu', version = '0.20.1', mode = 'lib' } +bytes = { name = 'bytes', version = '1.6.1', mode = 'lib' } +skrifa = { name = 'skrifa', version = '0.19.3', mode = 'lib' } # Random crates which are part of the default test set -puffin = {name = "puffin", version = '0.19.0'} +puffin = { name = 'puffin', version = '0.19.0', mode = 'lib' } # Top ~200 crates from crates.io -syn = { name = 'syn', version = '2.0.71' } -bitflags = { name = 'bitflags', version = '2.6.0' } -hashbrown = { name = 'hashbrown', version = '0.14.5' } -base64 = { name = 'base64', version = '0.22.1' } -regex-syntax = { name = 'regex-syntax', version = '0.8.4' } -proc-macro2 = { name = 'proc-macro2', version = '1.0.86' } -indexmap = { name = 'indexmap', version = '2.2.6' } -quote = { name = 'quote', version = '1.0.36' } -regex-automata = { name = 'regex-automata', version = '0.4.7' } -libc = { name = 'libc', version = '0.2.155' } -serde = { name = 'serde', version = '1.0.204' } -itertools = { name = 'itertools', version = '0.13.0' } -heck = { name = 'heck', version = '0.5.0' } -memchr = { name = 'memchr', version = '2.7.4' } -serde_derive = { name = 'serde_derive', version = '1.0.204' } -unicode-ident = { name = 'unicode-ident', version = '1.0.12' } -autocfg = { name = 'autocfg', version = '1.3.0' } -cfg-if = { name = 'cfg-if', version = '1.0.0' } -aho-corasick = { name = 'aho-corasick', version = '1.1.3' } -getrandom = { name = 'getrandom', version = '0.2.15' } -rand_core = { name = 'rand_core', version = '0.6.4' } -serde_json = { name = 'serde_json', version = '1.0.120' } -itoa = { name = 'itoa', version = '1.0.11' } -rand = { name = 'rand', version = '0.8.5' } -ryu = { name = 'ryu', version = '1.0.18' } -once_cell = { name = 'once_cell', version = '1.19.0' } -rustix = { name = 'rustix', version = '0.38.34' } -regex = { name = 'regex', version = '1.10.5' } -log = { name = 'log', version = '0.4.22' } -parking_lot_core = { name = 'parking_lot_core', version = '0.9.10' } -cc = { name = 'cc', version = '1.1.5' } -strsim = { name = 'strsim', version = '0.11.1' } -clap = { name = 'clap', version = '4.5.9' } -parking_lot = { name = 'parking_lot', version = '0.12.3' } -smallvec = { name = 'smallvec', version = '2.0.0-alpha.6' } -thiserror-impl = { name = 'thiserror-impl', version = '1.0.63' } -thiserror = { name = 'thiserror', version = '1.0.63' } -linux-raw-sys = { name = 'linux-raw-sys', version = '0.6.4' } -socket2 = { name = 'socket2', version = '0.5.7' } -idna = { name = 'idna', version = '1.0.2' } -fastrand = { name = 'fastrand', version = '2.1.0' } -either = { name = 'either', version = '1.13.0' } -num-traits = { name = 'num-traits', version = '0.2.19' } -rand_chacha = { name = 'rand_chacha', version = '0.3.1' } -lazy_static = { name = 'lazy_static', version = '1.5.0' } -semver = { name = 'semver', version = '1.0.23' } -lock_api = { name = 'lock_api', version = '0.4.12' } -scopeguard = { name = 'scopeguard', version = '1.2.0' } -ahash = { name = 'ahash', version = '0.8.11' } -anyhow = { name = 'anyhow', version = '1.0.86' } -rustls = { name = 'rustls', version = '0.23.11' } -http = { name = 'http', version = '1.1.0' } -toml_edit = { name = 'toml_edit', version = '0.22.16' } -pin-project-lite = { name = 'pin-project-lite', version = '0.2.14' } -spin = { name = 'spin', version = '0.9.8' } -miniz_oxide = { name = 'miniz_oxide', version = '0.7.4' } -memoffset = { name = 'memoffset', version = '0.9.1' } -digest = { name = 'digest', version = '0.11.0-pre.8' } -version_check = { name = 'version_check', version = '0.9.4' } -clap_lex = { name = 'clap_lex', version = '0.7.1' } -crossbeam-utils = { name = 'crossbeam-utils', version = '0.8.20' } -toml = { name = 'toml', version = '0.8.15' } -block-buffer = { name = 'block-buffer', version = '0.10.4' } -time = { name = 'time', version = '0.3.36' } -hyper = { name = 'hyper', version = '1.4.1' } -url = { name = 'url', version = '2.5.2' } -percent-encoding = { name = 'percent-encoding', version = '2.3.1' } -tokio = { name = 'tokio', version = '1.38.1' } -errno = { name = 'errno', version = '0.3.9' } -uuid = { name = 'uuid', version = '1.10.0' } -unicode-normalization = { name = 'unicode-normalization', version = '0.1.23' } -ppv-lite86 = { name = 'ppv-lite86', version = '0.2.17' } -futures-core = { name = 'futures-core', version = '0.3.30' } -http-body = { name = 'http-body', version = '1.0.1' } -tinyvec = { name = 'tinyvec', version = '1.8.0' } -futures-util = { name = 'futures-util', version = '0.3.30' } -futures-task = { name = 'futures-task', version = '0.3.30' } -sha2 = { name = 'sha2', version = '0.11.0-pre.3' } -ring = { name = 'ring', version = '0.17.8' } -slab = { name = 'slab', version = '0.4.9' } -chrono = { name = 'chrono', version = '0.4.38' } -futures-sink = { name = 'futures-sink', version = '0.3.30' } -futures-channel = { name = 'futures-channel', version = '0.3.30' } -num_cpus = { name = 'num_cpus', version = '1.16.0' } -untrusted = { name = 'untrusted', version = '0.9.0' } -tinyvec_macros = { name = 'tinyvec_macros', version = '0.1.1' } -mio = { name = 'mio', version = '1.0.0' } -byteorder = { name = 'byteorder', version = '1.5.0' } -form_urlencoded = { name = 'form_urlencoded', version = '1.2.1' } -unicode-bidi = { name = 'unicode-bidi', version = '0.3.15' } -futures-io = { name = 'futures-io', version = '0.3.30' } -tokio-util = { name = 'tokio-util', version = '0.7.11' } -rustls-pemfile = { name = 'rustls-pemfile', version = '2.1.2' } -generic-array = { name = 'generic-array', version = '1.1.0' } -tracing = { name = 'tracing', version = '0.1.40' } -equivalent = { name = 'equivalent', version = '1.0.1' } -tracing-core = { name = 'tracing-core', version = '0.1.32' } -pin-utils = { name = 'pin-utils', version = '0.1.0' } -tempfile = { name = 'tempfile', version = '3.10.1' } -h2 = { name = 'h2', version = '0.4.5' } -futures = { name = 'futures', version = '0.3.30' } -typenum = { name = 'typenum', version = '1.17.0' } -winnow = { name = 'winnow', version = '0.6.13' } -cpufeatures = { name = 'cpufeatures', version = '0.2.12' } -nix = { name = 'nix', version = '0.29.0' } -fnv = { name = 'fnv', version = '1.0.7' } -tokio-rustls = { name = 'tokio-rustls', version = '0.26.0' } -iana-time-zone = { name = 'iana-time-zone', version = '0.1.60' } -rustls-webpki = { name = 'rustls-webpki', version = '0.102.5' } -crc32fast = { name = 'crc32fast', version = '1.4.2' } -adler = { name = 'adler', version = '1.0.2' } -pkg-config = { name = 'pkg-config', version = '0.3.30' } -redox_syscall = { name = 'redox_syscall', version = '0.5.3' } -nom = { name = 'nom', version = '8.0.0-alpha2' } -rustc_version = { name = 'rustc_version', version = '0.4.0' } -futures-macro = { name = 'futures-macro', version = '0.3.30' } -clap_derive = { name = 'clap_derive', version = '4.5.8' } -futures-executor = { name = 'futures-executor', version = '0.3.30' } -event-listener = { name = 'event-listener', version = '5.3.1' } -num-integer = { name = 'num-integer', version = '0.1.46' } -time-macros = { name = 'time-macros', version = '0.2.18' } -flate2 = { name = 'flate2', version = '1.0.30' } -tokio-macros = { name = 'tokio-macros', version = '2.3.0' } -strum_macros = { name = 'strum_macros', version = '0.26.4' } -tracing-attributes = { name = 'tracing-attributes', version = '0.1.27' } -async-trait = { name = 'async-trait', version = '0.1.81' } -crypto-common = { name = 'crypto-common', version = '0.1.6' } -unicode-width = { name = 'unicode-width', version = '0.1.13' } -anstyle = { name = 'anstyle', version = '1.0.7' } -object = { name = 'object', version = '0.36.1' } -gimli = { name = 'gimli', version = '0.31.0' } -crossbeam-epoch = { name = 'crossbeam-epoch', version = '0.9.18' } -thread_local = { name = 'thread_local', version = '1.1.8' } -strum = { name = 'strum', version = '0.26.3' } -darling_core = { name = 'darling_core', version = '0.20.10' } -darling_macro = { name = 'darling_macro', version = '0.20.10' } -minimal-lexical = { name = 'minimal-lexical', version = '0.2.1' } -clap_builder = { name = 'clap_builder', version = '4.5.9' } -time-core = { name = 'time-core', version = '0.1.2' } -httparse = { name = 'httparse', version = '1.9.4' } -signal-hook-registry = { name = 'signal-hook-registry', version = '1.4.2' } -hex = { name = 'hex', version = '0.4.3' } -crossbeam-deque = { name = 'crossbeam-deque', version = '0.8.5' } -zerocopy = { name = 'zerocopy', version = '0.7.35' } -rustversion = { name = 'rustversion', version = '1.0.17' } -env_logger = { name = 'env_logger', version = '0.11.3' } -webpki-roots = { name = 'webpki-roots', version = '0.26.3' } -rustc-demangle = { name = 'rustc-demangle', version = '0.1.24' } -mime = { name = 'mime', version = '0.3.17' } -termcolor = { name = 'termcolor', version = '1.4.1' } -subtle = { name = 'subtle', version = '2.6.1' } -walkdir = { name = 'walkdir', version = '2.5.0' } -hermit-abi = { name = 'hermit-abi', version = '0.4.0' } -pin-project = { name = 'pin-project', version = '1.1.5' } -pin-project-internal = { name = 'pin-project-internal', version = '1.1.5' } -try-lock = { name = 'try-lock', version = '0.2.5' } -tracing-log = { name = 'tracing-log', version = '0.2.0' } -httpdate = { name = 'httpdate', version = '1.0.3' } -anstream = { name = 'anstream', version = '0.6.14' } -crossbeam-channel = { name = 'crossbeam-channel', version = '0.5.13' } -reqwest = { name = 'reqwest', version = '0.12.5' } -want = { name = 'want', version = '0.3.1' } -paste = { name = 'paste', version = '1.0.15' } -anstyle-parse = { name = 'anstyle-parse', version = '0.2.4' } -toml_datetime = { name = 'toml_datetime', version = '0.6.6' } -anstyle-query = { name = 'anstyle-query', version = '1.1.0' } -addr2line = { name = 'addr2line', version = '0.24.0' } -glob = { name = 'glob', version = '0.3.1' } -num-bigint = { name = 'num-bigint', version = '0.4.6' } -backtrace = { name = 'backtrace', version = '0.3.73' } -wasi = { name = 'wasi', version = '0.13.1+wasi-0.2.0' } -tower-service = { name = 'tower-service', version = '0.3.2' } -sync_wrapper = { name = 'sync_wrapper', version = '1.0.1' } -libloading = { name = 'libloading', version = '0.8.4' } -rayon = { name = 'rayon', version = '1.10.0' } -colorchoice = { name = 'colorchoice', version = '1.0.1' } -encoding_rs = { name = 'encoding_rs', version = '0.8.34' } -deranged = { name = 'deranged', version = '0.3.11' } -zeroize = { name = 'zeroize', version = '1.8.1' } -utf8parse = { name = 'utf8parse', version = '0.2.2' } -tracing-subscriber = { name = 'tracing-subscriber', version = '0.3.18' } -hyper-rustls = { name = 'hyper-rustls', version = '0.27.2' } -hmac = { name = 'hmac', version = '0.13.0-pre.3' } -rayon-core = { name = 'rayon-core', version = '1.12.1' } -same-file = { name = 'same-file', version = '1.0.6' } -prost = { name = 'prost', version = '0.13.1' } -sharded-slab = { name = 'sharded-slab', version = '0.1.7' } -textwrap = { name = 'textwrap', version = '0.16.1' } -bumpalo = {name = "bumpalo", version = '3.16.0'} -arrayvec = { name = 'arrayvec', version = '0.7.4' } +syn = { name = 'syn', version = '2.0.71' , mode = 'lib' } +bitflags = { name = 'bitflags', version = '2.6.0' , mode = 'lib' } +hashbrown = { name = 'hashbrown', version = '0.14.5' , mode = 'lib' } +base64 = { name = 'base64', version = '0.22.1' , mode = 'lib' } +regex-syntax = { name = 'regex-syntax', version = '0.8.4' , mode = 'lib' } +proc-macro2 = { name = 'proc-macro2', version = '1.0.86' , mode = 'lib' } +indexmap = { name = 'indexmap', version = '2.2.6' , mode = 'lib' } +quote = { name = 'quote', version = '1.0.36' , mode = 'lib' } +regex-automata = { name = 'regex-automata', version = '0.4.7' , mode = 'lib' } +libc = { name = 'libc', version = '0.2.155' , mode = 'lib' } +serde = { name = 'serde', version = '1.0.204' , mode = 'lib' } +itertools = { name = 'itertools', version = '0.13.0' , mode = 'lib' } +heck = { name = 'heck', version = '0.5.0' , mode = 'lib' } +memchr = { name = 'memchr', version = '2.7.4' , mode = 'lib' } +serde_derive = { name = 'serde_derive', version = '1.0.204' , mode = 'lib' } +unicode-ident = { name = 'unicode-ident', version = '1.0.12' , mode = 'lib' } +autocfg = { name = 'autocfg', version = '1.3.0' , mode = 'lib' } +cfg-if = { name = 'cfg-if', version = '1.0.0' , mode = 'lib' } +aho-corasick = { name = 'aho-corasick', version = '1.1.3' , mode = 'lib' } +getrandom = { name = 'getrandom', version = '0.2.15' , mode = 'lib' } +rand_core = { name = 'rand_core', version = '0.6.4' , mode = 'lib' } +serde_json = { name = 'serde_json', version = '1.0.120' , mode = 'lib' } +itoa = { name = 'itoa', version = '1.0.11' , mode = 'lib' } +rand = { name = 'rand', version = '0.8.5' , mode = 'lib' } +ryu = { name = 'ryu', version = '1.0.18' , mode = 'lib' } +once_cell = { name = 'once_cell', version = '1.19.0' , mode = 'lib' } +rustix = { name = 'rustix', version = '0.38.34' , mode = 'lib' } +regex = { name = 'regex', version = '1.10.5' , mode = 'lib' } +log = { name = 'log', version = '0.4.22' , mode = 'lib' } +parking_lot_core = { name = 'parking_lot_core', version = '0.9.10' , mode = 'lib' } +cc = { name = 'cc', version = '1.1.5' , mode = 'lib' } +strsim = { name = 'strsim', version = '0.11.1' , mode = 'lib' } +clap = { name = 'clap', version = '4.5.9' , mode = 'lib' } +parking_lot = { name = 'parking_lot', version = '0.12.3' , mode = 'lib' } +smallvec = { name = 'smallvec', version = '2.0.0-alpha.6' , mode = 'lib' } +thiserror-impl = { name = 'thiserror-impl', version = '1.0.63' , mode = 'lib' } +thiserror = { name = 'thiserror', version = '1.0.63' , mode = 'lib' } +linux-raw-sys = { name = 'linux-raw-sys', version = '0.6.4' , mode = 'lib' } +socket2 = { name = 'socket2', version = '0.5.7' , mode = 'lib' } +idna = { name = 'idna', version = '1.0.2' , mode = 'lib' } +fastrand = { name = 'fastrand', version = '2.1.0' , mode = 'lib' } +either = { name = 'either', version = '1.13.0' , mode = 'lib' } +num-traits = { name = 'num-traits', version = '0.2.19' , mode = 'lib' } +rand_chacha = { name = 'rand_chacha', version = '0.3.1' , mode = 'lib' } +lazy_static = { name = 'lazy_static', version = '1.5.0' , mode = 'lib' } +semver = { name = 'semver', version = '1.0.23' , mode = 'lib' } +lock_api = { name = 'lock_api', version = '0.4.12' , mode = 'lib' } +scopeguard = { name = 'scopeguard', version = '1.2.0' , mode = 'lib' } +ahash = { name = 'ahash', version = '0.8.11' , mode = 'lib' } +anyhow = { name = 'anyhow', version = '1.0.86' , mode = 'lib' } +rustls = { name = 'rustls', version = '0.23.11' , mode = 'lib' } +http = { name = 'http', version = '1.1.0' , mode = 'lib' } +toml_edit = { name = 'toml_edit', version = '0.22.16' , mode = 'lib' } +pin-project-lite = { name = 'pin-project-lite', version = '0.2.14' , mode = 'lib' } +spin = { name = 'spin', version = '0.9.8' , mode = 'lib' } +miniz_oxide = { name = 'miniz_oxide', version = '0.7.4' , mode = 'lib' } +memoffset = { name = 'memoffset', version = '0.9.1' , mode = 'lib' } +digest = { name = 'digest', version = '0.11.0-pre.8' , mode = 'lib' } +version_check = { name = 'version_check', version = '0.9.4' , mode = 'lib' } +clap_lex = { name = 'clap_lex', version = '0.7.1' , mode = 'lib' } +crossbeam-utils = { name = 'crossbeam-utils', version = '0.8.20' , mode = 'lib' } +toml = { name = 'toml', version = '0.8.15' , mode = 'lib' } +block-buffer = { name = 'block-buffer', version = '0.10.4' , mode = 'lib' } +time = { name = 'time', version = '0.3.36' , mode = 'lib' } +hyper = { name = 'hyper', version = '1.4.1' , mode = 'lib' } +url = { name = 'url', version = '2.5.2' , mode = 'lib' } +percent-encoding = { name = 'percent-encoding', version = '2.3.1' , mode = 'lib' } +tokio = { name = 'tokio', version = '1.38.1' , mode = 'lib' } +errno = { name = 'errno', version = '0.3.9' , mode = 'lib' } +uuid = { name = 'uuid', version = '1.10.0' , mode = 'lib' } +unicode-normalization = { name = 'unicode-normalization', version = '0.1.23' , mode = 'lib' } +ppv-lite86 = { name = 'ppv-lite86', version = '0.2.17' , mode = 'lib' } +futures-core = { name = 'futures-core', version = '0.3.30' , mode = 'lib' } +http-body = { name = 'http-body', version = '1.0.1' , mode = 'lib' } +tinyvec = { name = 'tinyvec', version = '1.8.0' , mode = 'lib' } +futures-util = { name = 'futures-util', version = '0.3.30' , mode = 'lib' } +futures-task = { name = 'futures-task', version = '0.3.30' , mode = 'lib' } +sha2 = { name = 'sha2', version = '0.11.0-pre.3' , mode = 'lib' } +ring = { name = 'ring', version = '0.17.8' , mode = 'lib' } +slab = { name = 'slab', version = '0.4.9' , mode = 'lib' } +chrono = { name = 'chrono', version = '0.4.38' , mode = 'lib' } +futures-sink = { name = 'futures-sink', version = '0.3.30' , mode = 'lib' } +futures-channel = { name = 'futures-channel', version = '0.3.30' , mode = 'lib' } +num_cpus = { name = 'num_cpus', version = '1.16.0' , mode = 'lib' } +untrusted = { name = 'untrusted', version = '0.9.0' , mode = 'lib' } +tinyvec_macros = { name = 'tinyvec_macros', version = '0.1.1' , mode = 'lib' } +mio = { name = 'mio', version = '1.0.0' , mode = 'lib' } +byteorder = { name = 'byteorder', version = '1.5.0' , mode = 'lib' } +form_urlencoded = { name = 'form_urlencoded', version = '1.2.1' , mode = 'lib' } +unicode-bidi = { name = 'unicode-bidi', version = '0.3.15' , mode = 'lib' } +futures-io = { name = 'futures-io', version = '0.3.30' , mode = 'lib' } +tokio-util = { name = 'tokio-util', version = '0.7.11' , mode = 'lib' } +rustls-pemfile = { name = 'rustls-pemfile', version = '2.1.2' , mode = 'lib' } +generic-array = { name = 'generic-array', version = '1.1.0' , mode = 'lib' } +tracing = { name = 'tracing', version = '0.1.40' , mode = 'lib' } +equivalent = { name = 'equivalent', version = '1.0.1' , mode = 'lib' } +tracing-core = { name = 'tracing-core', version = '0.1.32' , mode = 'lib' } +pin-utils = { name = 'pin-utils', version = '0.1.0' , mode = 'lib' } +tempfile = { name = 'tempfile', version = '3.10.1' , mode = 'lib' } +h2 = { name = 'h2', version = '0.4.5' , mode = 'lib' } +futures = { name = 'futures', version = '0.3.30' , mode = 'lib' } +typenum = { name = 'typenum', version = '1.17.0' , mode = 'lib' } +winnow = { name = 'winnow', version = '0.6.13' , mode = 'lib' } +cpufeatures = { name = 'cpufeatures', version = '0.2.12' , mode = 'lib' } +nix = { name = 'nix', version = '0.29.0' , mode = 'lib' } +fnv = { name = 'fnv', version = '1.0.7' , mode = 'lib' } +tokio-rustls = { name = 'tokio-rustls', version = '0.26.0' , mode = 'lib' } +iana-time-zone = { name = 'iana-time-zone', version = '0.1.60' , mode = 'lib' } +rustls-webpki = { name = 'rustls-webpki', version = '0.102.5' , mode = 'lib' } +crc32fast = { name = 'crc32fast', version = '1.4.2' , mode = 'lib' } +adler = { name = 'adler', version = '1.0.2' , mode = 'lib' } +pkg-config = { name = 'pkg-config', version = '0.3.30' , mode = 'lib' } +redox_syscall = { name = 'redox_syscall', version = '0.5.3' , mode = 'lib' } +nom = { name = 'nom', version = '8.0.0-alpha2' , mode = 'lib' } +rustc_version = { name = 'rustc_version', version = '0.4.0' , mode = 'lib' } +futures-macro = { name = 'futures-macro', version = '0.3.30' , mode = 'lib' } +clap_derive = { name = 'clap_derive', version = '4.5.8' , mode = 'lib' } +futures-executor = { name = 'futures-executor', version = '0.3.30' , mode = 'lib' } +event-listener = { name = 'event-listener', version = '5.3.1' , mode = 'lib' } +num-integer = { name = 'num-integer', version = '0.1.46' , mode = 'lib' } +time-macros = { name = 'time-macros', version = '0.2.18' , mode = 'lib' } +flate2 = { name = 'flate2', version = '1.0.30' , mode = 'lib' } +tokio-macros = { name = 'tokio-macros', version = '2.3.0' , mode = 'lib' } +strum_macros = { name = 'strum_macros', version = '0.26.4' , mode = 'lib' } +tracing-attributes = { name = 'tracing-attributes', version = '0.1.27' , mode = 'lib' } +async-trait = { name = 'async-trait', version = '0.1.81' , mode = 'lib' } +crypto-common = { name = 'crypto-common', version = '0.1.6' , mode = 'lib' } +unicode-width = { name = 'unicode-width', version = '0.1.13' , mode = 'lib' } +anstyle = { name = 'anstyle', version = '1.0.7' , mode = 'lib' } +object = { name = 'object', version = '0.36.1' , mode = 'lib' } +gimli = { name = 'gimli', version = '0.31.0' , mode = 'lib' } +crossbeam-epoch = { name = 'crossbeam-epoch', version = '0.9.18' , mode = 'lib' } +thread_local = { name = 'thread_local', version = '1.1.8' , mode = 'lib' } +strum = { name = 'strum', version = '0.26.3' , mode = 'lib' } +darling_core = { name = 'darling_core', version = '0.20.10' , mode = 'lib' } +darling_macro = { name = 'darling_macro', version = '0.20.10' , mode = 'lib' } +minimal-lexical = { name = 'minimal-lexical', version = '0.2.1' , mode = 'lib' } +clap_builder = { name = 'clap_builder', version = '4.5.9' , mode = 'lib' } +time-core = { name = 'time-core', version = '0.1.2' , mode = 'lib' } +httparse = { name = 'httparse', version = '1.9.4' , mode = 'lib' } +signal-hook-registry = { name = 'signal-hook-registry', version = '1.4.2' , mode = 'lib' } +hex = { name = 'hex', version = '0.4.3' , mode = 'lib' } +crossbeam-deque = { name = 'crossbeam-deque', version = '0.8.5' , mode = 'lib' } +zerocopy = { name = 'zerocopy', version = '0.7.35' , mode = 'lib' } +rustversion = { name = 'rustversion', version = '1.0.17' , mode = 'lib' } +env_logger = { name = 'env_logger', version = '0.11.3' , mode = 'lib' } +webpki-roots = { name = 'webpki-roots', version = '0.26.3' , mode = 'lib' } +rustc-demangle = { name = 'rustc-demangle', version = '0.1.24' , mode = 'lib' } +mime = { name = 'mime', version = '0.3.17' , mode = 'lib' } +termcolor = { name = 'termcolor', version = '1.4.1' , mode = 'lib' } +subtle = { name = 'subtle', version = '2.6.1' , mode = 'lib' } +walkdir = { name = 'walkdir', version = '2.5.0' , mode = 'lib' } +hermit-abi = { name = 'hermit-abi', version = '0.4.0' , mode = 'lib' } +pin-project = { name = 'pin-project', version = '1.1.5' , mode = 'lib' } +pin-project-internal = { name = 'pin-project-internal', version = '1.1.5' , mode = 'lib' } +try-lock = { name = 'try-lock', version = '0.2.5' , mode = 'lib' } +tracing-log = { name = 'tracing-log', version = '0.2.0' , mode = 'lib' } +httpdate = { name = 'httpdate', version = '1.0.3' , mode = 'lib' } +anstream = { name = 'anstream', version = '0.6.14' , mode = 'lib' } +crossbeam-channel = { name = 'crossbeam-channel', version = '0.5.13' , mode = 'lib' } +reqwest = { name = 'reqwest', version = '0.12.5' , mode = 'lib' } +want = { name = 'want', version = '0.3.1' , mode = 'lib' } +paste = { name = 'paste', version = '1.0.15' , mode = 'lib' } +anstyle-parse = { name = 'anstyle-parse', version = '0.2.4' , mode = 'lib' } +toml_datetime = { name = 'toml_datetime', version = '0.6.6' , mode = 'lib' } +anstyle-query = { name = 'anstyle-query', version = '1.1.0' , mode = 'lib' } +addr2line = { name = 'addr2line', version = '0.24.0' , mode = 'lib' } +glob = { name = 'glob', version = '0.3.1' , mode = 'lib' } +num-bigint = { name = 'num-bigint', version = '0.4.6' , mode = 'lib' } +backtrace = { name = 'backtrace', version = '0.3.73' , mode = 'lib' } +wasi = { name = 'wasi', version = '0.13.1+wasi-0.2.0' , mode = 'lib' } +tower-service = { name = 'tower-service', version = '0.3.2' , mode = 'lib' } +sync_wrapper = { name = 'sync_wrapper', version = '1.0.1' , mode = 'lib' } +libloading = { name = 'libloading', version = '0.8.4' , mode = 'lib' } +rayon = { name = 'rayon', version = '1.10.0' , mode = 'lib' } +colorchoice = { name = 'colorchoice', version = '1.0.1' , mode = 'lib' } +encoding_rs = { name = 'encoding_rs', version = '0.8.34' , mode = 'lib' } +deranged = { name = 'deranged', version = '0.3.11' , mode = 'lib' } +zeroize = { name = 'zeroize', version = '1.8.1' , mode = 'lib' } +utf8parse = { name = 'utf8parse', version = '0.2.2' , mode = 'lib' } +tracing-subscriber = { name = 'tracing-subscriber', version = '0.3.18' , mode = 'lib' } +hyper-rustls = { name = 'hyper-rustls', version = '0.27.2' , mode = 'lib' } +hmac = { name = 'hmac', version = '0.13.0-pre.3' , mode = 'lib' } +rayon-core = { name = 'rayon-core', version = '1.12.1' , mode = 'lib' } +same-file = { name = 'same-file', version = '1.0.6' , mode = 'lib' } +prost = { name = 'prost', version = '0.13.1' , mode = 'lib' } +sharded-slab = { name = 'sharded-slab', version = '0.1.7' , mode = 'lib' } +textwrap = { name = 'textwrap', version = '0.16.1' , mode = 'lib' } +bumpalo = {name = 'bumpalo', version = '3.16.0' , mode = 'lib' } +arrayvec = { name = 'arrayvec', version = '0.7.4' , mode = 'lib' } diff --git a/lintcheck/lintcheck_crates.toml b/lintcheck/lintcheck_crates.toml index d205c93c6362..a41b3f79dbac 100644 --- a/lintcheck/lintcheck_crates.toml +++ b/lintcheck/lintcheck_crates.toml @@ -12,33 +12,33 @@ [crates] # Some binaries -cargo = {name = "cargo", version = '0.80.0', online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}'} -ripgrep = {name = "ripgrep", version = '14.1.0'} -mdbook = {name = "mdbook", version = '0.4.40'} +cargo = {name = "cargo", version = '0.80.0', mode = "bin", online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}' } +ripgrep = {name = "ripgrep", version = '14.1.0', mode = "bin" } +mdbook = {name = "mdbook", version = '0.4.40', mode = "lib" } # Common libraries -rayon = {name = "rayon", version = '1.10.0'} -serde = {name = "serde", version = '1.0.204'} -bitflags = {name = "bitflags", version = '2.6.0'} -log = {name = "log", version = '0.4.22'} -quote = {name = "quote", version = '1.0.36'} -proc-macro2 = {name = "proc-macro2", version = '1.0.86'} -rand = {name = "rand", version = '0.8.5'} -rand_core = {name = "rand_core", version = '0.6.4'} -regex = {name = "regex", version = '1.10.5'} -syn = {name = "syn", version = '2.0.71'} -anyhow = {name = "anyhow", version = '1.0.86'} -async-trait = { name = 'async-trait', version = '0.1.81' } -cxx = {name = "cxx", version = '1.0.124'} -ryu = {name = "ryu", version = '1.0.18'} -thiserror = {name = "thiserror", version = '1.0.63'} -serde_yaml = {name = "serde_yaml", version = '0.9.33'} -puffin = {name = "puffin", version = '0.19.0'} -bumpalo = {name = "bumpalo", version = '3.16.0'} -wasmi = {name = "wasmi", version = '0.35.0'} -base64 = { name = 'base64', version = '0.22.1' } -once_cell = { name = 'once_cell', version = '1.19.0' } -tokio = { name = 'tokio', version = '1.38.1' } +rayon = {name = "rayon", version = '1.10.0', mode = "lib"} +serde = {name = "serde", version = '1.0.204', mode = "lib"} +bitflags = {name = "bitflags", version = '2.6.0', mode = "lib"} +log = {name = "log", version = '0.4.22', mode = "lib"} +quote = {name = "quote", version = '1.0.36', mode = "lib"} +proc-macro2 = {name = "proc-macro2", version = '1.0.86', mode = "lib"} +rand = {name = "rand", version = '0.8.5', mode = "lib"} +rand_core = {name = "rand_core", version = '0.6.4', mode = "lib"} +regex = {name = "regex", version = '1.10.5', mode = "lib"} +syn = {name = "syn", version = '2.0.71', mode = "lib"} +anyhow = {name = "anyhow", version = '1.0.86', mode = "lib"} +async-trait = {name = 'async-trait', version = '0.1.81' , mode = "lib"} +cxx = {name = "cxx", version = '1.0.124', mode = "lib"} +ryu = {name = "ryu", version = '1.0.18', mode = "lib"} +thiserror = {name = "thiserror", version = '1.0.63', mode = "lib"} +serde_yaml = {name = "serde_yaml", version = '0.9.33', mode = "lib"} +puffin = {name = "puffin", version = '0.19.0', mode = "lib"} +bumpalo = {name = "bumpalo", version = '3.16.0', mode = "lib"} +wasmi = {name = "wasmi", version = '0.35.0', mode = "lib"} +base64 = {name = 'base64', version = '0.22.1', mode = "lib"} +once_cell = {name = 'once_cell', version = '1.19.0', mode = "lib"} +tokio = {name = 'tokio', version = '1.38.1', mode = "lib"} [recursive] ignore = [ diff --git a/lintcheck/src/input.rs b/lintcheck/src/input.rs index 14956fe88c22..1b8717737049 100644 --- a/lintcheck/src/input.rs +++ b/lintcheck/src/input.rs @@ -8,7 +8,7 @@ use std::time::Duration; use serde::Deserialize; use walkdir::{DirEntry, WalkDir}; -use crate::{Crate, LINTCHECK_DOWNLOADS, LINTCHECK_SOURCES}; +use crate::{CheckMode, Crate, LINTCHECK_DOWNLOADS, LINTCHECK_SOURCES}; const DEFAULT_DOCS_LINK: &str = "https://docs.rs/{krate}/{version}/src/{krate_}/{file}.html#{line}"; const DEFAULT_GITHUB_LINK: &str = "{url}/blob/{hash}/src/{file}#L{line}"; @@ -37,6 +37,7 @@ struct TomlCrate { git_hash: Option, path: Option, options: Option>, + mode: Option, /// Magic values: /// * `{krate}` will be replaced by `self.name` /// * `{krate_}` will be replaced by `self.name` with all `-` replaced by `_` @@ -79,9 +80,10 @@ impl TomlCrate { #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)] pub struct CrateWithSource { pub name: String, - pub source: CrateSource, - pub file_link: String, - pub options: Option>, + source: CrateSource, + file_link: String, + options: Option>, + mode: Option, } #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)] @@ -112,6 +114,7 @@ pub fn read_crates(toml_path: &Path) -> (Vec, RecursiveOptions) }, file_link: tk.file_link(DEFAULT_PATH_LINK), options: tk.options.clone(), + mode: tk.mode, }); } else if let Some(ref version) = tk.version { crate_sources.push(CrateWithSource { @@ -121,6 +124,7 @@ pub fn read_crates(toml_path: &Path) -> (Vec, RecursiveOptions) }, file_link: tk.file_link(DEFAULT_DOCS_LINK), options: tk.options.clone(), + mode: tk.mode, }); } else if tk.git_url.is_some() && tk.git_hash.is_some() { // otherwise, we should have a git source @@ -132,6 +136,7 @@ pub fn read_crates(toml_path: &Path) -> (Vec, RecursiveOptions) }, file_link: tk.file_link(DEFAULT_GITHUB_LINK), options: tk.options.clone(), + mode: tk.mode, }); } else { panic!("Invalid crate source: {tk:?}"); @@ -199,6 +204,7 @@ impl CrateWithSource { let name = &self.name; let options = &self.options; let file_link = &self.file_link; + let mode = self.mode; match &self.source { CrateSource::CratesIo { version } => { let extract_dir = PathBuf::from(LINTCHECK_SOURCES); @@ -232,6 +238,7 @@ impl CrateWithSource { path: extract_dir.join(format!("{name}-{version}/")), options: options.clone(), base_url: file_link.clone(), + mode, } }, CrateSource::Git { url, commit } => { @@ -274,6 +281,7 @@ impl CrateWithSource { path: repo_path, options: options.clone(), base_url: file_link.clone(), + mode, } }, CrateSource::Path { path } => { @@ -314,6 +322,7 @@ impl CrateWithSource { path: dest_crate_root, options: options.clone(), base_url: file_link.clone(), + mode, } }, } diff --git a/lintcheck/src/json.rs b/lintcheck/src/json.rs index 4211bce90b2f..8f619f6a4d8e 100644 --- a/lintcheck/src/json.rs +++ b/lintcheck/src/json.rs @@ -90,6 +90,8 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) { } } + println!(); + println!(); print_summary_table(&lint_warnings); println!(); diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index b414cd17327c..529e6d416cee 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -55,6 +55,16 @@ struct Crate { path: PathBuf, options: Option>, base_url: String, + mode: Option, +} + +#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Ord, PartialOrd, serde::Deserialize)] +#[serde(rename_all = "lowercase")] +enum CheckMode { + Bin, + Lib, + Tests, + All, } impl Crate { @@ -131,15 +141,25 @@ impl Crate { cmd.arg("--message-format=json"); } - // It turns out that `cargo fix` by default runs all tests, benchmarks, - // and examples. This is different from `cargo check` which only runs the - // main packages. The `--tests` works for both `cargo fix` and `cargo check` - // to indicate that only the main packages and tests should be processed. - // This unifies the behavior between the different lintcheck modes. + // It turns out that `cargo fix` by default uses `--all-targets`. This is + // on contrast to `cargo check`. (See rust-lang/cargo#13527). Sadly, there + // is currently no simple way to opt out of this. + // + // We can also not just default to `--tests` or something uniform, as those + // don't always compile and almost doubles the run times. // - // It also makes sense to include tests either way, since some Clippy lints - // have custom behavior in test code. - cmd.arg("--tests"); + // The "simple" solution is to require a mode when running rustfix. This is + // turned into a flag like `--bins`, `--lib` etc. + if let Some(mode) = self.mode { + cmd.arg(mode.as_arg()); + } else if config.fix { + eprintln!( + "\n\ + WARNING: `--fix` requires the mode to be specified.\n\ + | Try adding a mode to the specified crate\n" + ); + return Vec::new(); + } cmd.arg("--quiet") .current_dir(&self.path) @@ -227,6 +247,17 @@ impl Crate { } } +impl CheckMode { + fn as_arg(self) -> &'static str { + match self { + Self::Bin => "--bins", + Self::Lib => "--lib", + Self::Tests => "--tests", + Self::All => "--all-targets", + } + } +} + /// The target directory can sometimes be stored in the file name of spans. /// This is problematic since the directory in constructed from the thread /// ID and also used in our CI to determine if two lint emissions are the From 771b94768cfce46f7631e1579203b21a1eb7eefa Mon Sep 17 00:00:00 2001 From: xFrednet Date: Tue, 30 Jul 2024 11:56:09 +0200 Subject: [PATCH 3/3] CI: Run `lintcheck --fix` in CI --- .github/workflows/lintcheck.yml | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/lintcheck.yml b/.github/workflows/lintcheck.yml index 6a5139b6dc0b..2b8cbff5c0fb 100644 --- a/.github/workflows/lintcheck.yml +++ b/.github/workflows/lintcheck.yml @@ -132,3 +132,46 @@ jobs: path: | full_diff.md truncated_diff.md + + # Run lintcheck in fix mode to check that all suggestions are good. This only + # runs on `clippy::all` + `clippy::pedantic` as lints and suggestions from these + # categories generally not conflict and overlap. + fix: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + # HEAD is the generated merge commit `refs/pull/N/merge` between the PR and `master`, `HEAD^` + # being the commit from `master` that is the base of the merge + - name: Checkout base + run: git checkout HEAD^ + + # Use the lintcheck from the PR to generate the JSON in case the PR modifies lintcheck in some + # way + - name: Checkout current lintcheck + run: | + rm -rf lintcheck + git checkout ${{ github.sha }} -- lintcheck + + - name: Cache lintcheck bin + id: cache-lintcheck-bin + uses: actions/cache@v4 + with: + path: target/debug/lintcheck + key: lintcheck-bin-${{ hashfiles('lintcheck/**') }} + + - name: Build lintcheck + if: steps.cache-lintcheck-bin.outputs.cache-hit != 'true' + run: cargo build --manifest-path=lintcheck/Cargo.toml + + - name: Create cache key + id: key + run: echo "key=lintcheck-base-${{ hashfiles('lintcheck/**') }}-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + + - name: Run lintcheck + if: steps.cache-json.outputs.cache-hit != 'true' + run: ./target/debug/lintcheck --crates-toml ./lintcheck/ci_crates.toml --fix