1use anyhow::Result;
4use clap::Args as ClapArgs;
5use colored::Colorize;
6
7use crate::core::{ConfigManager, Git, NotesManager, TemplateEngine};
8
9#[derive(ClapArgs, Debug)]
11pub struct Args {
12 pub adr_id: String,
14
15 #[arg(long, short)]
17 pub to: String,
18
19 #[arg(long)]
21 pub in_place: bool,
22}
23
24const FORMATS: &[&str] = &["nygard", "madr", "y-statement", "alexandrian"];
26
27pub fn run(args: Args) -> Result<()> {
33 let git = Git::new();
34 git.check_repository()?;
35
36 let config = ConfigManager::new(git.clone()).load()?;
37 let notes = NotesManager::new(git, config);
38
39 if !FORMATS.contains(&args.to.as_str()) {
41 anyhow::bail!(
42 "Unknown format: {}. Supported formats: {}",
43 args.to,
44 FORMATS.join(", ")
45 );
46 }
47
48 let adrs = notes.list()?;
50 let mut adr = adrs
51 .into_iter()
52 .find(|a| a.id == args.adr_id || a.id.contains(&args.adr_id))
53 .ok_or_else(|| anyhow::anyhow!("ADR not found: {}", args.adr_id))?;
54
55 let current_format = adr.frontmatter.format.as_deref().unwrap_or("nygard");
56
57 if current_format == args.to {
58 eprintln!(
59 "{} ADR is already in {} format",
60 "!".yellow(),
61 args.to.cyan()
62 );
63 return Ok(());
64 }
65
66 eprintln!(
67 "{} Converting ADR {} from {} to {}",
68 "→".blue(),
69 adr.id.cyan(),
70 current_format.yellow(),
71 args.to.green()
72 );
73
74 let template_engine = TemplateEngine::new();
76 let mut context = std::collections::HashMap::new();
77 context.insert("title".to_string(), adr.frontmatter.title.clone());
78 context.insert("status".to_string(), adr.frontmatter.status.to_string());
79 let new_body = template_engine.render(&args.to, &context)?;
80
81 adr.frontmatter.format = Some(args.to.clone());
83 adr.body = new_body;
84
85 if args.in_place {
86 notes.update(&adr)?;
88 eprintln!("{} ADR {} converted and saved", "✓".green(), adr.id.cyan());
89 } else {
90 println!("{}", adr.to_markdown()?);
92 eprintln!();
93 eprintln!("{} Use {} to save changes", "→".blue(), "--in-place".cyan());
94 }
95
96 Ok(())
97}