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
14impl Key {
15 #[must_use]
17 pub fn is_typo_correctable(&self, cli: &Cli) -> bool {
18 match &cli.typo {
19 Some(typos) => typos.contains(&self.typo) && self.corrections.len() == 1 && self.typo.len() >= cli.minlen,
20 None => self.corrections.len() == 1 && self.typo.len() >= cli.minlen,
21 }
22 }
23
24 pub fn run_sed(&self, files: &Vec<String>, cli: &Cli) {
31 if self.is_typo_correctable(cli) {
32 let sed_script = format!("s/\\b{}\\b/{}/g", self.typo, self.corrections[0]);
34
35 if cli.noop {
36 println!("sed --in-place --expression={sed_script} {files:?}");
37 } else {
38 let output = Command::new("sed")
39 .arg("--in-place")
40 .arg(format!("--expression={sed_script}"))
41 .args(files)
42 .output()
43 .unwrap_or_else(|_| panic!("{}", t!("keyvalue-process-sed")));
44
45 if !output.status.success() {
46 output_detected_errors(&output, t!("keyvalue-error-sed", { "typo" => self.typo, "correction" => format!("{:?}", self.corrections[0])}).as_str());
47 }
48 }
49 }
50 }
51
52 pub fn run_git_commit(&self, cli: &Cli) {
61 if self.is_typo_correctable(cli) {
62 let typo_message = if cli.message.contains("{typo}") {
64 &cli.message.replace("{typo}", &self.typo)
65 } else {
66 &cli.message
67 };
68
69 let git_message: &String = if cli.message.contains("{correction}") {
70 &typo_message.replace("{correction}", &self.corrections[0])
71 } else {
72 typo_message
73 };
74
75 if cli.noop {
76 println!("git commit --all --message={git_message}");
77 } else {
78 let output = Command::new("git")
83 .arg("commit")
84 .arg("--all")
85 .arg(format!("--message={git_message}"))
86 .output()
87 .expect("failed to execute git process");
88
89 if !output.status.success() {
90 output_detected_errors(&output, t!("keyvalue-error-git", { "typo" => self.typo, "correction" => format!("{:?}", self.corrections[0])}).as_str());
91 }
92 }
93 }
94 }
95}
96
97#[derive(Eq, Hash, PartialEq, Debug)]
99pub struct Value {
100 pub path: String,
101 pub line_num: u32,
102 pub byte_offset: u32,
103}
104
105fn output_detected_errors(output: &Output, message: &str) {
110 eprintln!("{message}");
111 if let Err(e) = io::stderr().write_all(&output.stderr) {
112 eprintln!("{}", t!("keyvalue-error-stderr", {"e" => e.to_string()}));
113 }
114 if let Err(e) = io::stdout().write_all(&output.stdout) {
115 eprintln!("{}", t!("keyvalue-error-stdout", {"e" => e.to_string()}));
116 }
117}