1use std::process::Command;
7
8use anyhow::{Result, anyhow};
9use colored::Colorize;
10use zoi_core::types::{self, Hooks, PlatformOrStringVec};
11use zoi_core::utils;
12
13pub mod global;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum HookType {
19 PreInstall,
21 PostInstall,
23 PreUpgrade,
25 PostUpgrade,
27 PreRemove,
29 PostRemove
31}
32
33fn execute_commands(commands: &[String], scope: types::Scope) -> Result<()> {
35 let scope_str = format!("{scope:?}").to_lowercase();
36 for cmd_str in commands {
37 println!("> {}", cmd_str.cyan());
38 let mut command = if cfg!(target_os = "windows") {
39 let mut c = Command::new("pwsh");
40 c.arg("-Command").arg(cmd_str);
41 c
42 } else {
43 let mut c = Command::new("bash");
44 c.arg("-c").arg(cmd_str);
45 c
46 };
47
48 command.env("ZOI_SCOPE", &scope_str);
49
50 let status = command.status()?;
51
52 if !status.success() {
53 return Err(anyhow!("Hook command failed: {cmd_str}"));
54 }
55 }
56 Ok(())
57}
58
59pub fn run_hooks(
72 hooks: &Hooks,
73 hook_type: HookType,
74 scope: types::Scope
75) -> Result<()> {
76 let platform = utils::get_platform()?;
77
78 let commands_to_run = match hook_type {
79 HookType::PreInstall => &hooks.pre_install,
80 HookType::PostInstall => &hooks.post_install,
81 HookType::PreUpgrade => &hooks.pre_upgrade,
82 HookType::PostUpgrade => &hooks.post_upgrade,
83 HookType::PreRemove => &hooks.pre_remove,
84 HookType::PostRemove => &hooks.post_remove
85 };
86
87 if let Some(platform_or_string_vec) = commands_to_run {
88 match platform_or_string_vec {
89 PlatformOrStringVec::StringVec(cmds) => {
90 execute_commands(cmds, scope)?;
91 }
92 PlatformOrStringVec::Platform(platform_map) => {
93 if let Some(cmds) = platform_map.get(&platform) {
94 execute_commands(cmds, scope)?;
95 } else if let Some(cmds) = platform_map.get("default") {
96 execute_commands(cmds, scope)?;
97 }
98 }
99 }
100 }
101
102 Ok(())
103}