mod dogs;
mod flock;
mod help;
mod import;
mod logs;
mod sheep;
mod store;
mod system;
mod verbs;
use std::path::PathBuf;
use help::{HELP_TEMPLATE, version_text};
pub use dogs::{AdoptArgs, DogArgs, DogsArgs, EnableArgs};
pub use flock::{FlockArgs, FoldArgs, LookoutArgs};
pub use import::{ImportArgs, ImportCommand, ImportEnvArgs, ImportPm2Args};
pub use logs::{BarksArgs, BleatsArgs, FlushArgs, ReopenArgs};
#[allow(unused_imports)]
pub(crate) use flock::FOLLOW_INTERVAL_FLOOR_SECONDS;
#[allow(unused_imports)]
pub use logs::DEFAULT_BLEAT_LINES;
pub use sheep::{
ResetMode, SelectorArgs, ServeArgs, SignalArgs, StartArgs, StockArgs, TriggerArgs, WhisperArgs,
};
pub use store::{KvGetArgs, KvSetArgs, KvUnsetArgs, SecretArgs, SecretCommand};
pub use system::{
CompletionArgs, DaemonArgs, DaemonCmd, DevArgs, InitArgs, RuntimeArgs, StartupArgs, StyleArgs,
};
pub use verbs::Commands;
#[derive(Debug, clap::Parser)]
#[command(
name = "shep",
bin_name = "shep",
version,
long_version = version_text(),
about = "A process manager for your flock",
propagate_version = true,
help_template = HELP_TEMPLATE,
after_help = "Run `shep help <command>` for one command, or `shep welcome` for the tour."
)]
pub struct Cli {
#[command(flatten)]
pub global: GlobalArgs,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, clap::Args)]
pub struct GlobalArgs {
#[arg(long, global = true, value_enum, default_value_t = Format::Table)]
pub format: Format,
#[arg(short, long, global = true)]
pub quiet: bool,
#[arg(long, global = true, value_enum)]
pub style: Option<crate::style::StyleLevel>,
#[arg(long, global = true, env = "SHEP_HOME")]
pub home: Option<PathBuf>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum Format {
Table,
Json,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
#[clap(rename_all = "kebab-case")]
pub enum Init {
Systemd,
Openrc,
Launchd,
FreebsdRc,
OpenbsdRc,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_defaults_to_table_and_accepts_json() {
use clap::Parser;
let cli = Cli::try_parse_from(["shep", "flock"]).unwrap();
assert_eq!(cli.global.format, Format::Table);
let cli = Cli::try_parse_from(["shep", "--format", "json", "flock"]).unwrap();
assert_eq!(cli.global.format, Format::Json);
}
#[test]
fn style_flag_defaults_to_unset_and_accepts_the_three_levels() {
use crate::style::StyleLevel;
use clap::Parser;
let cli = Cli::try_parse_from(["shep", "flock"]).unwrap();
assert_eq!(cli.global.style, None);
for (raw, expected) in [
("full", StyleLevel::Full),
("plain", StyleLevel::Plain),
("bare", StyleLevel::Bare),
] {
let cli = Cli::try_parse_from(["shep", "--style", raw, "flock"]).unwrap();
assert_eq!(cli.global.style, Some(expected), "--style {raw}");
}
assert!(Cli::try_parse_from(["shep", "--style", "loud", "flock"]).is_err());
}
#[test]
fn home_flag_is_wired_to_the_shep_home_env_var() {
use clap::CommandFactory;
let cmd = Cli::command();
let home_arg = cmd
.get_arguments()
.find(|a| a.get_id().as_str() == "home")
.expect("GlobalArgs::home must still be a flattened argument named `home`");
assert_eq!(home_arg.get_env(), Some(std::ffi::OsStr::new("SHEP_HOME")));
}
}