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 plugin.create_project(&name, &project_path)?;
107 }
108 Cli::Init { template, path } => {
110 let plugin = create_instance(template);
111
112 if !path.exists() {
113 return Err(anyhow!(
114 "Directory {} does not exist!",
115 path.clean().display()
116 ));
117 }
118 if !path.is_dir() {
119 return Err(anyhow!("{} is not a directory!", path.clean().display()));
120 }
121 if fs_err::read_dir(&path)?.next().is_some() {
122 return Err(anyhow!(
123 "Directory {} is not empty!",
124 path.clean().display()
125 ));
126 }
127
128 let name = path.file_name().unwrap().to_str().unwrap();
129 plugin.create_project(name, &path)?;
130 }
131 _ => todo!(),
132 };
133 Ok(())
134 }
135}