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