thoughts_tool/utils/
git.rs1use anyhow::Result;
2use std::fs;
3use std::path::Path;
4use tracing::info;
5
6pub fn ensure_gitignore_entry(
8 repo_path: &Path,
9 entry: &str,
10 comment: Option<&str>,
11) -> Result<bool> {
12 let gitignore_path = repo_path.join(".gitignore");
13
14 if gitignore_path.exists() {
16 let content = fs::read_to_string(&gitignore_path)?;
17
18 let entry_no_slash = entry.trim_start_matches('/');
20 let has_entry = content.lines().any(|line| {
21 let trimmed = line.trim();
22 trimmed == entry || trimmed == entry_no_slash || trimmed == format!("{entry_no_slash}/")
23 });
24
25 if !has_entry {
26 let mut new_content = content;
28 if !new_content.ends_with('\n') {
29 new_content.push('\n');
30 }
31 if let Some(comment_text) = comment {
32 new_content.push_str(&format!("\n# {comment_text}\n"));
33 }
34 new_content.push_str(entry);
35 new_content.push('\n');
36
37 fs::write(&gitignore_path, new_content)?;
38 info!("Added {} to .gitignore", entry);
39 Ok(true)
40 } else {
41 Ok(false)
42 }
43 } else {
44 let mut content = String::new();
46 if let Some(comment_text) = comment {
47 content.push_str(&format!("# {comment_text}\n"));
48 }
49 content.push_str(&format!("{entry}\n"));
50
51 fs::write(&gitignore_path, content)?;
52 info!("Created .gitignore with {} entry", entry);
53 Ok(true)
54 }
55}