1use anyhow::Result;
4use chrono::Utc;
5use clap::Args as ClapArgs;
6use colored::Colorize;
7
8use crate::core::{Adr, AdrStatus, ConfigManager, FlexibleDate, Git, NotesManager, TemplateEngine};
9
10#[derive(ClapArgs, Debug)]
12pub struct Args {
13 pub adr_id: String,
15
16 pub title: String,
18
19 #[arg(long)]
21 pub template: Option<String>,
22}
23
24pub fn run(args: Args) -> Result<()> {
30 let git = Git::new();
31 git.check_repository()?;
32
33 let config = ConfigManager::new(git.clone()).load()?;
34 let notes = NotesManager::new(git.clone(), config.clone());
35
36 let adrs = notes.list()?;
38 let mut old_adr = adrs
39 .into_iter()
40 .find(|a| a.id == args.adr_id || a.id.contains(&args.adr_id))
41 .ok_or_else(|| anyhow::anyhow!("ADR not found: {}", args.adr_id))?;
42
43 eprintln!(
44 "{} Superseding ADR {} with: {}",
45 "→".blue(),
46 old_adr.id.cyan(),
47 args.title.yellow()
48 );
49
50 let next_num = notes.next_number()?;
52 let new_adr_id = notes.format_id(next_num);
53
54 let format = args.template.as_deref().unwrap_or(&config.format);
56
57 let mut new_adr = Adr::new(new_adr_id.clone(), args.title.clone());
59 new_adr.commit = git.head()?;
60 new_adr.frontmatter.status = AdrStatus::Proposed;
61 new_adr.frontmatter.date = Some(FlexibleDate(Utc::now()));
62 new_adr.frontmatter.format = Some(format.to_string());
63
64 new_adr
66 .frontmatter
67 .tags
68 .clone_from(&old_adr.frontmatter.tags);
69
70 new_adr.frontmatter.supersedes = Some(old_adr.id.clone());
72
73 let template_engine = TemplateEngine::new();
75 let mut context = std::collections::HashMap::new();
76 context.insert("title".to_string(), new_adr.frontmatter.title.clone());
77 context.insert("status".to_string(), new_adr.frontmatter.status.to_string());
78 let body = template_engine.render(format, &context)?;
79 new_adr.body = body;
80
81 notes.create(&new_adr)?;
83
84 old_adr.frontmatter.status = AdrStatus::Superseded;
86 old_adr.frontmatter.superseded_by = Some(new_adr_id.clone());
87 notes.update(&old_adr)?;
88
89 eprintln!("{} Created new ADR: {}", "✓".green(), new_adr_id.cyan());
90 eprintln!(
91 "{} Updated {} status to superseded",
92 "✓".green(),
93 old_adr.id.cyan()
94 );
95
96 Ok(())
97}