mod browser_cookies;
mod cli;
pub mod transaction_id;
mod commands;
mod config;
mod context;
mod errors;
pub mod intel;
mod output;
mod providers;
mod star_nudge;
pub mod utils;
use clap::Parser;
use cli::Cli;
use config::load_config;
use context::AppContext;
use output::OutputFormat;
use std::sync::Arc;
fn has_json_flag() -> bool {
std::env::args_os().any(|a| a == "--json")
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("warn")),
)
.with_writer(std::io::stderr)
.init();
let json_flag = has_json_flag();
let cli = match Cli::try_parse() {
Ok(cli) => cli,
Err(e) => {
if matches!(
e.kind(),
clap::error::ErrorKind::DisplayHelp
| clap::error::ErrorKind::DisplayVersion
) {
e.exit();
}
let format = OutputFormat::detect(json_flag);
output::render_error(format, "bad_input", &e.to_string(), "Check arguments with: xmaster --help");
std::process::exit(3);
}
};
let format = OutputFormat::detect(cli.json);
let config = match load_config() {
Ok(c) => c,
Err(e) => {
output::render_error(format, e.error_code(), &e.to_string(), &e.suggestion());
std::process::exit(e.exit_code());
}
};
let ctx = match AppContext::new(config) {
Ok(c) => Arc::new(c),
Err(e) => {
output::render_error(format, e.error_code(), &e.to_string(), &e.suggestion());
std::process::exit(e.exit_code());
}
};
let result = commands::dispatch(ctx.clone(), &cli, format).await;
if let Err(e) = result {
output::render_error(format, e.error_code(), &e.to_string(), &e.suggestion());
std::process::exit(e.exit_code());
}
star_nudge::maybe_show(format);
}