pub mod scaffolding;
pub mod database;
pub mod monitoring;
pub mod builder;
pub mod utils;
pub mod auth;
pub use scaffolding::*;
pub use database::*;
pub use monitoring::*;
pub use builder::*;
pub use utils::*;
pub use auth::*;
use std::env;
use dotenvy::dotenv;
use colored::*;
use std::future::Future;
use std::pin::Pin;
pub type AsyncHook = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()>>>>;
pub async fn run_cli<F, G>(migrate_fn: F, seed_fn: G)
where
F: Fn(String) -> Pin<Box<dyn Future<Output = Result<(), String>>>>,
G: Fn() -> Pin<Box<dyn Future<Output = ()>>>
{
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
print_help();
return;
}
let command = &args[1];
if command != "new" {
let _ = dotenv();
}
match command.as_str() {
"migrate" | "migrate:refresh" | "migrate:back" | "migrate:rollback" => {
match migrate_fn(command.clone()).await {
Ok(_) => println!("\n{} Operasi '{}' berhasil.", "â
".green(), command),
Err(e) => eprintln!("\n{} Gagal: {}", "â".red(), e),
}
}
"db:seed" => {
println!("{}", "đą Menjalankan seeder database...".cyan());
seed_fn().await;
println!("\n{} Database seeding berhasil.", "â
".green());
}
_ => {
}
}
}
pub fn print_help() {
println!("\n{}", "đ ī¸ RustBasic CLI".magenta().bold());
println!("{}", "=================".magenta());
println!("{}", "Penggunaan:".bold());
println!(" {} {} <Nama> {}", "rustbasic".blue(), "new".green(), "Membuat project RustBasic baru".dimmed());
println!(" {} {} <Nama> {}", "rustbasic".blue(), "make:controller".green(), "Membuat controller baru".dimmed());
println!(" {} {} <Nama> [-m] {}", "rustbasic".blue(), "make:model".green(), "Membuat model & migration".dimmed());
println!(" {} {} <Nama> {}", "rustbasic".blue(), "make:migration".green(), "Membuat file migrasi (Create)".dimmed());
println!(" {} {} <Kolom> <Tabel> {}", "rustbasic".blue(), "make:migration:add".green(), "Membuat file migrasi (Add Column)".dimmed());
println!(" {} {} <Nama> {}", "rustbasic".blue(), "make:middleware".green(), "Membuat middleware baru".dimmed());
println!(" {} {} <Nama> {}", "rustbasic".blue(), "make:seeder".green(), "Membuat seeder baru".dimmed());
println!(" {} {} {}", "rustbasic".blue(), "migrate".green(), "Menjalankan migrasi database".dimmed());
println!(" {} {} {}", "rustbasic".blue(), "storage:link".green(), "Menghubungkan public/storage ke storage/app/public".dimmed());
println!(" {} {} {}", "rustbasic".blue(), "serve".green(), "Menjalankan server (Auto-Reload)".dimmed());
println!(" {} {} {}", "rustbasic".blue(), "version".green(), "Menampilkan versi CLI".dimmed());
println!("\nđĄ Gunakan 'rustbasic version' untuk informasi lebih lanjut.");
}
pub async fn handle<M: sea_orm_migration::MigratorTrait>(cfg: &rustbasic_core::Config, args: &[String]) -> bool {
if args.len() < 2 {
return false;
}
let command = args[1].as_str();
let is_migration_cmd = command.starts_with("migrate") || command == "db:seed";
let is_storage_cmd = command == "storage:link";
if !is_migration_cmd && !is_storage_cmd {
return false;
}
println!("{} {}", "đ ī¸ RustBasic Local CLI - Command:".magenta().bold(), command.yellow());
if is_storage_cmd {
handle_storage_link();
return true;
}
let db = rustbasic_core::database::connect(cfg).await;
match command {
"migrate" => {
println!("đ {}", "Menjalankan migrasi database...".cyan());
if let Err(e) = M::up(&db, None).await {
println!("â {} {}", "Gagal menjalankan migrasi:".red().bold(), e);
} else {
println!("â
{}", "Migrasi selesai!".green().bold());
}
}
"migrate:refresh" => {
println!("đ {}", "Mereset dan menjalankan ulang migrasi...".cyan());
if let Err(e) = M::fresh(&db).await {
println!("â {} {}", "Gagal refresh migrasi:".red().bold(), e);
} else {
println!("â
{}", "Database berhasil di-refresh!".green().bold());
}
}
"migrate:back" | "migrate:rollback" => {
println!("âŦ
ī¸ {}", "Rollback migrasi terakhir...".cyan());
if let Err(e) = M::down(&db, None).await {
println!("â {} {}", "Gagal rollback:".red().bold(), e);
} else {
println!("â
{}", "Rollback berhasil!".green().bold());
}
}
"db:seed" => {
println!("đą {}", "Fitur db:seed membutuhkan implementasi lokal.".yellow());
}
_ => return false,
}
true
}
fn handle_storage_link() {
let target = "public/storage";
let source = "storage/app/public";
if let Err(e) = std::fs::create_dir_all(source) {
println!("â {} {}", "Gagal membuat direktori storage:".red().bold(), e);
return;
}
let path = std::path::Path::new(target);
if path.exists() || path.is_symlink() {
println!("âšī¸ {}", "Link 'public/storage' sudah ada atau berupa file/folder lain.".yellow());
return;
}
println!("đ {}", "Membuat symbolic link...".cyan());
#[cfg(unix)]
{
use std::os::unix::fs::symlink;
if let Err(e) = symlink("../storage/app/public", target) {
println!("â {} {}", "Gagal membuat symlink:".red().bold(), e);
} else {
println!("â
{} [public/storage -> storage/app/public]", "Link storage berhasil dibuat!".green().bold());
}
}
#[cfg(windows)]
{
use std::os::windows::fs::symlink_dir;
if let Err(e) = symlink_dir("../storage/app/public", target) {
println!("â {} {}", "Gagal membuat symlink:".red().bold(), e);
} else {
println!("â
{} [public/storage -> storage/app/public]", "Link storage berhasil dibuat!".green().bold());
}
}
}