]> git.lizzy.rs Git - rust.git/blob - src/main.rs
66c1aa4d97c69dedfdf37e908db8840043644927
[rust.git] / src / main.rs
1 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
2
3 use rustc_tools_util::VersionInfo;
4
5 const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.
6
7 Usage:
8     cargo clippy [options] [--] [<opts>...]
9
10 Common options:
11     -h, --help               Print this message
12     -V, --version            Print version info and exit
13
14 Other options are the same as `cargo check`.
15
16 To allow or deny a lint from the command line you can use `cargo clippy --`
17 with:
18
19     -W --warn OPT       Set lint warnings
20     -A --allow OPT      Set lint allowed
21     -D --deny OPT       Set lint denied
22     -F --forbid OPT     Set lint forbidden
23
24 You can use tool lints to allow or deny lints from your code, eg.:
25
26     #[allow(clippy::needless_lifetimes)]
27 "#;
28
29 fn show_help() {
30     println!("{}", CARGO_CLIPPY_HELP);
31 }
32
33 fn show_version() {
34     let version_info = rustc_tools_util::get_version_info!();
35     println!("{}", version_info);
36 }
37
38 pub fn main() {
39     // Check for version and help flags even when invoked as 'cargo-clippy'
40     if std::env::args().any(|a| a == "--help" || a == "-h") {
41         show_help();
42         return;
43     }
44
45     if std::env::args().any(|a| a == "--version" || a == "-V") {
46         show_version();
47         return;
48     }
49
50     if let Err(code) = process(std::env::args().skip(2)) {
51         std::process::exit(code);
52     }
53 }
54
55 fn process<I>(mut old_args: I) -> Result<(), i32>
56 where
57     I: Iterator<Item = String>,
58 {
59     let mut args = vec!["check".to_owned()];
60
61     for arg in old_args.by_ref() {
62         if arg == "--fix" {
63             args[0] = "fix".to_owned();
64             continue;
65         }
66
67         if arg == "--" {
68             break;
69         }
70         args.push(arg);
71     }
72
73     let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();
74
75     let mut path = std::env::current_exe()
76         .expect("current executable path invalid")
77         .with_file_name("clippy-driver");
78     if cfg!(windows) {
79         path.set_extension("exe");
80     }
81
82     let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
83         .map(|_| {
84             std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
85                 || std::ffi::OsString::from("clippy_dogfood"),
86                 |d| {
87                     std::path::PathBuf::from(d)
88                         .join("target")
89                         .join("dogfood")
90                         .into_os_string()
91                 },
92             )
93         })
94         .map(|p| ("CARGO_TARGET_DIR", p));
95
96     // Run the dogfood tests directly on nightly cargo. This is required due
97     // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118.
98     if std::env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) {
99         args.insert(0, "+nightly".to_string());
100     }
101
102     let exit_status = std::process::Command::new("cargo")
103         .args(&args)
104         .env("RUSTC_WORKSPACE_WRAPPER", path)
105         .env("CLIPPY_ARGS", clippy_args)
106         .envs(target_dir)
107         .spawn()
108         .expect("could not run cargo")
109         .wait()
110         .expect("failed to wait for cargo?");
111
112     if exit_status.success() {
113         Ok(())
114     } else {
115         Err(exit_status.code().unwrap_or(-1))
116     }
117 }