]> git.lizzy.rs Git - rust.git/blob - clippy_dev/src/main.rs
Auto merge of #95524 - oli-obk:cached_stable_hash_cleanups, r=nnethercote
[rust.git] / clippy_dev / src / main.rs
1 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
2 // warn on lints, that are included in `rust-lang/rust`s bootstrap
3 #![warn(rust_2018_idioms, unused_lifetimes)]
4
5 use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
6 use clippy_dev::{bless, fmt, lint, new_lint, serve, setup, update_lints};
7 use indoc::indoc;
8 fn main() {
9     let matches = get_clap_config();
10
11     match matches.subcommand() {
12         ("bless", Some(matches)) => {
13             bless::bless(matches.is_present("ignore-timestamp"));
14         },
15         ("fmt", Some(matches)) => {
16             fmt::run(matches.is_present("check"), matches.is_present("verbose"));
17         },
18         ("update_lints", Some(matches)) => {
19             if matches.is_present("print-only") {
20                 update_lints::print_lints();
21             } else if matches.is_present("check") {
22                 update_lints::run(update_lints::UpdateMode::Check);
23             } else {
24                 update_lints::run(update_lints::UpdateMode::Change);
25             }
26         },
27         ("new_lint", Some(matches)) => {
28             match new_lint::create(
29                 matches.value_of("pass"),
30                 matches.value_of("name"),
31                 matches.value_of("category"),
32                 matches.is_present("msrv"),
33             ) {
34                 Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
35                 Err(e) => eprintln!("Unable to create lint: {}", e),
36             }
37         },
38         ("setup", Some(sub_command)) => match sub_command.subcommand() {
39             ("intellij", Some(matches)) => setup::intellij::setup_rustc_src(
40                 matches
41                     .value_of("rustc-repo-path")
42                     .expect("this field is mandatory and therefore always valid"),
43             ),
44             ("git-hook", Some(matches)) => setup::git_hook::install_hook(matches.is_present("force-override")),
45             ("vscode-tasks", Some(matches)) => setup::vscode::install_tasks(matches.is_present("force-override")),
46             _ => {},
47         },
48         ("remove", Some(sub_command)) => match sub_command.subcommand() {
49             ("git-hook", Some(_)) => setup::git_hook::remove_hook(),
50             ("intellij", Some(_)) => setup::intellij::remove_rustc_src(),
51             ("vscode-tasks", Some(_)) => setup::vscode::remove_tasks(),
52             _ => {},
53         },
54         ("serve", Some(matches)) => {
55             let port = matches.value_of("port").unwrap().parse().unwrap();
56             let lint = matches.value_of("lint");
57             serve::run(port, lint);
58         },
59         ("lint", Some(matches)) => {
60             let path = matches.value_of("path").unwrap();
61             lint::run(path);
62         },
63         _ => {},
64     }
65 }
66
67 fn get_clap_config<'a>() -> ArgMatches<'a> {
68     App::new("Clippy developer tooling")
69         .setting(AppSettings::ArgRequiredElseHelp)
70         .subcommand(
71             SubCommand::with_name("bless")
72                 .about("bless the test output changes")
73                 .arg(
74                     Arg::with_name("ignore-timestamp")
75                         .long("ignore-timestamp")
76                         .help("Include files updated before clippy was built"),
77                 ),
78         )
79         .subcommand(
80             SubCommand::with_name("fmt")
81                 .about("Run rustfmt on all projects and tests")
82                 .arg(
83                     Arg::with_name("check")
84                         .long("check")
85                         .help("Use the rustfmt --check option"),
86                 )
87                 .arg(
88                     Arg::with_name("verbose")
89                         .short("v")
90                         .long("verbose")
91                         .help("Echo commands run"),
92                 ),
93         )
94         .subcommand(
95             SubCommand::with_name("update_lints")
96                 .about("Updates lint registration and information from the source code")
97                 .long_about(
98                     "Makes sure that:\n \
99                  * the lint count in README.md is correct\n \
100                  * the changelog contains markdown link references at the bottom\n \
101                  * all lint groups include the correct lints\n \
102                  * lint modules in `clippy_lints/*` are visible in `src/lifb.rs` via `pub mod`\n \
103                  * all lints are registered in the lint store",
104                 )
105                 .arg(Arg::with_name("print-only").long("print-only").help(
106                     "Print a table of lints to STDOUT. \
107                  This does not include deprecated and internal lints. \
108                  (Does not modify any files)",
109                 ))
110                 .arg(
111                     Arg::with_name("check")
112                         .long("check")
113                         .help("Checks that `cargo dev update_lints` has been run. Used on CI."),
114                 ),
115         )
116         .subcommand(
117             SubCommand::with_name("new_lint")
118                 .about("Create new lint and run `cargo dev update_lints`")
119                 .arg(
120                     Arg::with_name("pass")
121                         .short("p")
122                         .long("pass")
123                         .help("Specify whether the lint runs during the early or late pass")
124                         .takes_value(true)
125                         .possible_values(&["early", "late"])
126                         .required(true),
127                 )
128                 .arg(
129                     Arg::with_name("name")
130                         .short("n")
131                         .long("name")
132                         .help("Name of the new lint in snake case, ex: fn_too_long")
133                         .takes_value(true)
134                         .required(true),
135                 )
136                 .arg(
137                     Arg::with_name("category")
138                         .short("c")
139                         .long("category")
140                         .help("What category the lint belongs to")
141                         .default_value("nursery")
142                         .possible_values(&[
143                             "style",
144                             "correctness",
145                             "suspicious",
146                             "complexity",
147                             "perf",
148                             "pedantic",
149                             "restriction",
150                             "cargo",
151                             "nursery",
152                             "internal",
153                             "internal_warn",
154                         ])
155                         .takes_value(true),
156                 )
157                 .arg(
158                     Arg::with_name("msrv")
159                         .long("msrv")
160                         .help("Add MSRV config code to the lint"),
161                 ),
162         )
163         .subcommand(
164             SubCommand::with_name("setup")
165                 .about("Support for setting up your personal development environment")
166                 .setting(AppSettings::ArgRequiredElseHelp)
167                 .subcommand(
168                     SubCommand::with_name("intellij")
169                         .about("Alter dependencies so Intellij Rust can find rustc internals")
170                         .arg(
171                             Arg::with_name("rustc-repo-path")
172                                 .long("repo-path")
173                                 .short("r")
174                                 .help("The path to a rustc repo that will be used for setting the dependencies")
175                                 .takes_value(true)
176                                 .value_name("path")
177                                 .required(true),
178                         ),
179                 )
180                 .subcommand(
181                     SubCommand::with_name("git-hook")
182                         .about("Add a pre-commit git hook that formats your code to make it look pretty")
183                         .arg(
184                             Arg::with_name("force-override")
185                                 .long("force-override")
186                                 .short("f")
187                                 .help("Forces the override of an existing git pre-commit hook")
188                                 .required(false),
189                         ),
190                 )
191                 .subcommand(
192                     SubCommand::with_name("vscode-tasks")
193                         .about("Add several tasks to vscode for formatting, validation and testing")
194                         .arg(
195                             Arg::with_name("force-override")
196                                 .long("force-override")
197                                 .short("f")
198                                 .help("Forces the override of existing vscode tasks")
199                                 .required(false),
200                         ),
201                 ),
202         )
203         .subcommand(
204             SubCommand::with_name("remove")
205                 .about("Support for undoing changes done by the setup command")
206                 .setting(AppSettings::ArgRequiredElseHelp)
207                 .subcommand(SubCommand::with_name("git-hook").about("Remove any existing pre-commit git hook"))
208                 .subcommand(SubCommand::with_name("vscode-tasks").about("Remove any existing vscode tasks"))
209                 .subcommand(
210                     SubCommand::with_name("intellij")
211                         .about("Removes rustc source paths added via `cargo dev setup intellij`"),
212                 ),
213         )
214         .subcommand(
215             SubCommand::with_name("serve")
216                 .about("Launch a local 'ALL the Clippy Lints' website in a browser")
217                 .arg(
218                     Arg::with_name("port")
219                         .long("port")
220                         .short("p")
221                         .help("Local port for the http server")
222                         .default_value("8000")
223                         .validator_os(serve::validate_port),
224                 )
225                 .arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
226         )
227         .subcommand(
228             SubCommand::with_name("lint")
229                 .about("Manually run clippy on a file or package")
230                 .after_help(indoc! {"
231                     EXAMPLES
232                         Lint a single file:
233                             cargo dev lint tests/ui/attrs.rs
234
235                         Lint a package directory:
236                             cargo dev lint tests/ui-cargo/wildcard_dependencies/fail
237                             cargo dev lint ~/my-project
238                 "})
239                 .arg(
240                     Arg::with_name("path")
241                         .required(true)
242                         .help("The path to a file or package directory to lint"),
243                 ),
244         )
245         .get_matches()
246 }