use crate::discovery::{discover_services, DiscoveredService};
use crate::infer::{infer_language, infer_platform};
use crate::manifest::{DiscoveryConfig, Manifest, DEFAULT_DISCOVERY_PATHS};
use anyhow::{bail, Result};
use std::path::{Path, PathBuf};
pub fn render_yaml(services: &[DiscoveredService], root: &Path) -> String {
let mut out = String::new();
out.push_str("# Generated by `svccat init`\n");
out.push_str("# Fill in the ~placeholder~ fields and commit this file.\n");
out.push_str("# Run `svccat check` to verify there is no drift.\n\n");
out.push_str("version: \"1\"\n\n");
out.push_str("discovery:\n");
out.push_str(" paths:\n");
for p in DEFAULT_DISCOVERY_PATHS {
out.push_str(&format!(" - {}\n", p));
}
out.push('\n');
out.push_str("services:\n");
if services.is_empty() {
out.push_str(" [] # no services detected — add entries manually\n");
} else {
for svc in services {
let lang = infer_language(root, &svc.path).unwrap_or_else(|| "~".to_string());
out.push_str(&format!(" - name: {}\n", svc.name));
out.push_str(&format!(" path: {}\n", svc.path));
out.push_str(&format!(" language: {}\n", lang));
match infer_platform(root, &svc.path) {
Some(platform) => out.push_str(&format!(" platform: {}\n", platform)),
None => out.push_str(
" platform: ~ # e.g. gcp-cloud-run, fly.io, vercel, aws-lambda\n",
),
}
out.push_str(" role: ~ # e.g. api, worker, frontend, database\n");
out.push_str(" url: ~ # e.g. https://my-service.example.com\n");
}
}
out
}
pub fn run(root: &Path, output_path: PathBuf, force: bool) -> Result<()> {
if output_path.exists() && !force {
bail!(
"{} already exists. Use --force to overwrite.",
output_path.display()
);
}
let bootstrap = Manifest {
version: "1".to_string(),
discovery: DiscoveryConfig {
paths: vec![],
markers: crate::manifest::default_markers_pub(),
ignore: vec![],
},
policy: Default::default(),
services: vec![],
};
let discovered = discover_services(root, &bootstrap);
let yaml = render_yaml(&discovered, root);
std::fs::write(&output_path, &yaml)?;
let verb = if output_path.exists() {
"Wrote"
} else {
"Created"
};
println!(
"{} {} ({} service{} detected)",
verb,
output_path.display(),
discovered.len(),
if discovered.len() == 1 { "" } else { "s" }
);
println!("Edit the file, then run `svccat check` to verify.");
Ok(())
}