basic support for running commands directly

This commit is contained in:
Michael 2018-08-16 17:10:55 +00:00
parent f7d015fab5
commit 87a8486c37

View file

@ -11,7 +11,12 @@ use PROGRAMS;
pub struct Handler { pub struct Handler {
config: TomlValue, config: TomlValue,
exec: PathBuf, program: Program,
}
pub enum Program {
Command(String),
Exec(PathBuf),
} }
impl Handler { impl Handler {
@ -21,15 +26,26 @@ impl Handler {
.ok_or(err_msg("No 'type' found."))? .ok_or(err_msg("No 'type' found."))?
.as_str() .as_str()
.ok_or(err_msg("'type' is not a string."))?; .ok_or(err_msg("'type' is not a string."))?;
let exec = { let program = match handler {
let programs = PROGRAMS.lock().unwrap(); "script" => {
programs let command = config
.get(handler) .get("command")
.ok_or(err_msg(format!("'{}' is not a valid executable", handler))) .ok_or(err_msg("No 'command' found"))?
.map(|value| value.clone())? .as_str()
.ok_or(err_msg("'command' is not a string."))?;
Program::Command(command.to_owned())
}
handler => {
let programs = PROGRAMS.lock().unwrap();
let program = programs
.get(handler)
.ok_or(err_msg(format!("'{}' is not a valid executable", handler)))
.map(|value| value.clone())?;
Program::Exec(program)
}
}; };
let config = config.clone(); let config = config.clone();
Ok(Handler { config, exec }) Ok(Handler { config, program })
} }
pub fn run(&self, input: JsonValue) -> Result<JsonValue, Error> { pub fn run(&self, input: JsonValue) -> Result<JsonValue, Error> {
let config = { let config = {
@ -41,33 +57,51 @@ impl Handler {
String::from_utf8(buf).unwrap() String::from_utf8(buf).unwrap()
}; };
let mut child = Command::new(&self.exec) match &self.program {
.env("DIP_ROOT", "") Program::Command(ref cmd) => {
.arg("--config") // TODO: allow some kind of simple variable replacement
.arg(config) let output = Command::new("/bin/bash").arg("-c").arg(cmd).output()?;
.stdin(Stdio::piped()) if !output.status.success() {
.stdout(Stdio::piped()) // TODO: get rid of unwraps
.stderr(Stdio::piped()) return Err(err_msg(format!(
.spawn()?; "Command '{}' returned with a non-zero status code: {}\nstdout:\n{}\nstderr:\n{}",
{ cmd,
match child.stdin { output.status,
Some(ref mut stdin) => { String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()),
write!(stdin, "{}", input)?; String::from_utf8(output.stderr).unwrap_or_else(|_| String::new())
)));
} }
None => bail!("done fucked"), }
}; Program::Exec(ref path) => {
} let mut child = Command::new(&path)
let output = child.wait_with_output()?; .env("DIP_ROOT", "")
if !output.status.success() { .arg("--config")
// TODO: get rid of unwraps .arg(config)
return Err(err_msg(format!( .stdin(Stdio::piped())
"'{:?}' returned with a non-zero status code: {}\nstdout:\n{}\nstderr:\n{}", .stdout(Stdio::piped())
self.exec, .stderr(Stdio::piped())
output.status, .spawn()?;
String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()), {
String::from_utf8(output.stderr).unwrap_or_else(|_| String::new()) match child.stdin {
))); Some(ref mut stdin) => {
} write!(stdin, "{}", input)?;
}
None => bail!("done fucked"),
};
}
let output = child.wait_with_output()?;
if !output.status.success() {
// TODO: get rid of unwraps
return Err(err_msg(format!(
"'{:?}' returned with a non-zero status code: {}\nstdout:\n{}\nstderr:\n{}",
path,
output.status,
String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()),
String::from_utf8(output.stderr).unwrap_or_else(|_| String::new())
)));
}
}
};
Ok(json!({})) Ok(json!({}))
} }
} }