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