pesde/src/scripts.rs

109 lines
3.3 KiB
Rust
Raw Normal View History

use std::{
ffi::OsStr,
2024-08-08 16:59:59 +01:00
fmt::{Display, Formatter},
io::{BufRead, BufReader},
2024-07-22 15:41:45 +01:00
path::Path,
process::{Command, Stdio},
thread::spawn,
};
2024-08-03 21:18:38 +01:00
/// Script names used by pesde
2024-07-24 10:55:15 +01:00
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum ScriptName {
2024-08-03 21:18:38 +01:00
/// Generates a config for syncing tools for Roblox. For example, for Rojo it should create a `default.project.json` file
2024-07-24 10:55:15 +01:00
#[cfg(feature = "roblox")]
RobloxSyncConfigGenerator,
2024-08-03 21:18:38 +01:00
/// Prints a sourcemap for a Wally package, used for finding the library export file
2024-07-24 10:55:15 +01:00
#[cfg(feature = "wally-compat")]
SourcemapGenerator,
}
impl Display for ScriptName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
#[cfg(feature = "roblox")]
ScriptName::RobloxSyncConfigGenerator => write!(f, "roblox_sync_config_generator"),
#[cfg(feature = "wally-compat")]
ScriptName::SourcemapGenerator => write!(f, "sourcemap_generator"),
}
}
}
2024-08-03 21:18:38 +01:00
/// Executes a script with the given arguments
2024-07-22 15:41:45 +01:00
pub fn execute_script<A: IntoIterator<Item = S>, S: AsRef<OsStr>, P: AsRef<Path>>(
script_name: Option<&str>,
2024-07-22 15:41:45 +01:00
script_path: &Path,
args: A,
2024-07-22 15:41:45 +01:00
cwd: P,
return_stdout: bool,
) -> Result<Option<String>, std::io::Error> {
match Command::new("lune")
.arg("run")
2024-07-22 15:41:45 +01:00
.arg(script_path.as_os_str())
2024-08-08 16:59:59 +01:00
.arg("--")
.args(args)
2024-07-22 15:41:45 +01:00
.current_dir(cwd)
2024-08-11 15:16:25 +01:00
.stdin(Stdio::inherit())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
{
Ok(mut child) => {
let stdout = BufReader::new(child.stdout.take().unwrap());
let stderr = BufReader::new(child.stderr.take().unwrap());
let script = match script_name {
Some(script) => script.to_string(),
2024-07-22 15:41:45 +01:00
None => script_path.to_string_lossy().to_string(),
};
let script_2 = script.to_string();
spawn(move || {
for line in stderr.lines() {
match line {
Ok(line) => {
log::error!("[{script}]: {line}");
}
Err(e) => {
log::error!("ERROR IN READING STDERR OF {script}: {e}");
break;
}
}
}
});
2024-07-22 15:41:45 +01:00
let mut stdout_str = String::new();
for line in stdout.lines() {
match line {
Ok(line) => {
2024-07-22 15:41:45 +01:00
if return_stdout {
stdout_str.push_str(&line);
stdout_str.push('\n');
2024-08-08 16:59:59 +01:00
} else {
log::info!("[{script_2}]: {line}");
2024-07-22 15:41:45 +01:00
}
}
Err(e) => {
log::error!("ERROR IN READING STDOUT OF {script_2}: {e}");
break;
}
}
}
2024-07-22 15:41:45 +01:00
if return_stdout {
Ok(Some(stdout_str))
} else {
Ok(None)
}
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
2024-07-22 15:41:45 +01:00
log::warn!("Lune could not be found in PATH: {e}");
2024-07-22 15:41:45 +01:00
Ok(None)
}
Err(e) => Err(e),
}
}