1pub mod scaffolding;
2pub mod database;
3pub mod monitoring;
4pub mod builder;
5pub mod utils;
6pub use scaffolding::*;
7pub use database::*;
8pub use monitoring::*;
9pub use builder::*;
10pub use utils::*;
11
12use std::env;
13use dotenvy::dotenv;
14use colored::*;
15use std::future::Future;
16use std::pin::Pin;
17
18pub type AsyncHook = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()>>>>;
19
20pub async fn run_cli<F, G>(migrate_fn: F, seed_fn: G)
21where
22 F: Fn(String) -> Pin<Box<dyn Future<Output = Result<(), String>>>>,
23 G: Fn() -> Pin<Box<dyn Future<Output = ()>>>
24{
25 let args: Vec<String> = env::args().collect();
26
27 if args.len() < 2 {
28 print_help();
29 return;
30 }
31
32 let command = &args[1];
33
34 if command != "new" {
36 let _ = dotenv();
37 ensure_session().await;
38 }
39
40 match command.as_str() {
41 "migrate" | "migrate:refresh" | "migrate:back" | "migrate:rollback" => {
42 match migrate_fn(command.clone()).await {
43 Ok(_) => println!("\n{} Operasi '{}' berhasil.", "â
".green(), command),
44 Err(e) => eprintln!("\n{} Gagal: {}", "â".red(), e),
45 }
46 }
47 "db:seed" => {
48 println!("{}", "đą Menjalankan seeder database...".cyan());
49 seed_fn().await;
50 println!("\n{} Database seeding berhasil.", "â
".green());
51 }
52 _ => {
53 }
56 }
57}
58
59pub fn print_help() {
60 println!("Gunakan 'rustbasic' untuk melihat opsi perintah.");
61}
62
63pub async fn handle<M: sea_orm_migration::MigratorTrait>(args: &[String]) -> bool {
65 if args.len() < 2 {
66 return false;
67 }
68
69 let command = args[1].as_str();
70
71 let is_migration_cmd = command.starts_with("migrate") || command == "db:seed";
73 let is_storage_cmd = command == "storage:link";
74
75 if !is_migration_cmd && !is_storage_cmd {
76 return false;
77 }
78
79 ensure_session().await;
80
81 println!("{} {}", "đ ī¸ RustBasic Local CLI - Command:".magenta().bold(), command.yellow());
82
83 if is_storage_cmd {
84 handle_storage_link();
85 return true;
86 }
87
88 let db = crate::database::connect().await;
90
91 match command {
92 "migrate" => {
93 println!("đ {}", "Menjalankan migrasi database...".cyan());
94 if let Err(e) = M::up(&db, None).await {
95 println!("â {} {}", "Gagal menjalankan migrasi:".red().bold(), e);
96 } else {
97 println!("â
{}", "Migrasi selesai!".green().bold());
98 }
99 }
100 "migrate:refresh" => {
101 println!("đ {}", "Mereset dan menjalankan ulang migrasi...".cyan());
102 if let Err(e) = M::fresh(&db).await {
103 println!("â {} {}", "Gagal refresh migrasi:".red().bold(), e);
104 } else {
105 println!("â
{}", "Database berhasil di-refresh!".green().bold());
106 }
107 }
108 "migrate:back" | "migrate:rollback" => {
109 println!("âŦ
ī¸ {}", "Rollback migrasi terakhir...".cyan());
110 if let Err(e) = M::down(&db, None).await {
111 println!("â {} {}", "Gagal rollback:".red().bold(), e);
112 } else {
113 println!("â
{}", "Rollback berhasil!".green().bold());
114 }
115 }
116 "db:seed" => {
117 println!("đą {}", "Fitur db:seed membutuhkan implementasi lokal.".yellow());
118 }
119 _ => return false,
120 }
121
122 true
123}
124
125fn handle_storage_link() {
127 let target = "public/storage";
128 let source = "storage/app/public";
129
130 if let Err(e) = std::fs::create_dir_all(source) {
132 println!("â {} {}", "Gagal membuat direktori storage:".red().bold(), e);
133 return;
134 }
135
136 let path = std::path::Path::new(target);
138 if path.exists() || path.is_symlink() {
139 println!("âšī¸ {}", "Link 'public/storage' sudah ada atau berupa file/folder lain.".yellow());
140 return;
141 }
142
143 println!("đ {}", "Membuat symbolic link...".cyan());
145
146 #[cfg(unix)]
147 {
148 use std::os::unix::fs::symlink;
149 if let Err(e) = symlink("../storage/app/public", target) {
151 println!("â {} {}", "Gagal membuat symlink:".red().bold(), e);
152 } else {
153 println!("â
{} [public/storage -> storage/app/public]", "Link storage berhasil dibuat!".green().bold());
154 }
155 }
156
157 #[cfg(windows)]
158 {
159 use std::os::windows::fs::symlink_dir;
160 if let Err(e) = symlink_dir("../storage/app/public", target) {
161 println!("â {} {}", "Gagal membuat symlink:".red().bold(), e);
162 } else {
163 println!("â
{} [public/storage -> storage/app/public]", "Link storage berhasil dibuat!".green().bold());
164 }
165 }
166}