solar_core/tool/
vhooks.rs1use crate::{Config, Global, SolarError, ToolTrait};
2use clap::Parser;
3use derive_getters::Getters;
4use rust_terminal::Terminal;
5use serde::{Deserialize, Serialize};
6use std::{
7 fs,
8 path::{Path, PathBuf},
9};
10
11fn default_name() -> String {
12 ".hooks".to_string()
13}
14
15#[derive(Parser, Clone, Default, PartialEq, Debug, Serialize, Deserialize, Getters)]
16pub struct Vhooks {
17 #[arg(short, long, default_value = ".")]
19 #[serde(skip)]
20 destination: PathBuf,
21
22 #[arg(short, long, default_value = ".hooks")]
24 #[serde(default = "default_name")]
25 name: String,
26
27 #[arg(short, long, default_value = "false")]
29 #[serde(skip)]
30 remove_all: bool,
31}
32
33impl Vhooks {
34 pub fn new(destination: PathBuf, name: String, remove_all: bool) -> Self {
35 Self {
36 destination,
37 name,
38 remove_all,
39 }
40 }
41
42 pub fn move_hooks(prev: &PathBuf, new: &Path) -> Result<(), SolarError> {
43 for item in fs::read_dir(prev)? {
44 let item = item?;
45 fs::rename(item.path(), new.join(item.file_name()))?;
46 }
47 Ok(())
48 }
49
50 pub fn set_hooks_path(&self, path: PathBuf) -> Result<(), SolarError> {
51 Terminal::command()
52 .current_dir(&self.destination)
53 .piped()
54 .run(
55 "git",
56 vec![
57 "config",
58 "core.hooksPath",
59 path.to_str().ok_or("Could not convert path to string.")?,
60 ],
61 )?;
62 Ok(())
63 }
64}
65
66impl ToolTrait for Vhooks {
67 fn set_dest(&mut self, dest: &Path) {
68 self.destination = dest.to_path_buf();
69 }
70
71 fn install(&mut self) -> Result<(), SolarError> {
72 let config = Config::load_or_default(&self.destination);
74 let current_tool_cfg = config.vhooks().clone();
75 config.set_vhooks(Some(self.clone())).save()?;
76
77 Global::git_init(&self.destination)?;
79
80 let hooks_path = self.destination.join(&self.name);
82
83 fs::create_dir_all(&hooks_path)?;
85
86 self.set_hooks_path(PathBuf::from(format!("./{}", &self.name)))?;
88
89 if let Some(vhooks) = current_tool_cfg {
91 let old_hooks_path = self.destination.join(vhooks.name());
92 Self::move_hooks(&old_hooks_path, &hooks_path)?;
93 fs::remove_dir_all(&old_hooks_path)?;
94 }
95
96 Ok(())
97 }
98
99 fn uninstall(&mut self) -> Result<(), SolarError> {
100 let config = Config::load_from(&self.destination)?;
101 let current_tool_cfg: Self = config
102 .vhooks()
103 .clone()
104 .ok_or("Cannot uninstall vhooks - vhooks not found in configuration.")?;
105
106 let hooks_path = self.destination.join(current_tool_cfg.name());
108 let default_path = self.destination.join(Global::default_git_hook_dir());
109
110 Global::is_git(&self.destination)?;
112
113 fs::create_dir_all(&default_path)?;
115
116 if !self.remove_all {
118 Self::move_hooks(&hooks_path, &default_path)?;
119 }
120
121 self.set_hooks_path(PathBuf::from(format!(
123 "./{}",
124 Global::default_git_hook_dir()
125 .to_str()
126 .ok_or("Could not convert path to string.")?
127 )))?;
128
129 fs::remove_dir_all(&hooks_path)?;
131
132 let config = config.set_vhooks(None);
134 match config.is_empty() {
135 true => fs::remove_file(config.path())?,
136 false => config.save()?,
137 }
138
139 Ok(())
140 }
141}