systemprompt_cli/commands/web/templates/
delete.rs1use anyhow::{Context, Result, anyhow};
7use clap::Args;
8use std::fs;
9use std::path::Path;
10
11use crate::CliConfig;
12use crate::interactive::{Prompter, require_confirmation, resolve_required};
13use crate::shared::CommandOutput;
14use systemprompt_logging::CliService;
15
16use super::super::paths::WebPaths;
17use super::super::types::{TemplateDeleteOutput, TemplatesConfig};
18use super::selection::prompt_template_selection;
19
20#[derive(Debug, Args)]
21pub struct DeleteArgs {
22 #[arg(help = "Template name")]
23 pub name: Option<String>,
24
25 #[arg(short = 'y', long, help = "Skip confirmation prompts")]
26 pub yes: bool,
27
28 #[arg(long, help = "Also delete the .html file")]
29 pub delete_file: bool,
30}
31
32pub(super) fn execute(
33 args: DeleteArgs,
34 prompter: &dyn Prompter,
35 config: &CliConfig,
36) -> Result<CommandOutput> {
37 execute_in_dir(args, prompter, config, &WebPaths::resolve()?.templates)
38}
39
40pub fn execute_in_dir(
41 args: DeleteArgs,
42 prompter: &dyn Prompter,
43 config: &CliConfig,
44 templates_dir: &Path,
45) -> Result<CommandOutput> {
46 let templates_yaml_path = templates_dir.join("templates.yaml");
47
48 let yaml_content = fs::read_to_string(&templates_yaml_path).with_context(|| {
49 format!(
50 "Failed to read templates config at {}",
51 templates_yaml_path.display()
52 )
53 })?;
54
55 let mut templates_config: TemplatesConfig =
56 serde_yaml::from_str(&yaml_content).with_context(|| {
57 format!(
58 "Failed to parse templates config at {}",
59 templates_yaml_path.display()
60 )
61 })?;
62
63 let name = resolve_required(args.name, "name", config, || {
64 prompt_template_selection(prompter, &templates_config, "Select template to delete")
65 })?;
66
67 if !templates_config.templates.contains_key(&name) {
68 return Err(anyhow!("Template '{}' not found", name));
69 }
70
71 let confirm_msg = if args.delete_file {
72 format!("Delete template '{}' and its HTML file?", name)
73 } else {
74 format!("Delete template '{}'?", name)
75 };
76
77 require_confirmation(prompter, &confirm_msg, args.yes, config)?;
78
79 templates_config.templates.remove(&name);
80
81 let html_file_path = templates_dir.join(format!("{}.html", name));
82 let file_deleted = if args.delete_file && html_file_path.exists() {
83 fs::remove_file(&html_file_path)
84 .with_context(|| format!("Failed to delete HTML file: {}", html_file_path.display()))?;
85 true
86 } else {
87 false
88 };
89
90 let yaml = serde_yaml::to_string(&templates_config).context("Failed to serialize config")?;
91 fs::write(&templates_yaml_path, yaml).with_context(|| {
92 format!(
93 "Failed to write templates config to {}",
94 templates_yaml_path.display()
95 )
96 })?;
97
98 let message = if file_deleted {
99 format!("Template '{}' deleted (including HTML file)", name)
100 } else if html_file_path.exists() {
101 format!(
102 "Template '{}' deleted. HTML file still exists at {}",
103 name,
104 html_file_path.display()
105 )
106 } else {
107 format!("Template '{}' deleted", name)
108 };
109
110 CliService::success(&message);
111
112 let output = TemplateDeleteOutput {
113 deleted: name,
114 file_deleted,
115 message,
116 };
117
118 Ok(CommandOutput::card_value("Template Deleted", &output))
119}