use crate::app::config_load::load_config_or_warn;
use crate::cli::Cli;
use crate::config::ReprexMode;
use crate::external::formatter;
use anyhow::{Context, Result};
use std::fs;
pub(crate) fn run_script(cli: &Cli) -> Result<()> {
let config = load_config_or_warn(cli.r_source.config.as_ref());
let resolution = super::setup_r(
&config.startup.r_source,
&config.experimental.r_source_overrides,
None,
cli.r_source.r_home.as_deref(),
cli.r_source.r_version.as_deref(),
cli.r_source.no_r_source_overrides,
)?;
resolution.emit_diagnostics();
if let Some(notice) = super::overrides::script_override_notice(&resolution) {
eprintln!("{notice}");
}
if let Err(e) = arf_libr::ensure_ld_library_path() {
log::warn!("Could not set LD_LIBRARY_PATH: {}", e);
}
let r_args = cli.r_args();
let r_args_refs: Vec<&str> = r_args.iter().map(|s| s.as_str()).collect();
unsafe {
arf_libr::initialize_r_with_args(&r_args_refs).context("Failed to initialize R")?;
}
#[cfg(windows)]
crate::app::r_profiles::source_r_profiles(&r_args);
let code = if let Some(eval_code) = &cli.eval {
eval_code.clone()
} else if let Some(script_path) = cli.script_file() {
if script_path == std::path::Path::new("-") {
use std::io::Read;
let mut buf = String::new();
std::io::stdin()
.read_to_string(&mut buf)
.context("Failed to read from stdin")?;
buf
} else {
fs::read_to_string(script_path)
.with_context(|| format!("Failed to read script file: {}", script_path.display()))?
}
} else {
return Ok(());
};
let mut reprex_mode = cli.reprex.unwrap_or(config.startup.reprex);
let formatter_selector = config.reprex.formatter;
let formatter_backend = formatter::resolve_formatter(formatter_selector);
if reprex_mode == ReprexMode::Format && formatter_backend.is_none() {
if cli.reprex.is_some() {
anyhow::bail!(
"{}",
formatter::unavailable_message(
formatter_selector,
formatter::FormatterUnavailableContext::ExplicitCli
)
);
}
eprintln!(
"{}",
formatter::unavailable_message(
formatter_selector,
formatter::FormatterUnavailableContext::ConfiguredMode
)
);
reprex_mode = ReprexMode::On;
}
if reprex_mode != ReprexMode::Off {
let code = if reprex_mode == ReprexMode::Format {
formatter::format_code(
formatter_backend.expect("format mode requires a resolved formatter"),
&code,
)?
} else {
code
};
match arf_harp::eval_string_reprex(&code, &config.reprex.comment) {
Ok(_) => Ok(()),
Err(e) => {
eprintln!("{}", e);
Ok(())
}
}
} else {
match arf_harp::eval_string(&code) {
Ok(_) => Ok(()),
Err(e) => {
eprintln!("{}", e);
Ok(())
}
}
}
}