use std::path::PathBuf; use embed_nu::{Argument, CommandGroupConfig, Context, ValueIntoExpression}; use tokio::fs; use crate::{ distro::OSConfig, error::{AppError, AppResult}, }; pub struct ExecBuilder { pub script: PathBuf, pub os_config: OSConfig, pub task_config: embed_nu::Value, } impl ExecBuilder { pub async fn exec(self) -> AppResult<()> { let script_contents = self.get_script_contents().await?; let mut ctx = Context::builder() .with_command_groups(CommandGroupConfig::default().all_groups(true))? .add_var("TRM_CONFIG", self.os_config)? .add_script(script_contents)? .build()?; if ctx.has_fn("main") { let pipeline = ctx.call_fn( "main", vec![Argument::Positional(self.task_config.into_expression())], )?; ctx.print_pipeline_stderr(pipeline)?; Ok(()) } else { Err(AppError::MissingMain(self.script)) } } async fn get_script_contents(&self) -> AppResult { let contents = fs::read_to_string(&self.script).await?; Ok(contents) } }