1use anyhow::{Context, Result};
4use clap::Args;
5use console::style;
6use dialoguer::{theme::ColorfulTheme, Select};
7use log::debug;
8use std::fs;
9use std::path::PathBuf;
10
11use crate::templates::project_templates::{TemplateManager, TemplateType};
12
13#[derive(Args)]
14pub struct NewArgs {
15 #[arg(required = true)]
17 name: String,
18
19 #[arg(short, long)]
21 template: Option<String>,
22
23 #[arg(short, long)]
25 output_dir: Option<PathBuf>,
26}
27
28pub fn execute(args: NewArgs) -> Result<()> {
29 println!(
30 "{} a new Orbit project: {}",
31 style("Creating").bold().green(),
32 style(&args.name).bold()
33 );
34
35 let template_manager =
36 TemplateManager::new().context("Failed to initialize template manager")?;
37
38 let template_type = if let Some(template) = args.template {
40 TemplateType::from_str(&template)
41 .with_context(|| format!("Invalid template type: {template}"))?
42 } else {
43 let templates = template_manager.list_templates();
45 let template_names: Vec<String> = templates.iter().map(|t| t.to_string()).collect();
46 let selection = Select::with_theme(&ColorfulTheme::default())
47 .with_prompt("Select a project template")
48 .default(0)
49 .items(&template_names)
50 .interact()
51 .context("Failed to get user selection")?;
52
53 templates
54 .get(selection)
55 .ok_or_else(|| anyhow::anyhow!("Invalid template selection"))?
56 .clone()
57 };
58
59 let output_dir = match args.output_dir {
61 Some(dir) => dir,
62 None => {
63 let mut dir = std::env::current_dir()?;
65 dir.push(&args.name);
66 dir
67 }
68 };
69
70 if !output_dir.exists() {
72 debug!("Creating output directory: {output_dir:?}");
73 fs::create_dir_all(&output_dir)
74 .with_context(|| format!("Failed to create directory: {output_dir:?}"))?;
75 }
76
77 template_manager
79 .generate_project(&args.name, template_type, &output_dir)
80 .with_context(|| format!("Failed to generate project in {output_dir:?}"))?;
81
82 println!(
83 "\n{} project created at {output_dir:?}",
84 style("Successfully").bold().green()
85 );
86
87 println!("\n{}", style("Next steps:").bold());
89 println!(" cd {}", args.name);
90 println!(" orbiton dev");
91
92 Ok(())
93}