#[macro_use]
extern crate rust_i18n;
i18n!("../locales", fallback = ["en", "zh-CN"]);
use clap::Parser;
use client_core::container::{detect_compose_command_type, set_compose_command_type};
use client_core::{DuckError, environment::Environment};
use nuwax_cli::{
AutoUpgradeDeployCommand, Cli, CliApp, Commands, UpgradeSubcommand,
check_and_install_nuwax_cli_update_early, run_diff_sql, run_init, setup_logging,
};
use rust_i18n::set_locale;
use tracing::{error, info, warn};
fn detect_and_set_language() {
set_locale("en");
}
#[tokio::main]
async fn main() {
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls ring crypto provider");
detect_and_set_language();
let cli = Cli::parse();
let environment = Environment::from_env();
if environment.is_testing() {
warn!("⚠️ RUNNING IN TESTING MODE");
warn!(" Environment: {env}", env = environment.display_name());
warn!(
" API Endpoint: {url}",
url = client_core::constants::api::get_base_url()
);
warn!(" Configuration: config-test.toml (if exists)");
warn!(" Use Ctrl+C to cancel if this is not intended");
warn!(" Waiting 2 seconds...");
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
warn!("🚀 Starting in Testing Environment...");
}
setup_logging(cli.verbose);
if let Commands::Init { force } = cli.command {
if let Err(e) = run_init(force).await {
error!("❌ Initialization failed: {error}", error = e.to_string());
std::process::exit(1);
}
return;
}
if let Commands::Status = cli.command {
nuwax_cli::show_client_version();
match CliApp::new_with_auto_config().await {
Ok(app) => {
if let Err(e) = nuwax_cli::run_status_details(&app).await {
error!(
"❌ Failed to get detailed status: {error}",
error = e.to_string()
);
}
}
Err(e) => {
error!(
"⚠️ Unable to get full status info: {error}",
error = e.to_string()
);
info!("");
info!("💡 Possible reasons:");
info!(" - Current directory is not Nuwax Cli ent working directory");
info!(" - Configuration or database file not in current directory");
info!(" - Database file locked by another process");
info!("");
info!("🔧 Solutions:");
info!(" 1. Switch to Nuwax Cli ent initialized directory (contains config.toml)");
info!(" 2. Or run 'nuwax-cli init' in a new directory to reinitialize");
info!(" 3. Ensure no other nuwax-cli process is running");
}
}
return;
}
if let Commands::DiffSql {
old_sql,
new_sql,
old_version,
new_version,
output,
} = cli.command
{
if let Err(e) = run_diff_sql(old_sql, new_sql, old_version, new_version, output).await {
error!(
"❌ SQL diff comparison failed: {error}",
error = e.to_string()
);
std::process::exit(1);
}
return;
}
if let Commands::AutoUpgradeDeploy(AutoUpgradeDeployCommand::OfflineDeploy { .. }) =
&cli.command
{
info!("🔍 Offline-deploy command detected, skipping CLI version check (offline mode)...");
} else if let Commands::AutoUpgradeDeploy(_) = &cli.command {
info!("🔍 AutoUpgradeDeploy command detected, prioritizing CLI version check...");
if let Err(e) = check_and_install_nuwax_cli_update_early().await {
error!(
"❌ CLI version check failed: {error}",
error = e.to_string()
);
std::process::exit(1);
}
info!("✅ CLI version check complete, continuing with AutoUpgradeDeploy command");
let compose_type = detect_compose_command_type().await;
set_compose_command_type(compose_type);
}
if let Commands::Upgrade {
subcommand: Some(UpgradeSubcommand::Download { .. }),
..
} = &cli.command
{
match nuwax_cli::run_download(Some(&cli.config)).await {
Ok(_) => return,
Err(e) => {
error!("❌ Download failed: {error}", error = e.to_string());
std::process::exit(1);
}
}
}
let mut app = match CliApp::new_with_config_path(&cli.config).await {
Ok(app) => app,
Err(e) => {
let mut source = e.source();
let mut is_config_not_found = false;
while let Some(err) = source {
if err.downcast_ref::<DuckError>().is_some()
&& let Some(DuckError::ConfigNotFound) = err.downcast_ref::<DuckError>()
{
is_config_not_found = true;
break;
}
source = err.source();
}
if is_config_not_found {
error!(
"❌ Configuration file '{file}' not found.",
file = cli.config.display()
);
error!("👉 Please run 'nuwax-cli init' first to create configuration file.");
} else {
error!(
"❌ Application initialization failed: {error}",
error = e.to_string()
);
}
std::process::exit(1);
}
};
if let Err(e) = app.run_command(cli.command).await {
error!("❌ Operation failed: {error}", error = e.to_string());
std::process::exit(1);
}
}