use super::*;
use commands::Command;
pub mod commands;
pub static CONFIG: OnceLock<Config> = OnceLock::new();
#[derive(Parser, Debug)]
#[command(name = "CI manager - Make common CI tasks easy!")]
#[command(bin_name = "ci-manager", version, propagate_version = true, author, styles = config_styles())]
#[command(about = "Manage CI")]
pub struct Config {
#[command(subcommand)]
command: Option<Command>,
#[arg(long, global = true, value_hint = ValueHint::Other, name = "SHELL")]
completions: Option<clap_complete::Shell>,
#[arg(short, long, global = true, default_value_t = 2)]
verbosity: u8,
#[arg(long, default_value_t = false, global = true)]
dry_run: bool,
#[arg(value_enum, long, global = true)]
ci: Option<CIProvider>,
#[arg(long, global = true, default_value_t = false)]
trim_timestamp: bool,
}
impl Config {
pub fn global() -> &'static Config {
CONFIG.get().expect("Config is not initialized")
}
pub fn subcmd(&self) -> &Command {
if let Some(subcmd) = &self.command {
subcmd
} else {
log::error!("Subcommand required! use `--help` for more information");
std::process::exit(1);
}
}
pub fn generate_completion_script(&self) -> bool {
match self.completions {
Some(shell) => {
generate_completion_script(shell);
true
}
None => false,
}
}
pub fn verbosity(&self) -> u8 {
self.verbosity
}
pub fn dry_run(&self) -> bool {
self.dry_run
}
pub fn no_ci(&self) -> Option<CIProvider> {
self.ci
}
pub fn trim_timestamp(&self) -> bool {
self.trim_timestamp
}
}
pub fn init() -> Result<()> {
let config = Config::parse();
CONFIG.set(config).expect("Config is already initialized");
use stderrlog::LogLevelNum;
let log_level = match Config::global().verbosity() {
0 => LogLevelNum::Error,
1 => LogLevelNum::Warn,
2 => LogLevelNum::Info,
3 => LogLevelNum::Debug,
4 => LogLevelNum::Trace,
_ => {
eprintln!("Invalid verbosity level: {}", Config::global().verbosity());
eprintln!("Using highest verbosity level: Trace");
LogLevelNum::Trace
}
};
stderrlog::new().verbosity(log_level).quiet(false).init()?;
if Config::global().dry_run() {
log::warn!("Running in dry-run mode. No writes/changes will be made");
}
Ok(())
}
fn config_styles() -> Styles {
Styles::styled()
.header(AnsiColor::Red.on_default() | Effects::BOLD)
.usage(AnsiColor::Yellow.on_default() | Effects::BOLD)
.literal(AnsiColor::Green.on_default() | Effects::BOLD)
.placeholder(AnsiColor::Blue.on_default())
}
fn generate_completion_script(shell: clap_complete::Shell) {
log::info!("Generating completion script for {shell:?}");
clap_complete::generate(
shell,
&mut <Config as clap::CommandFactory>::command(),
"ci-manager",
&mut std::io::stdout(),
);
}