1mod create_project;
2mod enums;
3
4use std::path::PathBuf;
5
6use anyhow::anyhow;
7use clap::Parser;
8pub use create_project::*;
9pub use enums::*;
10use path_clean::PathClean;
11
12use crate::{logo, plugin::create_instance};
13
14#[derive(Debug, Clone, clap::Parser)]
15#[clap(author, version, about, long_about = None)]
16pub enum Cli {
17 New {
19 name: String,
21 #[arg(short, long, default_value = "exe")]
23 template: TemplateType,
24 #[arg(short, long, default_value = ".")]
26 path: PathBuf,
27 },
28 Init {
30 #[arg(short, long, default_value = "exe")]
32 template: TemplateType,
33 #[arg(short, long, default_value = ".")]
35 path: PathBuf,
36 },
37 Build,
39 Run,
41 Clean,
43 Install,
45 Uninstall,
47 Pack,
49 Publish,
51 List,
53 Logo,
55}
56
57impl Cli {
58 pub fn new() -> Self {
63 let mut cli = Cli::parse();
64
65 let base_path = std::env::current_dir().unwrap();
67 macro_rules! to_abs_path {
69 ($($t: tt)*) => {
70 if let $($t)* { ref mut path, .. } = cli {
71 if path.is_relative() {
72 *path = base_path.join(&path).clean();
73 }
74 }
75 };
76 }
77 to_abs_path!(Self::New);
79 to_abs_path!(Self::Init);
80
81 cli
82 }
83
84 pub fn dispatch(self) -> anyhow::Result<()> {
86 match self {
87 Cli::Logo => logo(),
89 Cli::New {
91 name,
92 template,
93 path,
94 } => {
95 let plugin = create_instance(template);
96
97 let project_path = path.join(&name);
98 if project_path.exists() {
99 return Err(anyhow!(
100 "Directory or file {} already exists!",
101 project_path.clean().display()
102 ));
103 }
104
105 fs_err::create_dir_all(&project_path)?;
106 let result = plugin.create_project(&name, &project_path);
107 if let Err(e) = result {
109 fs_err::remove_dir_all(&project_path)?;
110 return Err(e);
111 }
112 }
113 Cli::Init { template, path } => {
115 let plugin = create_instance(template);
116
117 if !path.exists() {
118 return Err(anyhow!(
119 "Directory {} does not exist!",
120 path.clean().display()
121 ));
122 }
123 if !path.is_dir() {
124 return Err(anyhow!("{} is not a directory!", path.clean().display()));
125 }
126 if fs_err::read_dir(&path)?.next().is_some() {
127 return Err(anyhow!(
128 "Directory {} is not empty!",
129 path.clean().display()
130 ));
131 }
132
133 let name = path.file_name().unwrap().to_str().unwrap();
134 let result = plugin.create_project(name, &path);
135 if let Err(e) = result {
137 fs_err::remove_dir_all(&path)?;
138 fs_err::create_dir(path)?;
139 return Err(e);
140 }
141 }
142 _ => todo!(),
143 };
144 Ok(())
145 }
146}