mod cli;
mod context;
mod dropins;
mod logger;
mod plugins;
mod sigint;
use std::path::PathBuf;
use context::Context;
use reedline_repl_rs::Repl;
const VERSION: &str = env!("CARGO_PKG_VERSION");
fn throwing_error_handler<Context, E: std::fmt::Debug + std::fmt::Display>(
error: E,
_repl: &Repl<Context, E>,
) -> Result<(), reedline_repl_rs::Error> {
eprintln!("DevshellError: {error:?}");
Err(reedline_repl_rs::Error::UnknownCommand("".to_string()))
}
fn interactive_error_handler<Context, E: std::fmt::Debug + std::fmt::Display>(
error: E,
_repl: &Repl<Context, E>,
) -> Result<(), reedline_repl_rs::Error> {
eprintln!("DevshellError: {error:?}");
Ok(())
}
fn main() -> anyhow::Result<()> {
logger::init_subscriber()?;
tracing::info!("Starting new instance of devshell");
println!("=============================================================");
println!("GIT_BRANCH: {}", env!("GIT_BRANCH"));
println!("GIT_HASH: {}", env!("GIT_HASH"));
println!("=============================================================");
let mut context = Context::default();
let args = <cli::CliArguments as clap::Parser>::parse();
args.check_io_eligible()?;
if let Err(res) = cli::act_on_args(&args, &mut context) {
eprintln!("{res}");
}
let mut devshell_home: Option<PathBuf> = None;
if let Ok(dir) = std::env::var("DEVSHELL_HOME") {
devshell_home = Some(PathBuf::from(dir));
} else if let Ok(dir) = std::env::var("HOME") {
devshell_home = Some(PathBuf::from(dir).join(".devshell"));
};
let mut repl: Repl<Context, anyhow::Error> = Repl::new(context)
.with_name("devshell>")
.with_version(VERSION)
.with_description("wildland developer shell");
if args.uses_script() || args.uses_pipe() {
repl = repl.with_error_handler(throwing_error_handler);
}
if let Some(devshell_home) = devshell_home {
let historyfile = devshell_home.join("history");
repl = repl.with_history(historyfile, 5000);
}
let repl: Repl<Context, anyhow::Error> = dropins::lss::handler::extend(repl);
let repl: Repl<Context, anyhow::Error> = dropins::sfo::handler::extend(repl);
let repl: Repl<Context, anyhow::Error> = context::extend(repl);
let repl: Repl<Context, anyhow::Error> = plugins::dfs::extend(repl);
let repl: Repl<Context, anyhow::Error> = plugins::cargo::extend_all(repl);
let repl: Repl<Context, anyhow::Error> = plugins::evs::extend_all(repl);
let mut repl = repl;
tracing::warn!("Starting REPL loop");
args.process_io(&mut repl);
if args.is_interactive() || !(args.uses_pipe() || args.uses_script()) {
repl = repl.with_error_handler(interactive_error_handler);
repl.run()?;
}
Ok(())
}