use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "zinit")]
#[command(author, version)]
#[command(about = "Process supervisor with dependency management")]
#[command(
long_about = "zinit is a process supervisor with dependency management, \
similar to systemd but simpler.\n\n\
Examples:\n \
zinit list # List all services\n \
zinit status nginx # Show nginx service status\n \
zinit start --tree myapp # Start myapp and its dependencies\n \
zinit why myapp # Show why myapp is blocked\n \
zinit tree # Show dependency tree\n \
zinit tui # Launch interactive TUI (if enabled)\n \
zinit repl # Launch interactive REPL (if enabled)"
)]
pub struct Cli {
#[arg(short, long, global = true)]
pub socket: Option<PathBuf>,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
#[allow(clippy::large_enum_variant)]
pub enum Commands {
#[command(alias = "ls")]
List,
Status {
name: String,
},
Start {
name: String,
#[arg(long)]
tree: bool,
},
Stop {
name: String,
},
Restart {
name: String,
},
Kill {
name: String,
#[arg(short, long)]
signal: Option<String>,
},
Why {
name: String,
},
Tree,
Remove {
name: String,
},
Reload,
Logs {
name: String,
#[arg(short = 'n', long, default_value = "100")]
lines: usize,
#[arg(short, long)]
follow: bool,
},
Ping,
Shutdown,
Poweroff,
Reboot,
#[command(name = "add-service")]
AddService {
#[arg(value_name = "FILE", conflicts_with_all = ["name", "exec"])]
file: Option<PathBuf>,
#[arg(long, requires = "exec")]
name: Option<String>,
#[arg(long, requires = "name")]
exec: Option<String>,
#[arg(long, default_value = "/")]
dir: String,
#[arg(long)]
oneshot: bool,
#[arg(long = "env", short = 'e', value_name = "KEY=VALUE")]
envs: Vec<String>,
#[arg(long, value_name = "SERVICE")]
after: Vec<String>,
#[arg(long, value_name = "SERVICE")]
requires: Vec<String>,
#[arg(long, value_name = "SERVICE")]
wants: Vec<String>,
#[arg(long, value_name = "SERVICE")]
conflicts: Vec<String>,
#[arg(long, default_value = "on-failure")]
restart: String,
#[arg(long, default_value = "1000")]
restart_delay: u64,
#[arg(long, default_value = "300000")]
restart_delay_max: u64,
#[arg(long, default_value = "10")]
max_restarts: u32,
#[arg(long, conflicts_with = "ephemeral")]
persist: bool,
#[arg(long, conflicts_with = "persist")]
ephemeral: bool,
},
#[command(name = "debug-state")]
DebugState,
#[command(name = "debug-procs")]
DebugProcs {
name: String,
},
#[cfg(feature = "tui")]
Tui,
#[cfg(feature = "repl")]
Repl,
Xinet {
#[command(subcommand)]
command: XinetCommands,
},
}
#[derive(Subcommand)]
pub enum XinetCommands {
Register {
name: String,
#[arg(short, long, required = true)]
listen: Vec<String>,
#[arg(short, long)]
backend: String,
#[arg(long)]
service: String,
#[arg(long, default_value = "30")]
connect_timeout: u64,
#[arg(long, default_value = "0")]
idle_timeout: u64,
#[arg(long)]
single: bool,
},
Unregister {
name: String,
},
List,
Status {
name: Option<String>,
},
}