]> git.lizzy.rs Git - rust.git/blob - src/main.rs
fix rustfmt issue
[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     let mut fix = false;
62     let mut unstable_options = false;
63
64     for arg in old_args.by_ref() {
65         match arg.as_str() {
66             "--fix" => {
67                 fix = true;
68                 continue;
69             },
70             "--" => break,
71             // Cover -Zunstable-options and -Z unstable-options
72             s if s.ends_with("unstable-options") => unstable_options = true,
73             _ => {},
74         }
75
76         args.push(arg);
77     }
78
79     if fix {
80         if !unstable_options {
81             panic!("Usage of `--fix` requires `-Z unstable-options`");
82         } else {
83             args[0] = "fix".to_owned();
84         }
85     }
86
87     let path_env = if unstable_options {
88         "RUSTC_WORKSPACE_WRAPPER"
89     } else {
90         "RUSTC_WRAPPER"
91     };
92
93     let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();
94
95     let mut path = std::env::current_exe()
96         .expect("current executable path invalid")
97         .with_file_name("clippy-driver");
98     if cfg!(windows) {
99         path.set_extension("exe");
100     }
101
102     let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
103         .map(|_| {
104             std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
105                 || std::ffi::OsString::from("clippy_dogfood"),
106                 |d| {
107                     std::path::PathBuf::from(d)
108                         .join("target")
109                         .join("dogfood")
110                         .into_os_string()
111                 },
112             )
113         })
114         .map(|p| ("CARGO_TARGET_DIR", p));
115
116     // Run the dogfood tests directly on nightly cargo. This is required due
117     // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118.
118     if std::env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) {
119         args.insert(0, "+nightly".to_string());
120     }
121
122     let exit_status = std::process::Command::new("cargo")
123         .args(&args)
124         .env(path_env, path)
125         .env("CLIPPY_ARGS", clippy_args)
126         .envs(target_dir)
127         .spawn()
128         .expect("could not run cargo")
129         .wait()
130         .expect("failed to wait for cargo?");
131
132     if exit_status.success() {
133         Ok(())
134     } else {
135         Err(exit_status.code().unwrap_or(-1))
136     }
137 }