use crate::{error::WefterErr, fs::res::ResourceDir};
use anyhow::Result;
use clap::Parser;
use std::rc::Rc;
mod cli;
mod config;
mod engine;
mod error;
mod fs;
mod templates;
mod tui;
fn try_main() -> Result<()> {
let ui = Rc::new(tui::TuiInterface::new());
let params = cli::Params::parse();
if params.help {
ui.print_help();
return Ok(());
}
if params.meta {
ui.print_lua_meta();
return Ok(());
}
cli::setup_logger(params.verbose)?;
log::trace!("{:?}", ¶ms);
let mut dirs = fs::dirs::DirCfg::new()?;
dirs.create_if_not_exist()?;
if let Some(wd) = params.root {
log::info!("Changed working directory to: {:?}", &wd);
dirs.update_working_dir(wd)?;
}
let cfg = config::CfgFile::read(&dirs)?;
log::trace!("{:?}", &cfg);
if let Some(dir) = cfg.data_dir {
log::info!("Configuration set resource directory to: {:?}", &dir);
dirs.update_data_dir(dir)?;
}
if dirs.update_local_dir(params.local_resources).is_ok() {
log::info!("Reading from project directory: {:?}", &dirs.local);
}
log::trace!("{:?}", &dirs);
let resources = fs::res::ResourceDir::load(&dirs)?;
if resources.is_empty() {
ui.print_err_no_available_profiles(&dirs);
return Err(WefterErr::NoAvailableProfiles.into());
}
if params.profiles {
ui.print_profile_list(&resources, &dirs);
return Ok(());
}
let mut lua = engine::LuaInterpreter::new(&dirs)?;
let profile: (&String, &ResourceDir) = if let Some(key) = ¶ms.profile {
resources
.get_key_value(key)
.ok_or_else(|| WefterErr::UnknownProfile(key.clone()))
} else {
let auto = lua.run_auto(&resources)?;
log::trace!("Valid auto profiles: {:?}", &auto);
match auto.len() {
0 => Result::Err(WefterErr::NoProfileSpecified.into()),
1 => auto
.first()
.ok_or_else(|| WefterErr::NoAvailableProfiles)
.map(|k| {
resources
.get_key_value(k)
.ok_or_else(|| WefterErr::UnknownProfile(k.clone()))
})
.flatten(),
1.. => ui.select("Select a profile", &auto).map(|key| {
resources
.get_key_value(&key)
.ok_or_else(|| WefterErr::UnknownProfile(key))
})?,
}
}?;
log::debug!("Using profile: {:?}", &profile);
let pdef: engine::ProfileDef = lua.run_init(&profile.1)?;
log::info!("Successfully loaded profile definition: {:?}", profile.0);
log::trace!("{:?}", pdef);
if params.commands {
ui.print_profile(profile.0, &pdef);
return Ok(());
}
lua.init(profile.1, ui.clone())?;
match lua.exec_command(params.trailing, &pdef) {
Ok(history) => {
log::debug!("Executed 'init.lua' successfully");
if !history.borrow().is_empty() {
ui.print_history(
Rc::into_inner(history)
.ok_or(WefterErr::ApplicationError(
"Failed to take ownership of 'history'".to_string(),
))?
.into_inner(),
);
}
}
Err(err) => match err {
WefterErr::EmptyParameters => ui.print_err_empty_parameters(profile.0, &pdef),
_ => ui.print_error(&err),
},
};
Ok(())
}
fn main() -> () {
if let Err(e) = try_main() {
log::error!("{:#}", e);
std::process::exit(1);
}
}