Skip to main content

tidy/
arg_parser.rs

1use std::num::NonZeroUsize;
2use std::path::PathBuf;
3
4use clap::{Arg, ArgAction, ArgMatches, Command, value_parser};
5
6#[cfg(test)]
7mod tests;
8
9#[derive(Debug, Clone)]
10pub struct TidyArgParser {
11    pub root_path: PathBuf,
12    pub cargo: PathBuf,
13    pub output_directory: PathBuf,
14    pub concurrency: NonZeroUsize,
15    pub npm: PathBuf,
16    pub verbose: bool,
17    pub bless: bool,
18    pub extra_checks: Option<Vec<String>>,
19    pub pos_args: Vec<String>,
20}
21
22impl TidyArgParser {
23    fn command() -> Command {
24        Command::new("rust-tidy")
25            .arg(
26                Arg::new("root_path")
27                    .help("path of the root directory")
28                    .long("root-path")
29                    .required(true)
30                    .value_parser(value_parser!(PathBuf)),
31            )
32            .arg(
33                Arg::new("cargo")
34                    .help("path of cargo")
35                    .long("cargo-path")
36                    .required(true)
37                    .value_parser(value_parser!(PathBuf)),
38            )
39            .arg(
40                Arg::new("output_directory")
41                    .help("path of output directory")
42                    .long("output-dir")
43                    .required(true)
44                    .value_parser(value_parser!(PathBuf)),
45            )
46            .arg(
47                Arg::new("concurrency")
48                    .help("number of threads working concurrently")
49                    .long("concurrency")
50                    .required(true)
51                    .value_parser(value_parser!(NonZeroUsize)),
52            )
53            .arg(
54                Arg::new("npm")
55                    .help("path of npm")
56                    .long("npm-path")
57                    .required(true)
58                    .value_parser(value_parser!(PathBuf)),
59            )
60            .arg(Arg::new("verbose").help("verbose").long("verbose").action(ArgAction::SetTrue))
61            .arg(Arg::new("bless").help("target files are modified").long("bless").action(ArgAction::SetTrue))
62            .arg(
63                Arg::new("extra_checks")
64                    .help("extra checks")
65                    .long("extra-checks")
66                    .value_delimiter(',')
67                    .action(ArgAction::Append),
68            )
69            .arg(Arg::new("pos_args").help("for extra checks. you can specify configs and target files for external check tools").action(ArgAction::Append).last(true))
70    }
71
72    fn build(matches: ArgMatches) -> Self {
73        let mut tidy_flags = Self {
74            root_path: matches.get_one::<PathBuf>("root_path").unwrap().clone(),
75            cargo: matches.get_one::<PathBuf>("cargo").unwrap().clone(),
76            output_directory: matches.get_one::<PathBuf>("output_directory").unwrap().clone(),
77            concurrency: *matches.get_one::<NonZeroUsize>("concurrency").unwrap(),
78            npm: matches.get_one::<PathBuf>("npm").unwrap().clone(),
79            verbose: *matches.get_one::<bool>("verbose").unwrap(),
80            bless: *matches.get_one::<bool>("bless").unwrap(),
81            extra_checks: None,
82            pos_args: vec![],
83        };
84
85        if let Some(extra_checks) = matches.get_many::<String>("extra_checks") {
86            tidy_flags.extra_checks = Some(extra_checks.map(|s| s.to_string()).collect::<Vec<_>>());
87        }
88
89        tidy_flags.pos_args = matches
90            .get_many::<String>("pos_args")
91            .unwrap_or_default()
92            .map(|v| v.to_string())
93            .collect::<Vec<_>>();
94
95        tidy_flags
96    }
97
98    pub fn parse() -> Self {
99        let matches = Self::command().get_matches();
100        Self::build(matches)
101    }
102}