AkurAI Build
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(())
}