zinit 0.3.6

Process supervisor with dependency management
Documentation
//! zinit CLI - Command line interface for the zinit process supervisor.

use std::process::ExitCode;

use clap::Parser;
use zinit::client::cli::{Cli, Commands, XinetCommands, commands};
use zinit::sdk::{ZinitClient, socket};

#[cfg(feature = "repl")]
use zinit::client::repl;
#[cfg(feature = "tui")]
use zinit::client::tui;

fn main() -> ExitCode {
    let cli = Cli::parse();

    // Handle commands that don't need a daemon connection
    match &cli.command {
        Commands::Poweroff => {
            return match commands::cmd_poweroff() {
                Ok(()) => ExitCode::SUCCESS,
                Err(e) => {
                    eprintln!("Error: {}", e);
                    ExitCode::FAILURE
                }
            };
        }
        Commands::Reboot => {
            return match commands::cmd_reboot() {
                Ok(()) => ExitCode::SUCCESS,
                Err(e) => {
                    eprintln!("Error: {}", e);
                    ExitCode::FAILURE
                }
            };
        }
        #[cfg(feature = "tui")]
        Commands::Tui => {
            let socket_path = cli.socket.unwrap_or_else(socket::default_path);
            return match tui::run(&socket_path) {
                Ok(()) => ExitCode::SUCCESS,
                Err(e) => {
                    eprintln!("Error: {}", e);
                    ExitCode::FAILURE
                }
            };
        }
        #[cfg(feature = "repl")]
        Commands::Repl => {
            let socket_path = cli.socket.unwrap_or_else(socket::default_path);
            return match repl::run(&socket_path) {
                Ok(()) => ExitCode::SUCCESS,
                Err(e) => {
                    eprintln!("Error: {}", e);
                    ExitCode::FAILURE
                }
            };
        }
        _ => {}
    }

    // Connect to the daemon
    let socket_path = cli.socket.unwrap_or_else(socket::default_path);
    let mut client = match ZinitClient::connect(&socket_path) {
        Ok(c) => c,
        Err(e) => {
            eprintln!(
                "Error: Failed to connect to zinit daemon at {}: {}",
                socket_path.display(),
                e
            );
            eprintln!("Is zinit-server running?");
            return ExitCode::FAILURE;
        }
    };

    let result = match cli.command {
        Commands::List => commands::cmd_list(&mut client),
        Commands::Status { name } => commands::cmd_status(&mut client, &name),
        Commands::Start { name, tree } => commands::cmd_start(&mut client, &name, tree),
        Commands::Stop { name } => commands::cmd_stop(&mut client, &name),
        Commands::Restart { name } => commands::cmd_restart(&mut client, &name),
        Commands::Kill { name, signal } => {
            commands::cmd_kill(&mut client, &name, signal.as_deref())
        }
        Commands::Why { name } => commands::cmd_why(&mut client, &name),
        Commands::Tree => commands::cmd_tree(&mut client),
        Commands::Remove { name } => commands::cmd_remove(&mut client, &name),
        Commands::Reload => commands::cmd_reload(&mut client),
        Commands::Logs {
            name,
            lines,
            follow,
        } => commands::cmd_logs(&mut client, &name, lines, follow),
        Commands::Ping => commands::cmd_ping(&mut client),
        Commands::Shutdown => commands::cmd_shutdown(&mut 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(
            &mut 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(&mut client),
        Commands::DebugProcs { name } => commands::cmd_debug_procs(&mut client, &name),
        Commands::Xinet { command } => match command {
            XinetCommands::Register {
                name,
                listen,
                backend,
                service,
                connect_timeout,
                idle_timeout,
                single,
            } => commands::cmd_xinet_register(
                &mut client,
                name,
                listen,
                backend,
                service,
                connect_timeout,
                idle_timeout,
                single,
            ),
            XinetCommands::Unregister { name } => {
                commands::cmd_xinet_unregister(&mut client, &name)
            }
            XinetCommands::List => commands::cmd_xinet_list(&mut client),
            XinetCommands::Status { name } => {
                commands::cmd_xinet_status(&mut client, name.as_deref())
            }
        },
        // These are handled before client connection
        Commands::Poweroff | Commands::Reboot => unreachable!(),
        #[cfg(feature = "tui")]
        Commands::Tui => unreachable!(),
        #[cfg(feature = "repl")]
        Commands::Repl => unreachable!(),
    };

    match result {
        Ok(()) => ExitCode::SUCCESS,
        Err(e) => {
            eprintln!("Error: {}", e);
            ExitCode::FAILURE
        }
    }
}