Files
agent-manager/src/commands/init_cmd.rs
T

96 lines
3.2 KiB
Rust

//! init: generate a local agent-manager.yaml for the current directory,
//! based on the detected technology stack or an explicit template
//! (issue #52: 'am init --template web|python|rust|cli').
use super::*;
use crate::context;
use anyhow::{anyhow, Context, Result};
use std::path::{Path, PathBuf};
/// Generate a local config file in dir; refuses to overwrite unless force.
/// `template` renders a pre-filled config for a stack ('am init --template');
/// None falls back on the automatic stack detection. Returns the written path.
pub fn generate(dir: &Path, force: bool, template: Option<&str>) -> Result<PathBuf> {
let target = dir.join(crate::config::LOCAL_CONFIG_NAME);
if target.exists() && !force {
return Err(anyhow!(
"{} already exists — use --force to overwrite it",
target.display()
));
}
let project = dir
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_else(|| "project".to_string());
let dir_str = dir.to_string_lossy().to_string();
let content = if let Some(t) = template {
crate::templates::render(t, &project, &dir_str)?
} else {
let ctx = context::detect(dir);
let agents = context::recommended_agents(&ctx.stack);
let members = agents
.iter()
.map(|a| a.to_string())
.collect::<Vec<_>>()
.join(", ");
let stack = if ctx.stack.is_empty() {
crate::i18n::tr("aucune détectée").to_string()
} else {
ctx.stack.join(", ")
};
format!(
"# Généré par 'am init' le {date}
# Pile détectée : {stack}
version: \"1.0\"
groups:
dev: [{members}]
agents: []
",
date = crate::installers::now_rfc3339(),
)
};
std::fs::write(&target, content)
.with_context(|| format!("cannot write {}", target.display()))?;
Ok(target)
}
pub fn run(app: &App, force: bool, template: Option<&str>) -> Result<i32> {
// 'am init --template list' prints the available templates.
if template == Some("list") {
println!("available templates:");
for (name, desc) in crate::templates::TEMPLATES {
println!(" {name:<8} {desc}");
}
return Ok(0);
}
if app.dry_run() {
app.log.dry(format!(
"would generate {} in the current directory",
crate::config::LOCAL_CONFIG_NAME
));
return Ok(0);
}
let cwd = std::env::current_dir().context("cannot determine the current directory")?;
let ctx = context::detect(&cwd);
let path = generate(&cwd, force, template)?;
match template {
Some(t) => app.log.success(&format!(
"wrote {} (template: {t})",
path.display()
)),
None => app.log.success(&format!(
"wrote {} (stack: {})",
path.display(),
if ctx.stack.is_empty() {
crate::i18n::tr("aucune détectée").to_string()
} else {
ctx.stack.join(", ")
}
)),
}
app.log.info(&format!(
"group 'dev' prêt : am start group:dev — ajustez ensuite la config générée"
));
Ok(0)
}