ricecoder_hooks/cli/
mod.rs1pub mod commands;
7pub mod formatter;
8
9pub use commands::{delete_hook, disable_hook, enable_hook, inspect_hook, list_hooks, HookCommand};
10pub use formatter::{format_hook_json, format_hook_table, format_hooks_json, format_hooks_table};
11
12use crate::error::Result;
13use crate::registry::HookRegistry;
14
15pub struct HookCli<R: HookRegistry> {
17 registry: R,
18}
19
20impl<R: HookRegistry> HookCli<R> {
21 pub fn new(registry: R) -> Self {
23 Self { registry }
24 }
25
26 pub fn execute(&mut self, command: HookCommand) -> Result<String> {
28 match command {
29 HookCommand::List { format } => {
30 let hooks = self.registry.list_hooks()?;
31 Ok(match format.as_deref() {
32 Some("json") => format_hooks_json(&hooks)?,
33 _ => format_hooks_table(&hooks),
34 })
35 }
36 HookCommand::Inspect { id, format } => {
37 let hook = self.registry.get_hook(&id)?;
38 Ok(match format.as_deref() {
39 Some("json") => format_hook_json(&hook)?,
40 _ => format_hook_table(&hook),
41 })
42 }
43 HookCommand::Enable { id } => {
44 self.registry.enable_hook(&id)?;
45 Ok(format!("Hook '{}' enabled", id))
46 }
47 HookCommand::Disable { id } => {
48 self.registry.disable_hook(&id)?;
49 Ok(format!("Hook '{}' disabled", id))
50 }
51 HookCommand::Delete { id } => {
52 self.registry.unregister_hook(&id)?;
53 Ok(format!("Hook '{}' deleted", id))
54 }
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::registry::InMemoryHookRegistry;
63 use crate::types::{Action, CommandAction, Hook};
64
65 fn create_test_hook(id: &str, name: &str) -> Hook {
66 Hook {
67 id: id.to_string(),
68 name: name.to_string(),
69 description: Some("Test hook".to_string()),
70 event: "test_event".to_string(),
71 action: Action::Command(CommandAction {
72 command: "echo".to_string(),
73 args: vec!["test".to_string()],
74 timeout_ms: Some(5000),
75 capture_output: true,
76 }),
77 enabled: true,
78 tags: vec!["test".to_string()],
79 metadata: serde_json::json!({}),
80 condition: None,
81 }
82 }
83
84 #[test]
85 fn test_list_hooks() {
86 let mut registry = InMemoryHookRegistry::new();
87 let hook1 = create_test_hook("hook1", "Hook 1");
88 let hook2 = create_test_hook("hook2", "Hook 2");
89
90 registry.register_hook(hook1).unwrap();
91 registry.register_hook(hook2).unwrap();
92
93 let mut cli = HookCli::new(registry);
94 let result = cli.execute(HookCommand::List { format: None }).unwrap();
95
96 assert!(result.contains("Hook 1"));
97 assert!(result.contains("Hook 2"));
98 }
99
100 #[test]
101 fn test_inspect_hook() {
102 let mut registry = InMemoryHookRegistry::new();
103 let hook = create_test_hook("hook1", "Hook 1");
104 registry.register_hook(hook).unwrap();
105
106 let mut cli = HookCli::new(registry);
107 let result = cli
108 .execute(HookCommand::Inspect {
109 id: "hook1".to_string(),
110 format: None,
111 })
112 .unwrap();
113
114 assert!(result.contains("Hook 1"));
115 }
116
117 #[test]
118 fn test_enable_hook() {
119 let mut registry = InMemoryHookRegistry::new();
120 let mut hook = create_test_hook("hook1", "Hook 1");
121 hook.enabled = false;
122 registry.register_hook(hook).unwrap();
123
124 let mut cli = HookCli::new(registry);
125 let result = cli
126 .execute(HookCommand::Enable {
127 id: "hook1".to_string(),
128 })
129 .unwrap();
130
131 assert!(result.contains("enabled"));
132 }
133
134 #[test]
135 fn test_disable_hook() {
136 let mut registry = InMemoryHookRegistry::new();
137 let hook = create_test_hook("hook1", "Hook 1");
138 registry.register_hook(hook).unwrap();
139
140 let mut cli = HookCli::new(registry);
141 let result = cli
142 .execute(HookCommand::Disable {
143 id: "hook1".to_string(),
144 })
145 .unwrap();
146
147 assert!(result.contains("disabled"));
148 }
149
150 #[test]
151 fn test_delete_hook() {
152 let mut registry = InMemoryHookRegistry::new();
153 let hook = create_test_hook("hook1", "Hook 1");
154 registry.register_hook(hook).unwrap();
155
156 let mut cli = HookCli::new(registry);
157 let result = cli
158 .execute(HookCommand::Delete {
159 id: "hook1".to_string(),
160 })
161 .unwrap();
162
163 assert!(result.contains("deleted"));
164 }
165}