use crate::{Afterburner, AfterburnerError, EnvAccess, ScriptInvocation};
use anyhow::{Context, Result};
use std::collections::BTreeMap;
use std::io::Write;
use super::args::Cli;
use super::manifold::build_manifold;
pub fn build_invocation(cli: &Cli, script_label: &str, user_args: &[String]) -> ScriptInvocation {
let mut argv = Vec::with_capacity(2 + user_args.len());
argv.push("burn".to_string());
argv.push(script_label.to_string());
argv.extend(user_args.iter().cloned());
ScriptInvocation {
argv,
env: collect_env(cli),
cwd: cli_cwd(),
}
}
pub fn cli_cwd() -> String {
std::env::current_dir()
.map(|p| p.to_string_lossy().into_owned())
.unwrap_or_else(|_| "/".to_string())
}
fn collect_env(cli: &Cli) -> BTreeMap<String, String> {
let manifold = build_manifold(cli);
match &manifold.env {
EnvAccess::None => BTreeMap::new(),
EnvAccess::AllowList(keys) => keys
.iter()
.filter_map(|k| std::env::var(k).ok().map(|v| (k.clone(), v)))
.collect(),
EnvAccess::Full => std::env::vars().collect(),
}
}
pub fn execute(
ab: &Afterburner,
source: &str,
script_label: &str,
user_args: &[String],
cli: &Cli,
) -> Result<()> {
let invocation = build_invocation(cli, script_label, user_args);
let outcome = ab
.run_script_with(source, &invocation, ab.default_limits())
.map_err(|e: AfterburnerError| anyhow::anyhow!("{e}"))?;
std::io::stdout()
.write_all(&outcome.stdout)
.context("write script stdout")?;
std::io::stderr()
.write_all(&outcome.stderr)
.context("write script stderr")?;
if outcome.exit_code != 0 {
std::process::exit(outcome.exit_code);
}
Ok(())
}