]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_dev/src/main.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_dev / src / main.rs
CommitLineData
f20569fa 1#![cfg_attr(feature = "deny-warnings", deny(warnings))]
17df50a5
XL
2// warn on lints, that are included in `rust-lang/rust`s bootstrap
3#![warn(rust_2018_idioms, unused_lifetimes)]
f20569fa 4
9ffffee4 5use clap::{Arg, ArgAction, ArgMatches, Command};
fe692bf9 6use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints};
04454e1e 7use indoc::indoc;
fe692bf9 8use std::convert::Infallible;
064997fb 9
f20569fa
XL
10fn main() {
11 let matches = get_clap_config();
12
13 match matches.subcommand() {
fe692bf9
FG
14 Some(("bless", _)) => {
15 eprintln!("use `cargo bless` to automatically replace `.stderr` and `.fixed` files as tests are being run");
f20569fa 16 },
064997fb
FG
17 Some(("dogfood", matches)) => {
18 dogfood::dogfood(
9ffffee4
FG
19 matches.get_flag("fix"),
20 matches.get_flag("allow-dirty"),
21 matches.get_flag("allow-staged"),
064997fb
FG
22 );
23 },
923072b8 24 Some(("fmt", matches)) => {
9ffffee4 25 fmt::run(matches.get_flag("check"), matches.get_flag("verbose"));
f20569fa 26 },
923072b8 27 Some(("update_lints", matches)) => {
9ffffee4 28 if matches.get_flag("print-only") {
f20569fa 29 update_lints::print_lints();
9ffffee4 30 } else if matches.get_flag("check") {
04454e1e 31 update_lints::update(update_lints::UpdateMode::Check);
f20569fa 32 } else {
04454e1e 33 update_lints::update(update_lints::UpdateMode::Change);
f20569fa
XL
34 }
35 },
923072b8 36 Some(("new_lint", matches)) => {
f20569fa 37 match new_lint::create(
fe692bf9 38 matches.get_one::<String>("pass").unwrap(),
923072b8 39 matches.get_one::<String>("name"),
064997fb
FG
40 matches.get_one::<String>("category").map(String::as_str),
41 matches.get_one::<String>("type").map(String::as_str),
9ffffee4 42 matches.get_flag("msrv"),
f20569fa 43 ) {
add651ee 44 Ok(()) => update_lints::update(update_lints::UpdateMode::Change),
2b03887a 45 Err(e) => eprintln!("Unable to create lint: {e}"),
f20569fa
XL
46 }
47 },
923072b8
FG
48 Some(("setup", sub_command)) => match sub_command.subcommand() {
49 Some(("intellij", matches)) => {
9ffffee4 50 if matches.get_flag("remove") {
04454e1e
FG
51 setup::intellij::remove_rustc_src();
52 } else {
53 setup::intellij::setup_rustc_src(
54 matches
923072b8 55 .get_one::<String>("rustc-repo-path")
04454e1e
FG
56 .expect("this field is mandatory and therefore always valid"),
57 );
58 }
59 },
923072b8 60 Some(("git-hook", matches)) => {
9ffffee4 61 if matches.get_flag("remove") {
04454e1e
FG
62 setup::git_hook::remove_hook();
63 } else {
9ffffee4 64 setup::git_hook::install_hook(matches.get_flag("force-override"));
04454e1e
FG
65 }
66 },
923072b8 67 Some(("vscode-tasks", matches)) => {
9ffffee4 68 if matches.get_flag("remove") {
04454e1e
FG
69 setup::vscode::remove_tasks();
70 } else {
9ffffee4 71 setup::vscode::install_tasks(matches.get_flag("force-override"));
04454e1e
FG
72 }
73 },
136023e0
XL
74 _ => {},
75 },
923072b8
FG
76 Some(("remove", sub_command)) => match sub_command.subcommand() {
77 Some(("git-hook", _)) => setup::git_hook::remove_hook(),
78 Some(("intellij", _)) => setup::intellij::remove_rustc_src(),
79 Some(("vscode-tasks", _)) => setup::vscode::remove_tasks(),
136023e0
XL
80 _ => {},
81 },
923072b8
FG
82 Some(("serve", matches)) => {
83 let port = *matches.get_one::<u16>("port").unwrap();
84 let lint = matches.get_one::<String>("lint");
f20569fa
XL
85 serve::run(port, lint);
86 },
923072b8
FG
87 Some(("lint", matches)) => {
88 let path = matches.get_one::<String>("path").unwrap();
89 let args = matches.get_many::<String>("args").into_iter().flatten();
90 lint::run(path, args);
04454e1e 91 },
923072b8
FG
92 Some(("rename_lint", matches)) => {
93 let old_name = matches.get_one::<String>("old_name").unwrap();
94 let new_name = matches.get_one::<String>("new_name").unwrap_or(old_name);
9ffffee4 95 let uplift = matches.get_flag("uplift");
04454e1e 96 update_lints::rename(old_name, new_name, uplift);
a2a8927a 97 },
064997fb
FG
98 Some(("deprecate", matches)) => {
99 let name = matches.get_one::<String>("name").unwrap();
100 let reason = matches.get_one("reason");
101 update_lints::deprecate(name, reason);
102 },
f20569fa
XL
103 _ => {},
104 }
105}
106
923072b8
FG
107fn get_clap_config() -> ArgMatches {
108 Command::new("Clippy developer tooling")
109 .arg_required_else_help(true)
110 .subcommands([
111 Command::new("bless").about("bless the test output changes").arg(
112 Arg::new("ignore-timestamp")
113 .long("ignore-timestamp")
9ffffee4 114 .action(ArgAction::SetTrue)
923072b8
FG
115 .help("Include files updated before clippy was built"),
116 ),
064997fb 117 Command::new("dogfood").about("Runs the dogfood test").args([
9ffffee4
FG
118 Arg::new("fix")
119 .long("fix")
120 .action(ArgAction::SetTrue)
121 .help("Apply the suggestions when possible"),
064997fb
FG
122 Arg::new("allow-dirty")
123 .long("allow-dirty")
9ffffee4 124 .action(ArgAction::SetTrue)
064997fb
FG
125 .help("Fix code even if the working directory has changes")
126 .requires("fix"),
127 Arg::new("allow-staged")
128 .long("allow-staged")
9ffffee4 129 .action(ArgAction::SetTrue)
064997fb
FG
130 .help("Fix code even if the working directory has staged changes")
131 .requires("fix"),
132 ]),
923072b8 133 Command::new("fmt")
f20569fa 134 .about("Run rustfmt on all projects and tests")
923072b8 135 .args([
9ffffee4
FG
136 Arg::new("check")
137 .long("check")
138 .action(ArgAction::SetTrue)
139 .help("Use the rustfmt --check option"),
140 Arg::new("verbose")
141 .short('v')
142 .long("verbose")
143 .action(ArgAction::SetTrue)
144 .help("Echo commands run"),
923072b8
FG
145 ]),
146 Command::new("update_lints")
f20569fa
XL
147 .about("Updates lint registration and information from the source code")
148 .long_about(
149 "Makes sure that:\n \
923072b8
FG
150 * the lint count in README.md is correct\n \
151 * the changelog contains markdown link references at the bottom\n \
152 * all lint groups include the correct lints\n \
153 * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
154 * all lints are registered in the lint store",
f20569fa 155 )
923072b8 156 .args([
9ffffee4
FG
157 Arg::new("print-only")
158 .long("print-only")
159 .action(ArgAction::SetTrue)
160 .help(
161 "Print a table of lints to STDOUT. \
162 This does not include deprecated and internal lints. \
163 (Does not modify any files)",
164 ),
923072b8 165 Arg::new("check")
f20569fa 166 .long("check")
9ffffee4 167 .action(ArgAction::SetTrue)
f20569fa 168 .help("Checks that `cargo dev update_lints` has been run. Used on CI."),
923072b8
FG
169 ]),
170 Command::new("new_lint")
f20569fa 171 .about("Create new lint and run `cargo dev update_lints`")
923072b8
FG
172 .args([
173 Arg::new("pass")
174 .short('p')
f20569fa
XL
175 .long("pass")
176 .help("Specify whether the lint runs during the early or late pass")
9ffffee4 177 .value_parser(["early", "late"])
064997fb 178 .conflicts_with("type")
fe692bf9 179 .default_value("late"),
923072b8
FG
180 Arg::new("name")
181 .short('n')
f20569fa
XL
182 .long("name")
183 .help("Name of the new lint in snake case, ex: fn_too_long")
fe692bf9
FG
184 .required(true)
185 .value_parser(|name: &str| Ok::<_, Infallible>(name.replace('-', "_"))),
923072b8
FG
186 Arg::new("category")
187 .short('c')
f20569fa
XL
188 .long("category")
189 .help("What category the lint belongs to")
190 .default_value("nursery")
923072b8 191 .value_parser([
9ffffee4
FG
192 "style",
193 "correctness",
194 "suspicious",
195 "complexity",
196 "perf",
197 "pedantic",
198 "restriction",
199 "cargo",
200 "nursery",
201 "internal",
9ffffee4
FG
202 ]),
203 Arg::new("type").long("type").help("What directory the lint belongs in"),
204 Arg::new("msrv")
205 .long("msrv")
206 .action(ArgAction::SetTrue)
207 .help("Add MSRV config code to the lint"),
923072b8
FG
208 ]),
209 Command::new("setup")
136023e0 210 .about("Support for setting up your personal development environment")
923072b8
FG
211 .arg_required_else_help(true)
212 .subcommands([
213 Command::new("intellij")
136023e0 214 .about("Alter dependencies so Intellij Rust can find rustc internals")
923072b8
FG
215 .args([
216 Arg::new("remove")
04454e1e 217 .long("remove")
9ffffee4
FG
218 .action(ArgAction::SetTrue)
219 .help("Remove the dependencies added with 'cargo dev setup intellij'"),
923072b8 220 Arg::new("rustc-repo-path")
136023e0 221 .long("repo-path")
923072b8 222 .short('r')
136023e0 223 .help("The path to a rustc repo that will be used for setting the dependencies")
136023e0 224 .value_name("path")
04454e1e 225 .conflicts_with("remove")
136023e0 226 .required(true),
923072b8
FG
227 ]),
228 Command::new("git-hook")
136023e0 229 .about("Add a pre-commit git hook that formats your code to make it look pretty")
923072b8
FG
230 .args([
231 Arg::new("remove")
04454e1e 232 .long("remove")
9ffffee4
FG
233 .action(ArgAction::SetTrue)
234 .help("Remove the pre-commit hook added with 'cargo dev setup git-hook'"),
923072b8 235 Arg::new("force-override")
136023e0 236 .long("force-override")
923072b8 237 .short('f')
9ffffee4
FG
238 .action(ArgAction::SetTrue)
239 .help("Forces the override of an existing git pre-commit hook"),
923072b8
FG
240 ]),
241 Command::new("vscode-tasks")
136023e0 242 .about("Add several tasks to vscode for formatting, validation and testing")
923072b8
FG
243 .args([
244 Arg::new("remove")
04454e1e 245 .long("remove")
9ffffee4
FG
246 .action(ArgAction::SetTrue)
247 .help("Remove the tasks added with 'cargo dev setup vscode-tasks'"),
923072b8 248 Arg::new("force-override")
136023e0 249 .long("force-override")
923072b8 250 .short('f')
9ffffee4
FG
251 .action(ArgAction::SetTrue)
252 .help("Forces the override of existing vscode tasks"),
923072b8
FG
253 ]),
254 ]),
255 Command::new("remove")
136023e0 256 .about("Support for undoing changes done by the setup command")
923072b8
FG
257 .arg_required_else_help(true)
258 .subcommands([
259 Command::new("git-hook").about("Remove any existing pre-commit git hook"),
260 Command::new("vscode-tasks").about("Remove any existing vscode tasks"),
261 Command::new("intellij").about("Removes rustc source paths added via `cargo dev setup intellij`"),
262 ]),
263 Command::new("serve")
f20569fa 264 .about("Launch a local 'ALL the Clippy Lints' website in a browser")
923072b8
FG
265 .args([
266 Arg::new("port")
f20569fa 267 .long("port")
923072b8 268 .short('p')
f20569fa
XL
269 .help("Local port for the http server")
270 .default_value("8000")
923072b8
FG
271 .value_parser(clap::value_parser!(u16)),
272 Arg::new("lint").help("Which lint's page to load initially (optional)"),
273 ]),
274 Command::new("lint")
04454e1e
FG
275 .about("Manually run clippy on a file or package")
276 .after_help(indoc! {"
277 EXAMPLES
278 Lint a single file:
279 cargo dev lint tests/ui/attrs.rs
280
281 Lint a package directory:
282 cargo dev lint tests/ui-cargo/wildcard_dependencies/fail
283 cargo dev lint ~/my-project
923072b8
FG
284
285 Run rustfix:
286 cargo dev lint ~/my-project -- --fix
287
288 Set lint levels:
289 cargo dev lint file.rs -- -W clippy::pedantic
290 cargo dev lint ~/my-project -- -- -W clippy::pedantic
04454e1e 291 "})
923072b8
FG
292 .args([
293 Arg::new("path")
a2a8927a 294 .required(true)
04454e1e 295 .help("The path to a file or package directory to lint"),
923072b8
FG
296 Arg::new("args")
297 .action(ArgAction::Append)
298 .help("Pass extra arguments to cargo/clippy-driver"),
299 ]),
300 Command::new("rename_lint").about("Renames the given lint").args([
301 Arg::new("old_name")
302 .index(1)
303 .required(true)
304 .help("The name of the lint to rename"),
305 Arg::new("new_name")
306 .index(2)
307 .required_unless_present("uplift")
308 .help("The new name of the lint"),
309 Arg::new("uplift")
310 .long("uplift")
9ffffee4 311 .action(ArgAction::SetTrue)
923072b8
FG
312 .help("This lint will be uplifted into rustc"),
313 ]),
064997fb
FG
314 Command::new("deprecate").about("Deprecates the given lint").args([
315 Arg::new("name")
316 .index(1)
317 .required(true)
318 .help("The name of the lint to deprecate"),
319 Arg::new("reason")
320 .long("reason")
321 .short('r')
064997fb
FG
322 .help("The reason for deprecation"),
323 ]),
923072b8 324 ])
f20569fa
XL
325 .get_matches()
326}