use std::process::ExitCode;
use clap::Parser;
use tracing_subscriber::EnvFilter;
use crate::cli::{Cli, Command};
use crate::commands::ExitOutcome;
use crate::discovery::resolve_manifest;
mod cli;
mod commands;
mod control_url;
mod discovery;
mod output;
#[tokio::main]
async fn main() -> ExitCode {
let cli = Cli::parse();
if !matches!(cli.command, Command::Up { .. }) {
init_plain_logging();
}
match run(cli).await {
Ok(outcome) => ExitCode::from(u8::try_from(outcome.code()).unwrap_or(1)),
Err(err) => {
eprintln!("error: {err:#}");
ExitCode::from(1)
}
}
}
async fn run(cli: Cli) -> anyhow::Result<ExitOutcome> {
match cli.command {
Command::Up {
grace,
control_port,
no_otel,
} => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::up::run(&manifest, grace.into(), control_port, no_otel).await
}
Command::Down { grace } => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::down::run(&manifest, grace.into()).await
}
Command::Ps => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::ps::run(&manifest).await
}
Command::Logs { resource, follow } => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::logs::run(&manifest, &resource, follow).await
}
Command::Validate { strict } => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::validate::run(&manifest, strict)
}
Command::Manifest => {
let manifest = resolve_manifest(cli.file.as_deref())?;
commands::manifest::run(&manifest)
}
Command::Restart { resource, detach } => commands::restart::run(&resource, detach).await,
Command::Alias { action } => commands::alias::run(&action),
}
}
pub(crate) fn init_plain_logging() {
let filter =
EnvFilter::try_from_env("LIGHTSHUTTLE_LOG").unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.with_level(true)
.compact()
.init();
}