1use crate::{Result, templates::TemplateRegistry};
4use dialoguer::{Select, theme::ColorfulTheme};
5use std::path::Path;
6
7#[derive(Debug)]
9pub struct TemplateCommand;
10
11impl TemplateCommand {
12 pub fn list() -> Result<()> {
14 let registry = TemplateRegistry::new();
15 let templates = registry.list();
16
17 println!("📦 Available Templates:");
18 println!();
19
20 for template in templates {
21 println!(" {} - {}", template.name, template.description);
22 }
23
24 println!();
25 super::print_info("Use 'driven template apply <name>' to apply a template");
26
27 Ok(())
28 }
29
30 pub fn search(query: &str) -> Result<()> {
32 let registry = TemplateRegistry::new();
33 let results = registry.search(query);
34
35 if results.is_empty() {
36 super::print_warning(&format!("No templates matching '{}'", query));
37 } else {
38 println!("🔍 Templates matching '{}':", query);
39 println!();
40
41 for template in results {
42 println!(" {} - {}", template.name, template.description);
43 }
44 }
45
46 Ok(())
47 }
48
49 pub fn apply(project_root: &Path, template_name: &str) -> Result<()> {
51 let registry = TemplateRegistry::new();
52
53 let template = registry.get(template_name).ok_or_else(|| {
54 crate::DrivenError::Template(format!("Template not found: {}", template_name))
55 })?;
56
57 let spinner = super::create_spinner(&format!("Applying template '{}'...", template_name));
58
59 let content = template.render(&Default::default())?;
61
62 let rules_path = project_root.join(".driven/rules.md");
64 if let Some(parent) = rules_path.parent() {
65 std::fs::create_dir_all(parent).map_err(|e| {
66 crate::DrivenError::Template(format!("Failed to create directory: {}", e))
67 })?;
68 }
69
70 std::fs::write(&rules_path, content).map_err(|e| {
71 crate::DrivenError::Template(format!("Failed to write template: {}", e))
72 })?;
73
74 spinner.finish_and_clear();
75 super::print_success(&format!(
76 "Applied template '{}' to {}",
77 template_name,
78 rules_path.display()
79 ));
80
81 Ok(())
82 }
83
84 pub fn interactive(project_root: &Path) -> Result<()> {
86 let registry = TemplateRegistry::new();
87 let templates = registry.list();
88 let theme = ColorfulTheme::default();
89
90 let items: Vec<_> = templates
91 .iter()
92 .map(|t| format!("{} - {}", t.name, t.description))
93 .collect();
94
95 let selection = Select::with_theme(&theme)
96 .with_prompt("Select a template")
97 .items(&items)
98 .default(0)
99 .interact()
100 .map_err(|e| crate::DrivenError::Cli(e.to_string()))?;
101
102 Self::apply(project_root, &templates[selection].name)
103 }
104}