use std::path::Path;
use std::process::ExitCode;
use clap::Parser;
use zinit::{
ZinitHandle,
client::cli::{Cli, Commands, XinetCommands, commands},
};
#[cfg(feature = "tui")]
use zinit::client::tui;
fn main() -> ExitCode {
#[cfg(feature = "rhai")]
{
let args: Vec<String> = std::env::args().collect();
if args.len() >= 2 {
let first_arg = &args[1];
if !first_arg.starts_with('-') {
let path = Path::new(first_arg);
let is_rhai_script = first_arg.ends_with(".rhai") && path.is_file();
let is_rhai_dir = path.is_dir()
&& std::fs::read_dir(path)
.map(|entries| {
entries.filter_map(|e| e.ok()).any(|e| {
e.path()
.extension()
.map(|ext| ext == "rhai")
.unwrap_or(false)
})
})
.unwrap_or(false);
if is_rhai_script || is_rhai_dir {
return match commands::cmd_rhai(&path.to_path_buf()) {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("Error: {}", e);
ExitCode::FAILURE
}
};
}
}
}
}
let cli = Cli::parse();
#[cfg(feature = "tui")]
if let Commands::Tui = &cli.command {
let socket_path = cli.socket.clone().unwrap_or_else(|| {
let socket_str = std::env::var("ZINIT_SOCKET")
.unwrap_or_else(|_| format!("{}/.zinit/socket", std::env::var("HOME").unwrap()));
std::path::PathBuf::from(socket_str)
});
return match tui::run(&socket_path) {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("Error: {}", e);
ExitCode::FAILURE
}
};
}
let client = match ZinitHandle::new() {
Ok(c) => c,
Err(e) => {
eprintln!("Error: Failed to connect to zinit daemon: {}", e);
eprintln!("Is zinit-server running?");
return ExitCode::FAILURE;
}
};
let result = match cli.command {
Commands::List => commands::cmd_list(&client),
Commands::Status { name } => commands::cmd_status(&client, &name),
Commands::Start { name, tree } => commands::cmd_start(&client, &name, tree),
Commands::Stop { name } => commands::cmd_stop(&client, &name),
Commands::Restart { name } => commands::cmd_restart(&client, &name),
Commands::Kill { name, signal } => commands::cmd_kill(&client, &name, signal.as_deref()),
Commands::Why { name } => commands::cmd_why(&client, &name),
Commands::Tree => commands::cmd_tree(&client),
Commands::Remove { name } => commands::cmd_remove(&client, &name),
Commands::Reload => Err("reload command not supported in this version".to_string()),
Commands::Logs {
name,
lines,
follow,
} => commands::cmd_logs(&client, &name, lines, follow),
Commands::Ping => commands::cmd_ping(&client),
Commands::Shutdown => commands::cmd_shutdown(&client),
Commands::AddService {
file,
name,
exec,
dir,
oneshot,
envs,
after,
requires,
wants,
conflicts,
restart,
restart_delay,
restart_delay_max,
max_restarts,
persist,
ephemeral: _,
} => commands::cmd_add_service(
&client,
file,
name,
exec,
dir,
oneshot,
envs,
after,
requires,
wants,
conflicts,
restart,
restart_delay,
restart_delay_max,
max_restarts,
persist,
),
Commands::DebugState => commands::cmd_debug_state(&client),
Commands::DebugProcs { name } => commands::cmd_debug_procs(&client, &name),
Commands::Xinet { command } => match command {
XinetCommands::Register {
name,
listen,
backend,
service,
connect_timeout,
idle_timeout,
single,
} => commands::cmd_xinet_register(
&client,
name,
listen,
backend,
service,
connect_timeout,
idle_timeout,
single,
),
XinetCommands::Unregister { name } => commands::cmd_xinet_unregister(&client, &name),
XinetCommands::List => commands::cmd_xinet_list(&client),
XinetCommands::Status { name } => commands::cmd_xinet_status(&client, name.as_deref()),
},
Commands::Poweroff => commands::cmd_poweroff(&client),
Commands::Reboot => commands::cmd_reboot(&client),
#[cfg(feature = "tui")]
Commands::Tui => unreachable!(),
#[cfg(feature = "rhai")]
Commands::Rhai { path } => commands::cmd_rhai(&path),
};
match result {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("Error: {}", e);
ExitCode::FAILURE
}
}
}