use crate::external::rig;
use std::io::{self, Write};
use std::process::{Command, Stdio};
use super::arf_eprintln;
pub fn execute_shell_command(cmd: &str) {
#[cfg(unix)]
let result = {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
Command::new(&shell)
.arg("-c")
.arg(cmd)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
};
#[cfg(windows)]
let result = Command::new("cmd")
.arg("/c")
.arg(cmd)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn();
match result {
Ok(mut child) => {
if let Err(e) = child.wait() {
arf_eprintln!("Failed to wait for command: {}", e);
}
}
Err(e) => {
arf_eprintln!("Failed to execute command: {}", e);
}
}
}
pub fn confirm_action(prompt: &str) -> bool {
print!("{} [y/N]: ", prompt);
let _ = io::stdout().flush();
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
let response = input.trim().to_lowercase();
response == "y" || response == "yes"
}
Err(_) => false,
}
}
pub fn restart_process(version: Option<&str>) {
if let Some(ver) = version {
if !rig::rig_available() {
arf_eprintln!("Error: rig is not installed. Cannot switch R versions.");
arf_eprintln!("Install rig from https://github.com/r-lib/rig");
return;
}
match rig::resolve_version(ver) {
Ok(resolved) => {
log::info!(
"Switching to R version {} ({})",
resolved.version,
resolved.r_home
);
}
Err(e) => {
arf_eprintln!("Error: {}", e);
return;
}
}
}
let exe = match std::env::current_exe() {
Ok(e) => e,
Err(e) => {
arf_eprintln!("Error: Failed to get current executable: {}", e);
return;
}
};
let mut args: Vec<String> = std::env::args().skip(1).collect();
if let Some(v) = &version {
args = filter_r_version_args(args);
args.push("--with-r-version".to_string());
args.push(v.to_string());
}
if version.is_some() {
unsafe {
std::env::remove_var("R_HOME");
std::env::remove_var("LD_LIBRARY_PATH");
}
}
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
let mut cmd = Command::new(&exe);
cmd.args(&args);
let err = cmd.exec();
arf_eprintln!("Error: Failed to restart: {}", err);
}
#[cfg(not(unix))]
{
match Command::new(&exe)
.args(&args)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
{
Ok(mut child) => match child.wait() {
Ok(status) => std::process::exit(status.code().unwrap_or(1)),
Err(e) => {
arf_eprintln!("Error: Failed to wait for restarted process: {}", e);
std::process::exit(1);
}
},
Err(e) => {
arf_eprintln!("Error: Failed to restart: {}", e);
std::process::exit(1);
}
}
}
}
fn filter_r_version_args(args: Vec<String>) -> Vec<String> {
let mut result = Vec::new();
let mut skip_next = false;
for arg in args {
if skip_next {
skip_next = false;
continue;
}
if arg == "--with-r-version" {
skip_next = true;
continue;
}
if arg.starts_with("--with-r-version=") {
continue;
}
result.push(arg);
}
result
}