git_revise/
revise.rs

1pub mod prompts;
2pub mod status;
3pub mod template;
4
5use std::collections::HashMap;
6
7use inquire::InquireError;
8use status::Status;
9use template::Template;
10
11use crate::{
12    cli::ReviseCommands,
13    config::{self, Hook},
14    error::ReviseResult,
15    git::GitUtils,
16    hook::{HookRunner, HookType},
17};
18
19#[derive(Default, Debug)]
20pub struct Revise {
21    pub template: Template,
22    pub status: Status,
23    pub message: String,
24    pub hooks: HashMap<HookType, Vec<Hook>>,
25}
26
27impl Revise {
28    pub async fn run(&mut self, cmd: ReviseCommands) -> ReviseResult<()> {
29        let cfg = config::get_config();
30        self.hooks.clone_from(&cfg.hooks);
31        // if message is not empty, return it
32        if let Some(msg) = &cmd.message {
33            self.run_pre_commit_hooks()?;
34            GitUtils::new().commit(msg)?;
35            self.run_post_commit_hooks()?;
36            return Ok(());
37        }
38
39        if !cmd.add.is_empty() {
40            self.run_pre_add_hooks()?;
41            GitUtils::new().add(&cmd.add)?;
42            self.run_post_add_hooks()?;
43        }
44        self.run_pre_commit_hooks()?;
45        match self.template.run(&cmd).await {
46            Ok(msg) => {
47                GitUtils::new().commit(&msg)?;
48                self.run_post_commit_hooks()?;
49                Ok(())
50            }
51            Err(err) => {
52                if let Some(
53                    InquireError::OperationCanceled
54                    | InquireError::OperationInterrupted,
55                ) = err.downcast_ref()
56                {
57                    Ok(())
58                } else {
59                    Err(err)
60                }
61            }
62        }
63    }
64
65    pub fn run_pre_commit_hooks(&self) -> ReviseResult<()> {
66        let hooks = self.hooks.get(&HookType::PreCommit);
67        let mut sorted_hooks: Vec<_> = hooks.unwrap().iter().collect();
68        sorted_hooks.sort_by_key(|h| h.order.unwrap_or(u32::MAX));
69
70        for hook in sorted_hooks {
71            if hook.skip.unwrap_or(false) {
72                println!("Skipping hook: {}", hook.command);
73                continue;
74            }
75            HookRunner::run_hook(HookRunner::run_command, &hook.command)?;
76        }
77        Ok(())
78    }
79
80    pub fn run_post_commit_hooks(&self) -> ReviseResult<()> {
81        let hooks = self.hooks.get(&HookType::PostCommit);
82        let mut sorted_hooks: Vec<_> = hooks.unwrap().iter().collect();
83        sorted_hooks.sort_by_key(|h| h.order.unwrap_or(u32::MAX));
84
85        for hook in sorted_hooks {
86            if hook.skip.unwrap_or(false) {
87                println!("Skipping hook: {}", hook.command);
88                continue;
89            }
90            HookRunner::run_hook(HookRunner::run_command, &hook.command)?;
91        }
92        Ok(())
93    }
94
95    pub fn run_pre_add_hooks(&self) -> ReviseResult<()> {
96        let hooks = self.hooks.get(&HookType::PreAdd);
97        let mut sorted_hooks: Vec<_> = hooks.unwrap().iter().collect();
98        sorted_hooks.sort_by_key(|h| h.order.unwrap_or(u32::MAX));
99
100        for hook in sorted_hooks {
101            if hook.skip.unwrap_or(false) {
102                println!("Skipping hook: {}", hook.command);
103                continue;
104            }
105            HookRunner::run_hook(HookRunner::run_command, &hook.command)?;
106        }
107        Ok(())
108    }
109
110    pub fn run_post_add_hooks(&self) -> ReviseResult<()> {
111        let hooks = self.hooks.get(&HookType::PostAdd);
112        let mut sorted_hooks: Vec<_> = hooks.unwrap().iter().collect();
113        sorted_hooks.sort_by_key(|h| h.order.unwrap_or(u32::MAX));
114
115        for hook in sorted_hooks {
116            if hook.skip.unwrap_or(false) {
117                println!("Skipping hook: {}", hook.command);
118                continue;
119            }
120            HookRunner::run_hook(HookRunner::run_command, &hook.command)?;
121        }
122        Ok(())
123    }
124}