diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..3450fc4 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 80 +wrap_comments = true diff --git a/src/config.rs b/src/config.rs index 97c98af..6f40447 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,11 +19,12 @@ pub struct Config { /// The root configuration directory for dip. This argument is required. #[structopt(short = "d", long = "root", parse(from_os_str))] pub root: PathBuf, - /// A string containing the address to bind to. This defaults to "0.0.0.0:5000". + /// A string containing the address to bind to. This defaults to + /// "0.0.0.0:5000". #[structopt(short = "b", long = "bind", default_value = "0.0.0.0:5000")] pub bind: String, - /// If a hook is specified here, it will be triggered manually exactly once and then the - /// program will exit rather than running as a server. + /// If a hook is specified here, it will be triggered manually exactly once + /// and then the program will exit rather than running as a server. #[structopt(short = "h", long = "hook")] pub hook: Option, } @@ -44,7 +45,8 @@ where P: AsRef, { let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(1))?; + let mut watcher: RecommendedWatcher = + Watcher::new(tx, Duration::from_secs(1))?; println!("Watching {:?}", root.as_ref().to_path_buf()); watcher.watch(root.as_ref(), RecursiveMode::Recursive)?; loop { @@ -135,7 +137,10 @@ where })(path) { Ok(_) => (), - Err(err) => eprintln!("Failed to read config from {:?}: {}", path, err), + Err(err) => eprintln!( + "Failed to read config from {:?}: {}", + path, err + ), } } } diff --git a/src/github.rs b/src/github.rs index a57daef..d1fd074 100644 --- a/src/github.rs +++ b/src/github.rs @@ -97,8 +97,8 @@ pub(crate) fn main( ); } - let payload: GithubPayload = - serde_json::from_str(&payload.body).expect("Could not parse Github input into json"); + let payload: GithubPayload = serde_json::from_str(&payload.body) + .expect("Could not parse Github input into json"); let mut target_path = env.workdir.clone(); target_path.push(&config.path); Command::new("git") diff --git a/src/handler.rs b/src/handler.rs index e5f781d..37ecd38 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -26,10 +26,13 @@ pub struct Handler { #[derive(Clone)] pub enum Action { /// A builtin function (for example, the Github handler). - Builtin(fn(&Environment, &TomlValue, &JsonValue) -> Result), + Builtin( + fn(&Environment, &TomlValue, &JsonValue) -> Result, + ), /// A command represents a string to be executed by `bash -c`. Command(String), - /// A program represents one of the handlers specified in the `handlers` directory. + /// A program represents one of the handlers specified in the `handlers` + /// directory. Program(String), } @@ -99,69 +102,72 @@ impl Handler { .stderr(Stdio::piped()); }; - let output: Box + Send> = match action { - Action::Builtin(ref func) => { - let workdir = temp_path_cp.clone(); - let env = Environment { workdir }; - let result = func(&env, &config, &input); - Box::new(future::result(result)) - } - Action::Command(ref cmd) => { - // TODO: allow some kind of simple variable replacement - let mut command = Command::new("/bin/bash"); - command_helper(&mut command); - let child = command.arg("-c").arg(cmd); - let result = child - .output_async() - .map_err(|err| err_msg(format!("failed to spawn child: {}", err))) - .and_then(|output| { - let stdout = - String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()); - let stderr = - String::from_utf8(output.stderr).unwrap_or_else(|_| String::new()); - future::ok(json!({ - "stdout": stdout, - "stderr": stderr, - })) - }); - Box::new(result) - } - Action::Program(ref path) => { - let mut command = Command::new(&path); - command_helper(&mut command); - let mut child = command - .arg("--config") - .arg(config_str) - .spawn_async() - .expect("could not spawn child"); - - let stdin = child.stdin().take().unwrap(); - - let input = format!("{}", input); - let result = write_all(stdin, input) - .and_then(|_| child.wait_with_output()) - .map_err(|err| err_msg(format!("error: {}", err))) - .and_then(|output| { - let stdout = - String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()); - let stderr = - String::from_utf8(output.stderr).unwrap_or_else(|_| String::new()); - if output.status.success() { - Either::A(future::ok(json!({ + let output: Box + Send> = + match action { + Action::Builtin(ref func) => { + let workdir = temp_path_cp.clone(); + let env = Environment { workdir }; + let result = func(&env, &config, &input); + Box::new(future::result(result)) + } + Action::Command(ref cmd) => { + // TODO: allow some kind of simple variable replacement + let mut command = Command::new("/bin/bash"); + command_helper(&mut command); + let child = command.arg("-c").arg(cmd); + let result = child + .output_async() + .map_err(|err| { + err_msg(format!("failed to spawn child: {}", err)) + }) + .and_then(|output| { + let stdout = String::from_utf8(output.stdout) + .unwrap_or_else(|_| String::new()); + let stderr = String::from_utf8(output.stderr) + .unwrap_or_else(|_| String::new()); + future::ok(json!({ "stdout": stdout, "stderr": stderr, - }))) - } else { - Either::B(future::err(err_msg(format!( - "Failed, stdout: '{}', stderr: '{}'", - stdout, stderr - )))) - } - }); + })) + }); + Box::new(result) + } + Action::Program(ref path) => { + let mut command = Command::new(&path); + command_helper(&mut command); + let mut child = command + .arg("--config") + .arg(config_str) + .spawn_async() + .expect("could not spawn child"); - Box::new(result) - } - }; + let stdin = child.stdin().take().unwrap(); + + let input = format!("{}", input); + let result = write_all(stdin, input) + .and_then(|_| child.wait_with_output()) + .map_err(|err| err_msg(format!("error: {}", err))) + .and_then(|output| { + let stdout = String::from_utf8(output.stdout) + .unwrap_or_else(|_| String::new()); + let stderr = String::from_utf8(output.stderr) + .unwrap_or_else(|_| String::new()); + if output.status.success() { + Either::A(future::ok(json!({ + "stdout": stdout, + "stderr": stderr, + }))) + } else { + Either::B(future::err(err_msg(format!( + "Failed, stdout: '{}', stderr: '{}'", + stdout, stderr + )))) + } + }); + + Box::new(result) + } + }; output.map(|x| (temp_path_cp, x)) } } diff --git a/src/hook.rs b/src/hook.rs index d5ff322..e68c06b 100644 --- a/src/hook.rs +++ b/src/hook.rs @@ -20,7 +20,10 @@ pub struct Hook { impl Hook { /// Creates a hook from a (name, config) pair. - pub fn from(name: impl Into, config: &Value) -> Result { + pub fn from( + name: impl Into, + config: &Value, + ) -> Result { let name = name.into(); let handlers = config .get("handlers") @@ -59,7 +62,11 @@ impl Hook { self.name.clone() } - pub(crate) fn handle(&self, req: JsonValue, temp_path: PathBuf) -> Result { + pub(crate) fn handle( + &self, + req: JsonValue, + temp_path: PathBuf, + ) -> Result { let handlers = self .handlers .iter() @@ -68,7 +75,8 @@ impl Hook { let st = stream::iter_ok::<_, Error>(handlers.into_iter()) .fold((temp_path, req), |(path, prev), (config, action)| { Handler::run(config, action, path, prev) - }).map(|_| ()) + }) + .map(|_| ()) .map_err(|err: Error| { println!("Error from stream: {}", err); }); diff --git a/src/lib.rs b/src/lib.rs index aa901e2..32a16ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,11 +58,12 @@ use crate::service::*; const URIPATTERN_STR: &str = r"/webhook/(?P[A-Za-z._][A-Za-z0-9._]*)"; lazy_static! { - static ref URIPATTERN: Regex = - Regex::new(URIPATTERN_STR).expect("Could not compile regular expression."); + static ref URIPATTERN: Regex = Regex::new(URIPATTERN_STR) + .expect("Could not compile regular expression."); static ref PROGRAMS: Arc>> = Arc::new(Mutex::new(HashMap::new())); - static ref HOOKS: Arc>> = Arc::new(Mutex::new(HashMap::new())); + static ref HOOKS: Arc>> = + Arc::new(Mutex::new(HashMap::new())); } /// Main entry point of the entire application. diff --git a/src/service.rs b/src/service.rs index 18dba54..ceb10f0 100644 --- a/src/service.rs +++ b/src/service.rs @@ -42,14 +42,15 @@ pub(crate) fn dip_service( .filter_map(|(k, v)| { let key = k.unwrap().as_str().to_owned(); v.to_str().map(|value| (key, value.to_owned())).ok() - }).collect::>(); + }) + .collect::>(); let method = req.method().as_str().to_owned(); // spawn job Box::new(req.into_body().concat2().map(move |body| { let body = String::from_utf8(body.to_vec()).unwrap(); let req_obj = json!({ - "body": body, + "body": body, "headers": headers, "method": method, }); @@ -66,7 +67,9 @@ pub(crate) fn dip_service( return Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("not found")) - .unwrap_or_else(|_| Response::new(Body::from("not found"))); + .unwrap_or_else(|_| { + Response::new(Body::from("not found")) + }); } }; let (code, msg) = match hook.handle(req_obj, temp_path) { @@ -78,7 +81,9 @@ pub(crate) fn dip_service( Response::builder() .status(code) .body(Body::from(msg)) - .unwrap_or_else(|err| Response::new(Body::from(format!("{}", err)))) + .unwrap_or_else(|err| { + Response::new(Body::from(format!("{}", err))) + }) } })) }