1use crate::Error;
2use log::debug;
3use std::env;
4use std::path::PathBuf;
5use std::process::Command;
6
7#[derive(Debug)]
8pub struct Requirements<'a> {
9 pub args: &'a str,
10 pub current_dir: PathBuf,
11}
12
13impl<'a> TryFrom<&'a str> for Requirements<'a> {
14 type Error = Error;
15 fn try_from(args: &'a str) -> Result<Self, Self::Error> {
16 let current_dir = env::current_dir()?;
17 Ok(Self { args, current_dir })
18 }
19}
20
21pub fn run(binary: &str, requirements: Requirements, error: Error) -> Result<String, Error> {
22 debug!(
23 "cd {} && {binary} {};",
24 requirements.current_dir.display(),
25 requirements.args
26 );
27 let args = shell_words::split(requirements.args)?;
28 let output = Command::new(binary)
29 .args(args)
30 .current_dir(requirements.current_dir)
31 .output()?;
32 let stdout = String::from_utf8_lossy(&output.stdout);
33 if !output.status.success() {
34 debug!("stdout: {stdout}");
35 debug!("stderr: {}", String::from_utf8_lossy(&output.stderr));
36 return Err(error);
37 }
38 debug!("Finished executing command");
39 Ok(stdout.to_string())
40}