1use crate::Result;
7
8#[derive(Clone, Default)]
12pub struct Committer {}
13
14impl Committer {
15 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub async fn finalize(
27 &self,
28 _working_dir: &std::path::Path,
29 modified_files: &[std::path::PathBuf],
30 ) -> Result<CommitReport> {
31 let now = std::time::SystemTime::now()
33 .duration_since(std::time::UNIX_EPOCH)
34 .map(|d| d.as_secs())
35 .unwrap_or(0);
36
37 let transaction_id = format!("txn-{}", now);
38
39 Ok(CommitReport {
40 transaction_id: transaction_id.clone(),
41 files_committed: modified_files.to_vec(),
42 })
43 }
44
45 pub fn generate_summary(&self, steps: &[crate::planner::PlanStep]) -> String {
51 let mut summary = String::from("Applied ");
52
53 for (i, step) in steps.iter().enumerate() {
54 if i > 0 {
55 summary.push_str(", ");
56 }
57 summary.push_str(&step.description);
58 }
59
60 summary
61 }
62}
63
64#[derive(Clone, Debug)]
66pub struct CommitReport {
67 pub transaction_id: String,
69 pub files_committed: Vec<std::path::PathBuf>,
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use tempfile::TempDir;
77 use forge_core::Forge;
78
79 #[tokio::test]
80 async fn test_committer_creation() {
81 let _committer = Committer::new();
82
83 assert!(true);
85 }
86
87 #[tokio::test]
88 async fn test_generate_summary() {
89 let committer = Committer::new();
90
91 let steps = vec![
92 crate::planner::PlanStep {
93 description: "Step 1".to_string(),
94 operation: crate::planner::PlanOperation::Inspect {
95 symbol_id: forge_core::types::SymbolId(1),
96 symbol_name: "test".to_string(),
97 },
98 },
99 crate::planner::PlanStep {
100 description: "Step 2".to_string(),
101 operation: crate::planner::PlanOperation::Inspect {
102 symbol_id: forge_core::types::SymbolId(2),
103 symbol_name: "test2".to_string(),
104 },
105 },
106 ];
107
108 let summary = committer.generate_summary(&steps);
109
110 assert!(summary.contains("Step 1"));
111 assert!(summary.contains("Step 2"));
112 }
113
114 #[tokio::test]
115 async fn test_create_checkpoint() {
116 let temp_dir = TempDir::new().unwrap();
117 let _forge = Forge::open(temp_dir.path()).await.unwrap();
118 let committer = Committer::new();
119
120 let result = committer
121 .finalize(&std::path::PathBuf::new(), &[])
122 .await
123 .unwrap();
124
125 assert!(!result.transaction_id.is_empty());
126 assert!(result.files_committed.is_empty());
127 }
128}