ggen_cli_lib/cmds/hook/
remove.rs

1//! Remove knowledge hooks and uninstall them from the system.
2//!
3//! This module provides commands to remove hooks, which involves:
4//! - Deleting hook configuration files
5//! - Uninstalling git hooks from .git/hooks/
6//! - Stopping file watchers
7//! - Removing cron jobs
8//!
9//! # Examples
10//!
11//! ```bash
12//! # Remove a hook (with confirmation)
13//! ggen hook remove "pre-commit"
14//!
15//! # Force remove without confirmation
16//! ggen hook remove "nightly-rebuild" --force
17//! ```
18
19use clap::Args;
20use ggen_utils::error::Result;
21
22#[derive(Args, Debug)]
23pub struct RemoveArgs {
24    /// Hook name to remove
25    pub name: String,
26
27    /// Force removal without confirmation
28    #[arg(short = 'f', long)]
29    pub force: bool,
30}
31
32/// Main entry point for `ggen hook remove`
33pub async fn run(args: &RemoveArgs) -> Result<()> {
34    // Validate hook name
35    if args.name.trim().is_empty() {
36        return Err(ggen_utils::error::Error::new("Hook name cannot be empty"));
37    }
38
39    println!("🗑️  Removing hook '{}'...", args.name);
40
41    // TODO: Check if hook exists
42    // For now, assume it exists
43
44    if !args.force {
45        println!("\n⚠️  This will:");
46        println!("  - Delete hook configuration");
47        println!("  - Uninstall git hooks (if applicable)");
48        println!("  - Stop file watchers (if applicable)");
49        println!("  - Remove cron jobs (if applicable)");
50        println!("\nAre you sure you want to continue? (y/N)");
51
52        // TODO: Implement actual confirmation prompt
53        // For now, just proceed
54        println!("Proceeding with removal...");
55    }
56
57    // TODO: Implement actual hook removal
58    // This will involve:
59    // 1. Load hook config to determine type
60    // 2. Uninstall git hook if trigger is git-*
61    // 3. Stop file watcher process if trigger is file-watch
62    // 4. Remove cron job if trigger is cron
63    // 5. Delete hook config file from .ggen/hooks/
64
65    println!("  Uninstalling hook from system...");
66    println!("  Deleting hook configuration...");
67
68    println!("\n✅ Hook '{}' removed successfully!", args.name);
69
70    Ok(())
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[tokio::test]
78    async fn test_remove_hook_basic() {
79        let args = RemoveArgs {
80            name: "test-hook".to_string(),
81            force: true, // Force to skip confirmation
82        };
83        let result = run(&args).await;
84        assert!(result.is_ok());
85    }
86
87    #[tokio::test]
88    async fn test_remove_hook_empty_name() {
89        let args = RemoveArgs {
90            name: "".to_string(),
91            force: true,
92        };
93        let result = run(&args).await;
94        assert!(result.is_err());
95    }
96
97    #[tokio::test]
98    async fn test_remove_hook_with_force() {
99        let args = RemoveArgs {
100            name: "test-hook".to_string(),
101            force: true,
102        };
103        let result = run(&args).await;
104        assert!(result.is_ok());
105    }
106}