dotenv_linter/
cli.rs

1use clap::{Arg, Command};
2use std::ffi::OsStr;
3
4pub fn new(current_dir: &OsStr) -> Command {
5    Command::new(env!("CARGO_PKG_NAME"))
6        .about(env!("CARGO_PKG_DESCRIPTION"))
7        .author(env!("CARGO_PKG_AUTHORS"))
8        .version(env!("CARGO_PKG_VERSION"))
9        .disable_help_subcommand(true)
10        .propagate_version(true)
11        .mut_arg("version", |a| a.short('v'))
12        .args(common_args(current_dir))
13        .arg(not_check_updates_flag())
14        .subcommands([compare_command(), fix_command(current_dir), list_command()])
15}
16
17fn compare_command<'a>() -> Command<'a> {
18    Command::new("compare")
19        .visible_alias("c")
20        .args(&vec![
21            Arg::new("input")
22                .help("Files to compare")
23                .multiple_occurrences(true)
24                .multiple_values(true)
25                .min_values(2)
26                .required(true),
27            no_color_flag(),
28            quiet_flag(),
29        ])
30        .about("Compares if files have the same keys")
31        .override_usage("dotenv-linter compare [OPTIONS] <input>...")
32}
33
34fn fix_command(current_dir: &OsStr) -> Command {
35    Command::new("fix")
36        .visible_alias("f")
37        .args(common_args(current_dir))
38        .arg(
39            Arg::new("no-backup")
40                .long("no-backup")
41                .help("Prevents backing up .env files"),
42        )
43        .override_usage("dotenv-linter fix [OPTIONS] <input>...")
44        .about("Automatically fixes warnings")
45}
46
47fn list_command<'a>() -> Command<'a> {
48    Command::new("list")
49        .visible_alias("l")
50        .override_usage("dotenv-linter list")
51        .about("Shows list of available checks")
52}
53
54fn common_args(current_dir: &OsStr) -> Vec<Arg> {
55    vec![
56        Arg::new("input")
57            .help("files or paths")
58            .index(1)
59            .default_value_os(current_dir)
60            .multiple_occurrences(true)
61            .multiple_values(true),
62        Arg::new("exclude")
63            .short('e')
64            .long("exclude")
65            .value_name("FILE_NAME")
66            .help("Excludes files from check")
67            .multiple_occurrences(true)
68            .multiple_values(true)
69            .takes_value(true),
70        Arg::new("skip")
71            .short('s')
72            .long("skip")
73            .value_name("CHECK_NAME")
74            .help("Skips checks")
75            .multiple_occurrences(true)
76            .multiple_values(true)
77            .takes_value(true),
78        Arg::new("recursive")
79            .short('r')
80            .long("recursive")
81            .help("Recursively searches and checks .env files"),
82        no_color_flag(),
83        quiet_flag(),
84    ]
85}
86
87fn quiet_flag<'a>() -> Arg<'a> {
88    Arg::new("quiet")
89        .short('q')
90        .long("quiet")
91        .help("Doesn't display additional information")
92}
93
94fn no_color_flag<'a>() -> Arg<'a> {
95    Arg::new("no-color")
96        .long("no-color")
97        .help("Turns off the colored output")
98}
99
100fn not_check_updates_flag<'a>() -> Arg<'a> {
101    Arg::new("not-check-updates")
102        .long("not-check-updates")
103        .help("Doesn't check for updates")
104}
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109    use std::env;
110
111    #[test]
112    fn verify_app() {
113        let current_dir = env::current_dir().expect("Failed to get current dir");
114        new(current_dir.as_os_str()).debug_assert();
115    }
116}