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) {
|
fn update_lints(update_mode: &UpdateMode) {
|
||||||
let lint_list: Vec<Lint> = gather_all().collect();
|
let lint_list: Vec<Lint> = gather_all().collect();
|
||||||
|
|
||||||
let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
|
let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
|
||||||
let lint_count = usable_lints.len();
|
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(
|
let mut file_change = replace_region_in_file(
|
||||||
"../README.md",
|
"../README.md",
|
||||||
r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang.github.io/rust-clippy/master/index.html\)"#,
|
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::path::Path;
|
||||||
use std::process::{exit, Command};
|
use std::process::{exit, Command};
|
||||||
|
|
||||||
|
mod lintlist;
|
||||||
|
|
||||||
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
/// 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`.
|
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
|
||||||
fn arg_value<'a>(
|
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() {
|
pub fn main() {
|
||||||
rustc_driver::init_rustc_env_logger();
|
rustc_driver::init_rustc_env_logger();
|
||||||
exit(
|
exit(
|
||||||
@ -153,13 +291,34 @@ pub fn main() {
|
|||||||
|
|
||||||
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
|
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
|
||||||
// We're invoking the compiler programmatically, so we ignore this/
|
// We're invoking the compiler programmatically, so we ignore this/
|
||||||
if orig_args.len() <= 1 {
|
let wrapper_mode = Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref());
|
||||||
std::process::exit(1);
|
|
||||||
}
|
if wrapper_mode {
|
||||||
if Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref()) {
|
|
||||||
// we still want to be able to invoke it normally though
|
// we still want to be able to invoke it normally though
|
||||||
orig_args.remove(1);
|
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
|
// this conditional check for the --sysroot flag is there so users can call
|
||||||
// `clippy_driver` directly
|
// `clippy_driver` directly
|
||||||
// without having to pass --sysroot or anything
|
// 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