use std::path::Path;
use super::templates::{self, Template};
pub fn run(name: &str, template: Option<&str>) -> anyhow::Result<()> {
let root = Path::new(name);
if root.exists() {
anyhow::bail!("Directory '{name}' already exists.");
}
let config = match template {
Some(t) => {
let tmpl = Template::from_str(t)?;
templates::WizardConfig {
template: tmpl,
db: templates::DbDriver::Postgres,
auth: templates::AuthDriver::Jwt,
cache: templates::CacheDriver::Memory,
queue: templates::QueueDriver::None,
include_examples: true,
}
}
None => templates::prompt_wizard()?,
};
let tmpl = config.template;
println!(
"Creating rok application: {name} (template: {})",
tmpl.label()
);
println!();
if !tmpl.handles_directory_creation() {
std::fs::create_dir_all(root)?;
}
tmpl.generate(name, root, &config)?;
let _ = git_init(root);
println!();
println!("Application '{name}' created!");
println!();
println!("Next steps:");
println!(" cd {name}");
println!(" rok secrets:generate # generate JWT_SECRET and write .env");
println!(" # Or: cp .env.example .env && edit DATABASE_URL");
println!(" rok serve");
Ok(())
}
fn git_init(root: &Path) -> anyhow::Result<()> {
use std::process::Command;
let already_in_repo = Command::new("git")
.args(["rev-parse", "--is-inside-work-tree"])
.current_dir(root)
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if already_in_repo {
return Ok(());
}
Command::new("git").arg("init").current_dir(root).output()?;
Command::new("git")
.args(["add", "."])
.current_dir(root)
.output()?;
Command::new("git")
.args(["commit", "-m", "Initial commit (rok new)"])
.env("GIT_AUTHOR_NAME", "rok")
.env("GIT_AUTHOR_EMAIL", "rok@localhost")
.env("GIT_COMMITTER_NAME", "rok")
.env("GIT_COMMITTER_EMAIL", "rok@localhost")
.current_dir(root)
.output()?;
Ok(())
}