use std::path::Path;
use std::process::ExitCode;
use clap::{CommandFactory, Parser};
use clap_complete::env::{Bash, CompleteEnv, Fish, Shells, Zsh};
use overbrainer::cli::{self, Cli};
fn main() -> ExitCode {
CompleteEnv::with_factory(Cli::command)
.shells(Shells(&[&Bash, &Zsh, &Fish]))
.complete();
let cli = Cli::parse();
let needs_env = !matches!(cli.command, cli::Command::Skill { .. });
if needs_env && let Err(message) = load_dotenv(&cli.project_dir.join(".env")) {
eprintln!("error: {message}");
return ExitCode::FAILURE;
}
let logs = cli.command.log_mode();
overbrainer::logging::init(&logs);
let runtime = match tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
{
Ok(runtime) => runtime,
Err(e) => {
eprintln!("error: cannot start async runtime: {e}");
return ExitCode::FAILURE;
},
};
match runtime.block_on(cli::run(cli, logs)) {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("error: {e:#}");
ExitCode::FAILURE
},
}
}
fn load_dotenv(path: &Path) -> Result<(), String> {
match dotenvy::from_path(path) {
Ok(()) => Ok(()),
Err(dotenvy::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(dotenvy::Error::LineParse(_, index)) => {
Err(format!("cannot parse .env (syntax error at index {index})"))
},
Err(dotenvy::Error::Io(e)) => Err(format!("cannot load .env: {e}")),
Err(_) => Err("cannot load .env".to_string()),
}
}