use clap_verbosity_flag::Verbosity;
use golem_common::tracing::directive;
use golem_common::tracing::directive::{debug, warn};
use shadow_rs::shadow;
use tracing_log::LogTracer;
use tracing_subscriber::{EnvFilter, FmtSubscriber};
pub mod app;
pub mod auth;
pub mod command;
pub mod command_handler;
pub mod config;
pub mod context;
pub mod diagnose;
pub mod error;
pub mod fs;
pub mod fuzzy;
pub mod log;
pub mod model;
pub mod validation;
pub mod wasm_rpc_stubgen;
#[allow(unused)]
mod wasm_metadata;
#[cfg(test)]
test_r::enable!();
shadow!(build);
pub fn command_name() -> String {
std::env::current_exe()
.ok()
.and_then(|path| {
path.file_stem()
.map(|name| name.to_string_lossy().to_string())
})
.unwrap_or("golem-cli".to_string())
}
pub fn version() -> &'static str {
if build::PKG_VERSION != "0.0.0" {
build::PKG_VERSION
} else {
build::GIT_DESCRIBE_TAGS
}
}
pub fn init_tracing(verbosity: Verbosity, pretty_mode: bool) {
if let Some(level) = verbosity.tracing_level() {
let subscriber = FmtSubscriber::builder();
let mut filter = EnvFilter::builder().parse_lossy(level.as_str());
for directive in directive::default_deps() {
filter = filter.add_directive(directive);
}
filter = filter.add_directive(warn("opentelemetry_sdk"));
filter = filter.add_directive(warn("opentelemetry"));
filter = filter.add_directive(warn("poem"));
filter = filter.add_directive(
if level == tracing::Level::TRACE {
debug("sqlx")
} else {
warn("sqlx")
},
);
if pretty_mode {
let subscriber = subscriber
.pretty()
.with_max_level(level)
.with_writer(std::io::stderr)
.with_env_filter(filter)
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
} else {
let subscriber = subscriber
.with_max_level(level)
.with_writer(std::io::stderr)
.with_env_filter(filter)
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
};
LogTracer::init().expect("failed to initialize log tracer");
}
}
#[cfg(test)]
mod tests {
use test_r::test;
use crate::command::GolemCliCommand;
use clap::{ArgAction, Command, CommandFactory};
#[test]
fn dump_commands_v_1_2() {
let command = GolemCliCommand::command();
dump_command(0, &command);
}
fn dump_command(level: usize, command: &Command) {
print!("{}{}", "\t".repeat(level), command.get_name());
let aliases = command.get_aliases().collect::<Vec<_>>();
if !aliases.is_empty() {
print!(" ({})", aliases.join(", "));
}
let (positional, flag_args): (Vec<_>, Vec<_>) =
command.get_arguments().partition(|arg| arg.is_positional());
if !positional.is_empty() {
for arg in positional {
let id = arg.get_id().to_string().to_uppercase();
if arg.is_required_set() && arg.get_default_values().is_empty() {
print!(" <{id}>");
} else {
print!(" [{id}]");
}
if let ArgAction::Append = arg.get_action() {
print!("...")
}
}
}
println!();
if !flag_args.is_empty() {
print!("{}", "\t".repeat(level + 2));
for arg in flag_args.clone() {
print!(" --{}", arg.get_long().unwrap(),);
arg.get_short().iter().for_each(|short| print!("({short})"));
}
println!()
}
let subcommand_level = level + 1;
for subcommand in command.get_subcommands() {
dump_command(subcommand_level, subcommand);
}
}
}