use std::{
cell::RefCell,
env::current_dir,
ffi::OsStr,
fs::{create_dir, create_dir_all},
io::Write,
path::PathBuf,
sync::OnceLock,
};
use anyhow::bail;
use cliargs::parse_args;
use console::style;
use env_logger::Env;
use indicatif::MultiProgress;
use indicatif_log_bridge::LogWrapper;
use crate::envs::HOME;
pub mod caching;
pub mod cliargs;
pub mod config;
pub mod plugin;
pub mod pom;
pub mod submodules;
pub mod templating;
thread_local! {
pub static MULTI_PRPGRESS_BAR: RefCell<MultiProgress> = RefCell::new(MultiProgress::new());
}
static PROJECT_ROOT: OnceLock<PathBuf> = OnceLock::new();
pub const LABT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub mod envs {
pub const LABT_HOME: &str = "LABT_HOME";
pub const HOME: &str = "HOME";
}
pub fn get_home() -> anyhow::Result<PathBuf> {
if let Ok(path) = std::env::var(envs::LABT_HOME) {
return Ok(PathBuf::from(path));
}
if let Ok(path) = std::env::var(envs::HOME) {
let mut path = PathBuf::from(path);
path.push(".labt");
if path.exists() {
return Ok(path);
} else {
bail!(std::io::Error::new(
std::io::ErrorKind::NotFound,
".labt folder does not exist on $HOME",
));
}
}
bail!("No apropriate Labt home directory detected!");
}
pub fn get_project_root<'a>() -> std::io::Result<&'a PathBuf> {
if let Some(path) = PROJECT_ROOT.get() {
return Ok(path);
}
let cwd = current_dir()?;
let path = get_project_root_recursive(cwd)?;
Ok(PROJECT_ROOT.get_or_init(|| path))
}
fn get_project_root_recursive(current_dir: PathBuf) -> std::io::Result<PathBuf> {
for entry in (current_dir.read_dir()?).flatten() {
let file = entry.path();
if file.is_file() && file.file_name() == Some(OsStr::new("Labt.toml")) {
return Ok(current_dir);
}
}
if let Some(path) = current_dir.parent() {
get_project_root_recursive(PathBuf::from(path))
} else {
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"Failed to get project root",
))
}
}
fn first_run(path: &mut PathBuf) -> anyhow::Result<()> {
path.push(".labt");
create_dir_all(&path)?;
path.push("cache");
create_dir(&path)?;
path.pop();
path.push("plugins");
create_dir(&path)?;
Ok(())
}
fn main() -> anyhow::Result<()> {
if get_home().is_err() {
if let Ok(home) = std::env::var(HOME) {
println!("Initializing LABt configs on home directory.");
let mut path = PathBuf::from(home);
first_run(&mut path)?;
}
};
let logger = env_logger::Builder::from_env(Env::default().default_filter_or("info"))
.format_timestamp(None)
.format(|buf, record| {
let level = match record.level() {
log::Level::Error => style("ERROR").red().bold(),
log::Level::Warn => style(" WARN").yellow().bold(),
log::Level::Info => style(" INFO").green().bold(),
log::Level::Debug => style("DEBUG").blue().bold(),
log::Level::Trace => style("TRACE").blue().bold(),
};
writeln!(
buf,
"{}{} {}{} {}",
style("[").dim(),
level,
style(record.target()).dim(),
style("]").dim(),
record.args()
)
})
.build();
let multi = MULTI_PRPGRESS_BAR.with(|multi| multi.borrow().clone());
LogWrapper::new(multi.clone(), logger).try_init()?;
parse_args();
Ok(())
}