typos_git_commit/
keyvalue.rs1use crate::cli::Cli;
2use fluent_i18n::t;
3use std::io::{self, Write};
4use std::process::{Command, Output};
5
6#[derive(Eq, Hash, PartialEq, Debug)]
9pub struct Key {
10 pub typo: String,
11 pub corrections: Vec<String>,
12}
13
14fn output_detected_errors(output: &Output, message: &str) {
19 eprintln!("{message}");
20 if let Err(e) = io::stderr().write_all(&output.stderr) {
21 eprintln!("{}", t!("keyvalue-error-stderr", {"e" => e.to_string()}));
22 }
23 if let Err(e) = io::stdout().write_all(&output.stdout) {
24 eprintln!("{}", t!("keyvalue-error-stdout", {"e" => e.to_string()}));
25 }
26}
27
28impl Key {
29 #[must_use]
31 pub fn is_typo_correctable(&self, cli: &Cli) -> bool {
32 match &cli.typo {
33 Some(typos) => typos.contains(&self.typo) && self.corrections.len() == 1 && self.typo.len() >= cli.minlen,
34 None => self.corrections.len() == 1 && self.typo.len() >= cli.minlen,
35 }
36 }
37
38 pub fn run_sed(&self, files: &Vec<String>, cli: &Cli) {
45 if !self.is_typo_correctable(cli) {
46 return;
47 }
48
49 let sed_script = format!("s/\\b{}\\b/{}/g", self.typo, self.corrections[0]);
51
52 if cli.noop {
53 println!("sed --in-place --expression={sed_script} {files:?}");
54 } else {
55 let output = Command::new("sed")
56 .arg("--in-place")
57 .arg(format!("--expression={sed_script}"))
58 .args(files)
59 .output()
60 .unwrap_or_else(|_| panic!("{}", t!("keyvalue-process-sed")));
61
62 if !output.status.success() {
63 output_detected_errors(&output, t!("keyvalue-error-sed", { "typo" => self.typo, "correction" => format!("{:?}", self.corrections[0])}).as_str());
64 }
65 }
66 }
67
68 fn format_git_message(&self, cli: &Cli) -> String {
71 if let Some(correction) = self.corrections.first() {
72 cli.message.replace("{typo}", &self.typo).replace("{correction}", correction)
73 } else {
74 cli.message.replace("{typo}", &self.typo)
75 }
76 }
77
78 pub fn run_git_commit(&self, cli: &Cli) {
87 if !self.is_typo_correctable(cli) {
88 return;
89 }
90
91 let git_message = self.format_git_message(cli);
94
95 if cli.noop {
96 println!("git commit --all --message={git_message}");
97 } else {
98 let output = Command::new("git")
103 .arg("commit")
104 .arg("--all")
105 .arg(format!("--message={git_message}"))
106 .output()
107 .expect("failed to execute git process");
108
109 if !output.status.success() {
110 output_detected_errors(&output, t!("keyvalue-error-git", { "typo" => self.typo, "correction" => format!("{:?}", self.corrections[0])}).as_str());
111 }
112 }
113 }
114}
115
116#[derive(Eq, Hash, PartialEq, Debug)]
118pub struct Value {
119 pub path: String,
120 pub line_num: u32,
121 pub byte_offset: u32,
122}
123
124impl Value {
125 pub fn print_value_details(&self) {
126 println!(
127 "\t{}",
128 t!("thashmap-typo-details", {"path" => self.path, "line" => self.line_num, "offset" => self.byte_offset})
129 );
130 }
131}