use crate::utils::trad::{t, tf};
use anyhow::Result;
use std::{fs, path::Path, process::Command};
pub fn runique_start(main_path: &str, admin_path: &str) -> Result<()> {
let main_file = Path::new(main_path);
if !main_file.exists() {
anyhow::bail!("{}", tf("cli.file_not_found", &[&main_path]));
}
let main_source = fs::read_to_string(main_file)?;
if !has_admin(&main_source) {
println!(" {}", t("cli.add_admin_hint"));
return Ok(());
}
println!("{}", t("cli.admin_detected"));
generate_admin(admin_path)?;
format_workspace();
let status = Command::new("cargo")
.arg("run")
.arg("--release")
.status()
.unwrap_or_else(|_| panic!("{}", t("cli.cargo_run_expect")));
if !status.success() {
anyhow::bail!("{}", t("cli.cargo_run_failed"));
}
Ok(())
}
fn has_admin(source: &str) -> bool {
source.lines().any(|line| {
let trimmed = line.trim();
!trimmed.starts_with("//") && trimmed.contains(".with_admin(")
})
}
fn format_workspace() {
match Command::new("cargo").arg("fmt").arg("--all").status() {
Ok(status) if status.success() => {}
Ok(status) => eprintln!(" {}", tf("cli.fmt_failed", &[&status.to_string()])),
Err(e) => eprintln!(" {}", tf("cli.fmt_failed", &[&e.to_string()])),
}
}
fn generate_admin(admin_path: &str) -> Result<()> {
use crate::admin::daemon::generate_once;
let admin_file = Path::new(admin_path);
if !admin_file.exists() {
anyhow::bail!("{}", tf("cli.admin_not_found", &[&admin_path]));
}
generate_once(admin_file)
.map_err(|e| anyhow::anyhow!("{}", tf("cli.daemon_error", std::slice::from_ref(&e))))?;
Ok(())
}
#[cfg(test)]
mod has_admin_tests {
use super::has_admin;
#[test]
fn only_an_active_with_admin_call_counts() {
assert!(has_admin(" .with_admin(|a| a.auth(x))\n"));
assert!(!has_admin(" // .with_admin(|a| a)\n"));
assert!(!has_admin(" .with_database(db)\n"));
assert!(has_admin("// setup\n.with_admin(|a| a)\n"));
}
}