Menu
Public repository / master
AkurAI-Framework / crates/cli/src/cmd_new.rs
Latest change efd5eb833824dca5c86104004c11bc6d39ff1a72 - feat(template): pure-std SSR template engine + component showcase by Ólafur Búi Ólafsson
//! `akurai new <path>` — bootstrap a fresh project from embedded templates.
//!
//! Templates are baked into the binary with `include_str!`, so a single
//! executable can scaffold a complete project anywhere with no network or
//! extra files.
use std::fs;
use std::io;
use std::path::Path;
const INDEX_HTML: &str = include_str!("../assets/index.html");
const HEADER_HTML: &str = include_str!("../assets/header.html");
const FOOTER_HTML: &str = include_str!("../assets/footer.html");
const STYLES_CSS: &str = include_str!("../assets/styles.css");
const APP_JS: &str = include_str!("../assets/app.js");
const PAGE_JSON: &str = include_str!("../assets/page.json");
const AKURAI_TOML: &str = include_str!("../assets/akurai.toml");
const COLLECTIONS_TOML: &str = include_str!("../assets/collections.toml");
/// Scaffold a new project at `dir`. Fails if the directory already exists and
/// is non-empty, to avoid clobbering work.
pub fn run(dir: &Path) -> io::Result<()> {
let app_name = dir
.file_name()
.and_then(|s| s.to_str())
.unwrap_or("app")
.to_string();
if dir.exists() && dir.read_dir()?.next().is_some() {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("{} already exists and is not empty", dir.display()),
));
}
let render = |s: &str| s.replace("__APP_NAME__", &app_name);
fs::create_dir_all(dir.join("frontend"))?;
fs::create_dir_all(dir.join("backend"))?;
fs::create_dir_all(dir.join("data"))?;
fs::write(dir.join("frontend/index.html"), render(INDEX_HTML))?;
fs::write(dir.join("frontend/header.html"), render(HEADER_HTML))?;
fs::write(dir.join("frontend/footer.html"), render(FOOTER_HTML))?;
fs::write(dir.join("frontend/styles.css"), STYLES_CSS)?;
fs::write(dir.join("frontend/app.js"), APP_JS)?;
fs::write(dir.join("backend/page.json"), render(PAGE_JSON))?;
fs::write(dir.join("backend/collections.toml"), COLLECTIONS_TOML)?;
fs::write(dir.join("akurai.toml"), render(AKURAI_TOML))?;
fs::write(dir.join("data/.gitkeep"), "")?;
fs::write(dir.join(".gitignore"), "/data/\n*.db\n*.db-*\n")?;
println!("Created project '{app_name}' at {}", dir.display());
println!();
println!(" cd {}", dir.display());
println!(" akurai serve");
Ok(())
}