mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-27 14:24:08 +00:00
Auto merge of #4175 - yaahallo:master, r=oli-obk
Implement better help for clippy-driver https://github.com/rust-lang/rust-clippy/issues/4173
This commit is contained in:
commit
bd39cea01c
@ -87,9 +87,31 @@ fn print_lints() {
|
||||
|
||||
fn update_lints(update_mode: &UpdateMode) {
|
||||
let lint_list: Vec<Lint> = gather_all().collect();
|
||||
|
||||
let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
|
||||
let lint_count = usable_lints.len();
|
||||
|
||||
let mut sorted_usable_lints = usable_lints.clone();
|
||||
sorted_usable_lints.sort_by_key(|lint| lint.name.clone());
|
||||
|
||||
std::fs::write(
|
||||
"../src/lintlist/mod.rs",
|
||||
&format!(
|
||||
"\
|
||||
//! This file is managed by `util/dev update_lints`. Do not edit.
|
||||
|
||||
pub mod lint;
|
||||
pub use lint::Level;
|
||||
pub use lint::Lint;
|
||||
pub use lint::LINT_LEVELS;
|
||||
|
||||
pub const ALL_LINTS: [Lint; {}] = {:#?};\n",
|
||||
sorted_usable_lints.len(),
|
||||
sorted_usable_lints
|
||||
),
|
||||
)
|
||||
.expect("can write to file");
|
||||
|
||||
let mut file_change = replace_region_in_file(
|
||||
"../README.md",
|
||||
r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang.github.io/rust-clippy/master/index.html\)"#,
|
||||
|
167
src/driver.rs
167
src/driver.rs
@ -15,6 +15,8 @@ use rustc_tools_util::*;
|
||||
use std::path::Path;
|
||||
use std::process::{exit, Command};
|
||||
|
||||
mod lintlist;
|
||||
|
||||
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
||||
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
|
||||
fn arg_value<'a>(
|
||||
@ -108,6 +110,142 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::find_map, clippy::filter_map)]
|
||||
fn describe_lints() {
|
||||
use lintlist::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
println!(
|
||||
"
|
||||
Available lint options:
|
||||
-W <foo> Warn about <foo>
|
||||
-A <foo> Allow <foo>
|
||||
-D <foo> Deny <foo>
|
||||
-F <foo> Forbid <foo> (deny <foo> and all attempts to override)
|
||||
|
||||
"
|
||||
);
|
||||
|
||||
let lint_level = |lint: &Lint| {
|
||||
LINT_LEVELS
|
||||
.iter()
|
||||
.find(|level_mapping| level_mapping.0 == lint.group)
|
||||
.map(|(_, level)| match level {
|
||||
Level::Allow => "allow",
|
||||
Level::Warn => "warn",
|
||||
Level::Deny => "deny",
|
||||
})
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let mut lints: Vec<_> = ALL_LINTS.iter().collect();
|
||||
// The sort doesn't case-fold but it's doubtful we care.
|
||||
lints.sort_by_cached_key(|x: &&Lint| (lint_level(x), x.name));
|
||||
|
||||
let max_lint_name_len = lints
|
||||
.iter()
|
||||
.map(|lint| lint.name.len())
|
||||
.map(|len| len + "clippy::".len())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
let padded = |x: &str| {
|
||||
let mut s = " ".repeat(max_lint_name_len - x.chars().count());
|
||||
s.push_str(x);
|
||||
s
|
||||
};
|
||||
|
||||
let scoped = |x: &str| format!("clippy::{}", x);
|
||||
|
||||
let lint_groups: HashSet<_> = lints.iter().map(|lint| lint.group).collect();
|
||||
|
||||
println!("Lint checks provided by clippy:\n");
|
||||
println!(" {} {:7.7} meaning", padded("name"), "default");
|
||||
println!(" {} {:7.7} -------", padded("----"), "-------");
|
||||
|
||||
let print_lints = |lints: &[&Lint]| {
|
||||
for lint in lints {
|
||||
let name = lint.name.replace("_", "-");
|
||||
println!(
|
||||
" {} {:7.7} {}",
|
||||
padded(&scoped(&name)),
|
||||
lint_level(lint),
|
||||
lint.desc
|
||||
);
|
||||
}
|
||||
println!("\n");
|
||||
};
|
||||
|
||||
print_lints(&lints);
|
||||
|
||||
let max_group_name_len = std::cmp::max(
|
||||
"clippy::all".len(),
|
||||
lint_groups
|
||||
.iter()
|
||||
.map(|group| group.len())
|
||||
.map(|len| len + "clippy::".len())
|
||||
.max()
|
||||
.unwrap_or(0),
|
||||
);
|
||||
|
||||
let padded_group = |x: &str| {
|
||||
let mut s = " ".repeat(max_group_name_len - x.chars().count());
|
||||
s.push_str(x);
|
||||
s
|
||||
};
|
||||
|
||||
println!("Lint groups provided by clippy:\n");
|
||||
println!(" {} sub-lints", padded_group("name"));
|
||||
println!(" {} ---------", padded_group("----"));
|
||||
println!(" {} the set of all clippy lints", padded_group("clippy::all"));
|
||||
|
||||
let print_lint_groups = || {
|
||||
for group in lint_groups {
|
||||
let name = group.to_lowercase().replace("_", "-");
|
||||
let desc = lints
|
||||
.iter()
|
||||
.filter(|&lint| lint.group == group)
|
||||
.map(|lint| lint.name)
|
||||
.map(|name| name.replace("_", "-"))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
println!(" {} {}", padded_group(&scoped(&name)), desc);
|
||||
}
|
||||
println!("\n");
|
||||
};
|
||||
|
||||
print_lint_groups();
|
||||
}
|
||||
|
||||
fn display_help() {
|
||||
println!(
|
||||
"\
|
||||
Checks a package to catch common mistakes and improve your Rust code.
|
||||
|
||||
Usage:
|
||||
cargo clippy [options] [--] [<opts>...]
|
||||
|
||||
Common options:
|
||||
-h, --help Print this message
|
||||
-V, --version Print version info and exit
|
||||
|
||||
Other options are the same as `cargo check`.
|
||||
|
||||
To allow or deny a lint from the command line you can use `cargo clippy --`
|
||||
with:
|
||||
|
||||
-W --warn OPT Set lint warnings
|
||||
-A --allow OPT Set lint allowed
|
||||
-D --deny OPT Set lint denied
|
||||
-F --forbid OPT Set lint forbidden
|
||||
|
||||
You can use tool lints to allow or deny lints from your code, eg.:
|
||||
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
exit(
|
||||
@ -153,13 +291,34 @@ pub fn main() {
|
||||
|
||||
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
|
||||
// We're invoking the compiler programmatically, so we ignore this/
|
||||
if orig_args.len() <= 1 {
|
||||
std::process::exit(1);
|
||||
}
|
||||
if Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref()) {
|
||||
let wrapper_mode = Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref());
|
||||
|
||||
if wrapper_mode {
|
||||
// we still want to be able to invoke it normally though
|
||||
orig_args.remove(1);
|
||||
}
|
||||
|
||||
if !wrapper_mode && std::env::args().any(|a| a == "--help" || a == "-h") {
|
||||
display_help();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
let should_describe_lints = || {
|
||||
let args: Vec<_> = std::env::args().collect();
|
||||
args.windows(2).any(|args| {
|
||||
args[1] == "help"
|
||||
&& match args[0].as_str() {
|
||||
"-W" | "-A" | "-D" | "-F" => true,
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
if !wrapper_mode && should_describe_lints() {
|
||||
describe_lints();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// this conditional check for the --sysroot flag is there so users can call
|
||||
// `clippy_driver` directly
|
||||
// without having to pass --sysroot or anything
|
||||
|
27
src/lintlist/lint.rs
Normal file
27
src/lintlist/lint.rs
Normal file
@ -0,0 +1,27 @@
|
||||
/// Lint data parsed from the Clippy source code.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub struct Lint {
|
||||
pub name: &'static str,
|
||||
pub group: &'static str,
|
||||
pub desc: &'static str,
|
||||
pub deprecation: Option<&'static str>,
|
||||
pub module: &'static str,
|
||||
}
|
||||
|
||||
#[derive(PartialOrd, PartialEq, Ord, Eq)]
|
||||
pub enum Level {
|
||||
Allow,
|
||||
Warn,
|
||||
Deny,
|
||||
}
|
||||
|
||||
pub const LINT_LEVELS: [(&str, Level); 8] = [
|
||||
("correctness", Level::Deny),
|
||||
("style", Level::Warn),
|
||||
("complexity", Level::Warn),
|
||||
("perf", Level::Warn),
|
||||
("restriction", Level::Allow),
|
||||
("pedantic", Level::Allow),
|
||||
("nursery", Level::Allow),
|
||||
("cargo", Level::Allow),
|
||||
];
|
2137
src/lintlist/mod.rs
Normal file
2137
src/lintlist/mod.rs
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user