use crate::auth_registry;
use crate::commands::write_files;
use crate::project_auth;
use crate::{default_registry, project_generator, GeneratorRegistry};
use doido_core::Result;
use std::path::Path;
const CARGO_TOML: &str = "Cargo.toml";
pub fn registry_for_project_at(base: &Path) -> GeneratorRegistry {
let mut reg = default_registry();
if project_auth::project_has_doido_auth(base.join(CARGO_TOML)) {
auth_registry::register_auth_generators(&mut reg);
}
reg
}
pub fn registry_for_project() -> GeneratorRegistry {
registry_for_project_at(Path::new("."))
}
pub fn project_has_doido_auth_at(base: &Path) -> bool {
project_auth::project_has_doido_auth(base.join(CARGO_TOML))
}
pub fn project_has_doido_auth() -> bool {
project_has_doido_auth_at(Path::new("."))
}
pub fn run(args: &[String]) {
let first = args.first().map(String::as_str);
if matches!(first, None | Some("-h" | "--help" | "help")) {
print_generator_list();
return;
}
let generator = args[0].as_str();
let rest: Vec<&str> = args[1..].iter().map(String::as_str).collect();
run_generate(generator, &rest);
}
fn print_generator_list() {
let registry = registry_for_project();
let auth_installed = project_has_doido_auth();
println!("Available generators:\n");
println!("Built-in:");
for name in registry.list() {
if auth_installed && auth_registry::auth_generator_names().contains(&name) {
continue;
}
println!(" {name}");
}
if auth_installed {
println!("\nAuth (doido-auth):");
for name in auth_registry::auth_generator_names() {
println!(" {name}");
}
}
let project = project_generator::list();
if !project.is_empty() {
println!("\nProject (lib/generators/):");
for name in project {
println!(" {name}");
}
}
println!("\nUsage: doido generate <name> [args...]");
}
pub fn run_generate(generator: &str, args: &[&str]) {
match resolve_and_run(generator, args) {
Ok(files) => {
if files.is_empty() {
doido_core::tracing::info!("no files generated");
return;
}
if let Err(e) = write_files(&files, Path::new(".")) {
doido_core::tracing::error!("error writing files: {e}");
std::process::exit(1);
}
}
Err(e) => {
doido_core::tracing::error!("{e}");
std::process::exit(1);
}
}
}
fn resolve_and_run(generator: &str, args: &[&str]) -> Result<Vec<crate::GeneratedFile>> {
if auth_registry::auth_generator_names().contains(&generator) && !project_has_doido_auth() {
return Err(doido_core::anyhow::anyhow!(
"auth generator '{generator}' requires doido-auth in Cargo.toml. \
Add the dependency (e.g. `cargo add doido-auth`) or scaffold with `doido new --auth`."
));
}
let registry = registry_for_project();
if registry.list().contains(&generator) {
registry.run(generator, args)
} else if let Some(dir) = project_generator::find(generator) {
doido_core::tracing::info!("using project generator: {}", dir.display());
project_generator::run(&dir, args)
} else {
let mut hint = format!(
"unknown generator '{generator}'. built-in: {}",
registry.list().join(", ")
);
if !project_has_doido_auth() {
hint.push_str(". auth generators require doido-auth in Cargo.toml");
}
Err(doido_core::anyhow::anyhow!(hint))
}
}