]>
Commit | Line | Data |
---|---|---|
923072b8 FG |
1 | use clap::{Arg, ArgAction, ArgMatches, Command}; |
2 | use std::env; | |
3 | use std::path::PathBuf; | |
4 | ||
5 | fn get_clap_config() -> ArgMatches { | |
6 | Command::new("lintcheck") | |
7 | .about("run clippy on a set of crates and check output") | |
8 | .args([ | |
9 | Arg::new("only") | |
10 | .action(ArgAction::Set) | |
11 | .value_name("CRATE") | |
12 | .long("only") | |
13 | .help("Only process a single crate of the list"), | |
14 | Arg::new("crates-toml") | |
15 | .action(ArgAction::Set) | |
16 | .value_name("CRATES-SOURCES-TOML-PATH") | |
17 | .long("crates-toml") | |
18 | .help("Set the path for a crates.toml where lintcheck should read the sources from"), | |
19 | Arg::new("threads") | |
20 | .action(ArgAction::Set) | |
21 | .value_name("N") | |
22 | .value_parser(clap::value_parser!(usize)) | |
23 | .short('j') | |
24 | .long("jobs") | |
25 | .help("Number of threads to use, 0 automatic choice"), | |
26 | Arg::new("fix") | |
27 | .long("fix") | |
28 | .help("Runs cargo clippy --fix and checks if all suggestions apply"), | |
29 | Arg::new("filter") | |
30 | .long("filter") | |
31 | .action(ArgAction::Append) | |
32 | .value_name("clippy_lint_name") | |
33 | .help("Apply a filter to only collect specified lints, this also overrides `allow` attributes"), | |
34 | Arg::new("markdown") | |
35 | .long("markdown") | |
36 | .help("Change the reports table to use markdown links"), | |
2b03887a FG |
37 | Arg::new("recursive") |
38 | .long("--recursive") | |
39 | .help("Run clippy on the dependencies of crates specified in crates-toml") | |
40 | .conflicts_with("threads") | |
41 | .conflicts_with("fix"), | |
923072b8 FG |
42 | ]) |
43 | .get_matches() | |
44 | } | |
45 | ||
2b03887a | 46 | #[derive(Debug, Clone)] |
923072b8 FG |
47 | pub(crate) struct LintcheckConfig { |
48 | /// max number of jobs to spawn (default 1) | |
49 | pub max_jobs: usize, | |
50 | /// we read the sources to check from here | |
51 | pub sources_toml_path: PathBuf, | |
52 | /// we save the clippy lint results here | |
53 | pub lintcheck_results_path: PathBuf, | |
54 | /// Check only a specified package | |
55 | pub only: Option<String>, | |
56 | /// whether to just run --fix and not collect all the warnings | |
57 | pub fix: bool, | |
58 | /// A list of lints that this lintcheck run should focus on | |
59 | pub lint_filter: Vec<String>, | |
60 | /// Indicate if the output should support markdown syntax | |
61 | pub markdown: bool, | |
2b03887a FG |
62 | /// Run clippy on the dependencies of crates |
63 | pub recursive: bool, | |
923072b8 FG |
64 | } |
65 | ||
66 | impl LintcheckConfig { | |
67 | pub fn new() -> Self { | |
68 | let clap_config = get_clap_config(); | |
69 | ||
70 | // first, check if we got anything passed via the LINTCHECK_TOML env var, | |
71 | // if not, ask clap if we got any value for --crates-toml <foo> | |
72 | // if not, use the default "lintcheck/lintcheck_crates.toml" | |
73 | let sources_toml = env::var("LINTCHECK_TOML").unwrap_or_else(|_| { | |
74 | clap_config | |
75 | .get_one::<String>("crates-toml") | |
2b03887a | 76 | .map_or("lintcheck/lintcheck_crates.toml", |s| &**s) |
923072b8 FG |
77 | .into() |
78 | }); | |
79 | ||
80 | let markdown = clap_config.contains_id("markdown"); | |
81 | let sources_toml_path = PathBuf::from(sources_toml); | |
82 | ||
83 | // for the path where we save the lint results, get the filename without extension (so for | |
84 | // wasd.toml, use "wasd"...) | |
85 | let filename: PathBuf = sources_toml_path.file_stem().unwrap().into(); | |
86 | let lintcheck_results_path = PathBuf::from(format!( | |
87 | "lintcheck-logs/{}_logs.{}", | |
88 | filename.display(), | |
89 | if markdown { "md" } else { "txt" } | |
90 | )); | |
91 | ||
92 | // look at the --threads arg, if 0 is passed, ask rayon rayon how many threads it would spawn and | |
93 | // use half of that for the physical core count | |
94 | // by default use a single thread | |
95 | let max_jobs = match clap_config.get_one::<usize>("threads") { | |
96 | Some(&0) => { | |
97 | // automatic choice | |
98 | // Rayon seems to return thread count so half that for core count | |
2b03887a | 99 | rayon::current_num_threads() / 2 |
923072b8 FG |
100 | }, |
101 | Some(&threads) => threads, | |
102 | // no -j passed, use a single thread | |
103 | None => 1, | |
104 | }; | |
105 | ||
106 | let lint_filter: Vec<String> = clap_config | |
107 | .get_many::<String>("filter") | |
108 | .map(|iter| { | |
109 | iter.map(|lint_name| { | |
110 | let mut filter = lint_name.replace('_', "-"); | |
111 | if !filter.starts_with("clippy::") { | |
112 | filter.insert_str(0, "clippy::"); | |
113 | } | |
114 | filter | |
115 | }) | |
116 | .collect() | |
117 | }) | |
118 | .unwrap_or_default(); | |
119 | ||
120 | LintcheckConfig { | |
121 | max_jobs, | |
122 | sources_toml_path, | |
123 | lintcheck_results_path, | |
124 | only: clap_config.get_one::<String>("only").map(String::from), | |
125 | fix: clap_config.contains_id("fix"), | |
126 | lint_filter, | |
127 | markdown, | |
2b03887a | 128 | recursive: clap_config.contains_id("recursive"), |
923072b8 FG |
129 | } |
130 | } | |
131 | } |