use supports_color::Stream;
use tracing::{error, info};
use tracing_subscriber::{fmt, EnvFilter};
use xbp_cli::{api, cli};
fn strip_ansi_codes(input: &str) -> String {
let mut output = String::with_capacity(input.len());
let mut chars = input.chars().peekable();
while let Some(ch) = chars.next() {
if ch == '\u{1b}' && matches!(chars.peek(), Some('[')) {
let _ = chars.next();
for next in chars.by_ref() {
if ('@'..='~').contains(&next) {
break;
}
}
continue;
}
output.push(ch);
}
output
}
fn should_emit_ansi() -> bool {
let disable_via_clicolor = std::env::var("CLICOLOR")
.map(|value| value == "0")
.unwrap_or(false);
if std::env::var_os("NO_COLOR").is_some() || disable_via_clicolor {
return false;
}
if std::env::var_os("FORCE_COLOR").is_some() || std::env::var_os("CLICOLOR_FORCE").is_some() {
return true;
}
supports_color::on(Stream::Stderr).is_some()
}
#[tokio::main]
async fn main() {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_ansi(should_emit_ansi())
.init();
if std::env::var("PORT_XBP_API").is_ok() {
info!("Starting XBP API server mode");
if let Err(e) = api::start_api_server().await {
error!("API server error: {}", e);
std::process::exit(1);
}
} else if let Err(e) = cli::run().await {
let rendered = e.to_string();
eprintln!("{}", rendered);
error!("Error: {}", strip_ansi_codes(&rendered));
std::process::exit(1);
}
}