|
1 | 1 | #![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
2 | 2 |
|
3 | 3 | use rustc_tools_util::VersionInfo;
|
| 4 | +use std::env; |
| 5 | +use std::path::PathBuf; |
| 6 | +use std::process::{self, Command}; |
| 7 | +use std::ffi::OsString; |
4 | 8 |
|
5 | 9 | const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.
|
6 | 10 |
|
@@ -37,93 +41,135 @@ fn show_version() {
|
37 | 41 |
|
38 | 42 | pub fn main() {
|
39 | 43 | // Check for version and help flags even when invoked as 'cargo-clippy'
|
40 |
| - if std::env::args().any(|a| a == "--help" || a == "-h") { |
| 44 | + if env::args().any(|a| a == "--help" || a == "-h") { |
41 | 45 | show_help();
|
42 | 46 | return;
|
43 | 47 | }
|
44 | 48 |
|
45 |
| - if std::env::args().any(|a| a == "--version" || a == "-V") { |
| 49 | + if env::args().any(|a| a == "--version" || a == "-V") { |
46 | 50 | show_version();
|
47 | 51 | return;
|
48 | 52 | }
|
49 | 53 |
|
50 |
| - if let Err(code) = process(std::env::args().skip(2)) { |
51 |
| - std::process::exit(code); |
| 54 | + if let Err(code) = process(env::args().skip(2)) { |
| 55 | + process::exit(code); |
52 | 56 | }
|
53 | 57 | }
|
54 | 58 |
|
55 |
| -fn process<I>(mut old_args: I) -> Result<(), i32> |
56 |
| -where |
57 |
| - I: Iterator<Item = String>, |
| 59 | +struct ClippyCmd { |
| 60 | + unstable_options: bool, |
| 61 | + cmd: &'static str, |
| 62 | + args: Vec<String>, |
| 63 | + clippy_args: String |
| 64 | +} |
| 65 | + |
| 66 | +impl ClippyCmd |
58 | 67 | {
|
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 |
| - _ => {}, |
| 68 | + fn new<I>(mut old_args: I) -> Self |
| 69 | + where |
| 70 | + I: Iterator<Item = String>, |
| 71 | + { |
| 72 | + let mut cmd = "check"; |
| 73 | + let mut unstable_options = false; |
| 74 | + let mut args = vec![]; |
| 75 | + |
| 76 | + for arg in old_args.by_ref() { |
| 77 | + match arg.as_str() { |
| 78 | + "--fix" => { |
| 79 | + cmd = "fix"; |
| 80 | + continue; |
| 81 | + } |
| 82 | + "--" => break, |
| 83 | + // Cover -Zunstable-options and -Z unstable-options |
| 84 | + s if s.ends_with("unstable-options") => unstable_options = true, |
| 85 | + _ => {} |
| 86 | + } |
| 87 | + |
| 88 | + args.push(arg); |
| 89 | + } |
| 90 | + |
| 91 | + if cmd == "fix" && !unstable_options { |
| 92 | + panic!("Usage of `--fix` requires `-Z unstable-options`"); |
74 | 93 | }
|
75 | 94 |
|
76 |
| - args.push(arg); |
| 95 | + // Run the dogfood tests directly on nightly cargo. This is required due |
| 96 | + // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118. |
| 97 | + if env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) { |
| 98 | + args.insert(0, "+nightly".to_string()); |
| 99 | + } |
| 100 | + |
| 101 | + let clippy_args: String = |
| 102 | + old_args |
| 103 | + .map(|arg| format!("{}__CLIPPY_HACKERY__", arg)) |
| 104 | + .collect(); |
| 105 | + |
| 106 | + ClippyCmd { |
| 107 | + unstable_options, |
| 108 | + cmd, |
| 109 | + args, |
| 110 | + clippy_args, |
| 111 | + } |
77 | 112 | }
|
78 | 113 |
|
79 |
| - if fix { |
80 |
| - if unstable_options { |
81 |
| - args[0] = "fix".to_owned(); |
| 114 | + fn path_env(&self) -> &'static str { |
| 115 | + if self.unstable_options { |
| 116 | + "RUSTC_WORKSPACE_WRAPPER" |
82 | 117 | } else {
|
83 |
| - panic!("Usage of `--fix` requires `-Z unstable-options`"); |
| 118 | + "RUSTC_WRAPPER" |
84 | 119 | }
|
85 | 120 | }
|
86 | 121 |
|
87 |
| - let path_env = if unstable_options { |
88 |
| - "RUSTC_WORKSPACE_WRAPPER" |
89 |
| - } else { |
90 |
| - "RUSTC_WRAPPER" |
91 |
| - }; |
| 122 | + fn path(&self) -> PathBuf { |
| 123 | + let mut path = env::current_exe() |
| 124 | + .expect("current executable path invalid") |
| 125 | + .with_file_name("clippy-driver"); |
92 | 126 |
|
93 |
| - let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect(); |
| 127 | + if cfg!(windows) { |
| 128 | + path.set_extension("exe"); |
| 129 | + } |
| 130 | + |
| 131 | + path |
| 132 | + } |
94 | 133 |
|
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"); |
| 134 | + fn target_dir() -> Option<(&'static str, OsString)> { |
| 135 | + env::var_os("CLIPPY_DOGFOOD") |
| 136 | + .map(|_| { |
| 137 | + env::var_os("CARGO_MANIFEST_DIR").map_or_else( |
| 138 | + || std::ffi::OsString::from("clippy_dogfood"), |
| 139 | + |d| { |
| 140 | + std::path::PathBuf::from(d) |
| 141 | + .join("target") |
| 142 | + .join("dogfood") |
| 143 | + .into_os_string() |
| 144 | + }, |
| 145 | + ) |
| 146 | + }) |
| 147 | + .map(|p| ("CARGO_TARGET_DIR", p)) |
100 | 148 | }
|
101 | 149 |
|
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()); |
| 150 | + fn to_std_cmd(self) -> Command { |
| 151 | + let mut cmd = Command::new("cargo"); |
| 152 | + |
| 153 | + cmd.env(self.path_env(), self.path()) |
| 154 | + .envs(ClippyCmd::target_dir()) |
| 155 | + .env("CLIPPY_ARGS", self.clippy_args) |
| 156 | + .arg(self.cmd) |
| 157 | + .args(&self.args); |
| 158 | + |
| 159 | + cmd |
120 | 160 | }
|
| 161 | +} |
| 162 | + |
| 163 | + |
| 164 | +fn process<I>(old_args: I) -> Result<(), i32> |
| 165 | +where |
| 166 | + I: Iterator<Item = String>, |
| 167 | +{ |
| 168 | + let cmd = ClippyCmd::new(old_args); |
| 169 | + |
| 170 | + let mut cmd = cmd.to_std_cmd(); |
121 | 171 |
|
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) |
| 172 | + let exit_status = cmd |
127 | 173 | .spawn()
|
128 | 174 | .expect("could not run cargo")
|
129 | 175 | .wait()
|
|
0 commit comments