Format all code

This commit is contained in:
Michael Zhang 2020-11-02 18:02:52 -06:00
parent 92e5ab998e
commit 9ae78d506e
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
7 changed files with 106 additions and 79 deletions

2
rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
max_width = 80
wrap_comments = true

View file

@ -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<String>,
}
@ -44,7 +45,8 @@ where
P: AsRef<Path>,
{
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
),
}
}
}

View file

@ -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")

View file

@ -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<JsonValue, Error>),
Builtin(
fn(&Environment, &TomlValue, &JsonValue) -> Result<JsonValue, Error>,
),
/// 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<dyn Future<Item = JsonValue, Error = Error> + 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<dyn Future<Item = JsonValue, Error = Error> + 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))
}
}

View file

@ -20,7 +20,10 @@ pub struct Hook {
impl Hook {
/// Creates a hook from a (name, config) pair.
pub fn from(name: impl Into<String>, config: &Value) -> Result<Self, Error> {
pub fn from(
name: impl Into<String>,
config: &Value,
) -> Result<Self, Error> {
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<String, String> {
pub(crate) fn handle(
&self,
req: JsonValue,
temp_path: PathBuf,
) -> Result<String, String> {
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);
});

View file

@ -58,11 +58,12 @@ use crate::service::*;
const URIPATTERN_STR: &str = r"/webhook/(?P<name>[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<Mutex<HashMap<String, PathBuf>>> =
Arc::new(Mutex::new(HashMap::new()));
static ref HOOKS: Arc<Mutex<HashMap<String, Hook>>> = Arc::new(Mutex::new(HashMap::new()));
static ref HOOKS: Arc<Mutex<HashMap<String, Hook>>> =
Arc::new(Mutex::new(HashMap::new()));
}
/// Main entry point of the entire application.

View file

@ -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::<HashMap<_, _>>();
})
.collect::<HashMap<_, _>>();
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)))
})
}
}))
}