use crate::exec::{Cmd, ScanPolicy};
use crate::logger::*;
use crate::paths::*;
use std::io::{self, Write};
pub fn run_add(targets: &[String], tracked_file: &str, home: &str) -> io::Result<()> {
log_section("Updating tracked paths...");
let parent_dir = std::path::Path::new(tracked_file).parent().unwrap();
std::fs::create_dir_all(parent_dir)?;
std::fs::OpenOptions::new()
.create(true)
.write(true)
.open(tracked_file)?;
let home_path = canonical_path(home);
let mut added_any = false;
let mut existing_paths = Vec::new();
if let Ok(file) = std::fs::File::open(tracked_file) {
use std::io::BufRead;
for line in std::io::BufReader::new(file).lines() {
if let Ok(line) = line {
existing_paths.push(line.trim().to_string());
}
}
}
let mut file = std::fs::OpenOptions::new()
.append(true)
.open(tracked_file)?;
for target in targets {
let abs_path = canonical_path(target);
if abs_path.starts_with(&home_path) {
let rel_path = if abs_path == home_path {
"".to_string()
} else {
let offset = if home_path.ends_with('/') {
home_path.len()
} else {
home_path.len() + 1
};
abs_path[offset..].to_string()
};
if existing_paths.contains(&rel_path) {
log_warn(&(rel_path.clone() + " is already present."));
} else {
writeln!(file, "{}", rel_path)?;
log_success(&("Added ".to_owned() + &rel_path));
added_any = true;
}
} else {
log_warn(&("Skipping path outside home: ".to_owned() + target));
}
}
if targets.is_empty() || added_any {
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "nvim".to_string());
log_step(&("Opening in ".to_owned() + &editor));
std::process::Command::new(editor)
.arg(tracked_file)
.status()?;
} else {
log_done("No new tracked paths were added.");
}
Ok(())
}
pub fn run_edit_lists(tracked_file: &str, tracked_enc_file: &str) -> io::Result<()> {
log_section("Opening tracking lists...");
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "nvim".to_string());
log_step(&("Launching ".to_owned() + &editor));
std::process::Command::new(editor)
.arg("-p")
.arg(tracked_file)
.arg(tracked_enc_file)
.status()?;
Ok(())
}
pub fn run_manual_add(targets: &[String], policy: ScanPolicy) -> io::Result<()> {
log_section("Manually adding paths...");
log_step(&format!("Adding {:?} recursively...", targets));
let chezmoi = Cmd::new();
let mut argv: Vec<&str> = vec!["--recursive"];
argv.extend(targets.iter().map(|t| t.as_str()));
let outcome = chezmoi.run("add", &argv, chezmoi.secrets_arg("add", policy))?;
outcome.report();
outcome.report_summary();
if outcome.success {
log_done("Manually added targets recursively.");
}
Ok(())
}
pub fn run_manual_add_secret(targets: &[String], policy: ScanPolicy) -> io::Result<()> {
log_section("Manually adding encrypted paths...");
log_step(&format!(
"Adding and encrypting {:?} recursively...",
targets
));
let chezmoi = Cmd::new();
let mut argv: Vec<&str> = vec!["--encrypt", "--recursive"];
argv.extend(targets.iter().map(|t| t.as_str()));
let outcome = chezmoi.run("add", &argv, chezmoi.secrets_arg("add", policy))?;
outcome.report();
if outcome.success {
log_done("Manually added and encrypted targets.");
}
Ok(())
}