rocket_cli/commands/
new.rs

1use crate::commands::NewArgs;
2use crate::templates::load_template_files;
3use colored::*;
4use handlebars::Handlebars;
5use std::collections::HashMap;
6use std::fs;
7use std::path::Path;
8
9pub fn handle(args: NewArgs) {
10    if args.list {
11        println!("\nAvailable Rocket templates:\n");
12        println!("  minimal     → Basic Rocket project with a single route [default]");
13        println!("  mongodb     → Rocket + MongoDB integration");
14        println!("  postgres    → Rocket + PostgreSQL");
15        println!("  mysql       → Rocket + MySQL (WIP)");
16        println!("  mssql       → Rocket + SQL Server (WIP)");
17        println!("  sqlite      → Rocket + SQLite (WIP)");
18        println!("\nExample: rocket new my-app --template postgres --git");
19        return;
20    }
21
22    if let Some(name) = args.name {
23        execute(name, args.git, args.template);
24    } else {
25        eprintln!(
26            "{}",
27            "Project name is required. Use `rocket new <name>` or `rocket new --list`.".yellow()
28        );
29        std::process::exit(1);
30    }
31}
32
33pub fn execute(name: String, git: bool, template: String) {
34    eprintln!(
35        "Creating Rocket project -> {} using template '{}'",
36        name, template
37    );
38
39    let project_dir = Path::new(&name);
40
41    if project_dir.exists() {
42        eprintln!(
43            "{}",
44            format!("Project directory '{}' already exists.", name).yellow()
45        );
46        std::process::exit(1);
47    }
48
49    let template_files = load_template_files(&template).unwrap_or_else(|| {
50        eprintln!("{}", format!("Rocket Template '{}' not found...", template).red());
51        std::process::exit(1);
52    });
53
54    let handlebars = Handlebars::new();
55    let mut ctx = HashMap::new();
56    ctx.insert("project_name", name.as_str());
57
58    for (relative_path, content) in template_files {
59        let rendered = handlebars.render_template(content, &ctx).unwrap();
60        let full_path = project_dir.join(relative_path);
61
62        if let Some(parent) = full_path.parent() {
63            fs::create_dir_all(parent).expect("Failed to create directories...");
64        }
65
66        fs::write(full_path, rendered).expect("Failed to write file...");
67    }
68
69    if git {
70        std::process::Command::new("git")
71            .arg("init")
72            .arg(&name)
73            .status()
74            .expect("Failed to initialize git...");
75        println!("Git initialized.");
76    }
77
78    println!(
79        "{}",
80        format!(
81            "Project '{}' created successfully using '{}' template!",
82            name, template
83        )
84        .green()
85    );
86}