use std::fs;
use std::io::Write;
use std::process::Command;
use tempfile::NamedTempFile;
use crate::error::{EchoCommentError, Result};
pub struct ScriptRunner {
}
impl ScriptRunner {
pub fn new() -> Self {
Self {}
}
pub fn run_script(&self, script_content: &str, script_args: &[String]) -> Result<()> {
let mut temp_file =
NamedTempFile::new().map_err(|e| EchoCommentError::TempFileCreation { source: e })?;
temp_file
.write_all(script_content.as_bytes())
.map_err(|e| EchoCommentError::FileWrite { source: e })?;
temp_file
.flush()
.map_err(|e| EchoCommentError::FileWrite { source: e })?;
let temp_path = temp_file.into_temp_path();
#[cfg(unix)]
self.make_executable(&temp_path)?;
let status = Command::new(&temp_path)
.args(script_args)
.status()
.map_err(|e| EchoCommentError::ScriptExecution {
message: "Failed to execute processed script".to_string(),
source: e,
})?;
temp_path.close().map_err(|e| EchoCommentError::FileWrite {
source: std::io::Error::other(e),
})?;
std::process::exit(status.code().unwrap_or(1));
}
#[cfg(unix)]
fn make_executable(&self, path: &std::path::Path) -> Result<()> {
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(path)
.map_err(|e| EchoCommentError::PermissionSet { source: e })?
.permissions();
perms.set_mode(0o755);
fs::set_permissions(path, perms)
.map_err(|e| EchoCommentError::PermissionSet { source: e })?;
Ok(())
}
}
impl Default for ScriptRunner {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_script_runner_creation() {
let _runner = ScriptRunner::new();
}
}