1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use clap::{crate_name, CommandFactory, Parser};
use clap_complete::{generate, Shell};
use std::io;
use std::process::exit;

// displayed when --contributors is invoked
static CONTRIBUTORS: &str = include_str!("../Contributors");

// displayed when --changelog is invoked
static CHANGELOG: &str = include_str!("../ChangeLog");

#[derive(Parser, Debug)]
/// This program analyzes a json file produced with `typos` and makes commits
/// for each correction.
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Cli {
    /// typos file filename to analyze
    #[arg(long, default_value = "")]
    pub filename: String,

    /// minimum length of the typo correction to be considered as correctable automatically.
    #[arg(long, default_value_t = 6)]
    pub minlen: usize,

    /// Prints what it will do without doing it
    #[arg(long, default_value_t = false)]
    pub noop: bool,

    /// Lists typos found in a brief way (does not modify anything)
    #[arg(long, default_value_t = false)]
    pub only_list_typos: bool,

    /// Details output of --only-list-typos option
    #[arg(long, default_value_t = false)]
    pub details: bool,

    /// Message to be used in commits. It may use '{typo}' and '{correction}'.
    #[arg(long, default_value = "Corrects typo '{typo}' into '{correction}'.")]
    pub message: String,

    /// Excludes file from being included in corrections.
    #[arg(long)]
    pub exclude_file: Option<Vec<String>>,

    /// Excludes typo from being corrected.
    #[arg(long)]
    pub exclude_typo: Option<Vec<String>>,

    /// Excludes a correction from being correctable.
    #[arg(long)]
    pub exclude_correction: Option<Vec<String>>,

    /// Debug options that prints information to know what is going on
    #[arg(long, default_value_t = false)]
    pub debug: bool,

    /// prints typos-git-commit contributor's list
    #[arg(long, default_value_t = false)]
    pub contributors: bool,

    /// prints typos-git-commit changelog
    #[arg(long, default_value_t = false)]
    pub changelog: bool,

    /// prints typos-git-commit bash completion's shell script
    #[arg(long, default_value = None)]
    pub completion: Option<Shell>,
}

impl Cli {
    pub fn analyze() -> Self {
        /* Parsing Cli to either print contributors, changelog, shell's completion
         * scripts or be sure that --filename option has been filed.
         */
        let cli = Cli::parse();

        if cli.contributors {
            print!("{CONTRIBUTORS}");
            exit(0);
        }

        if cli.changelog {
            print!("{CHANGELOG}");
            exit(0);
        }

        if let Some(shell) = cli.completion {
            let mut cmd = Cli::command();
            generate(shell, &mut cmd, crate_name!(), &mut io::stdout());
            exit(0);
        }

        if cli.filename.is_empty() {
            let mut cmd = Cli::command();
            match cmd.print_help() {
                Ok(_) => eprintln!("\nerror: one of these --filename, --contributors, --changelog, --completion must be used."),
                Err(e) => eprintln!("error while printing help: {e}"),
            }
            exit(1);
        }

        cli
    }
}