From ccf594d858b19fbd4265a1cd65011ecf6d8b74df Mon Sep 17 00:00:00 2001 From: Tim Fox Date: Thu, 5 Jul 2018 03:06:36 -0700 Subject: [PATCH] Update repoconfig and hookloader to support per file hooks Summary: This diff updates rep config to support per file hooks. We also extend the hookloader to support per file hooks. Reviewed By: lukaspiatkowski Differential Revision: D8713464 fbshipit-source-id: 65cf20957506adc620bf06d84707669d125366ed --- hooks/src/hook_loader.rs | 15 +++++++++++--- metaconfig/src/repoconfig.rs | 40 ++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/hooks/src/hook_loader.rs b/hooks/src/hook_loader.rs index 4c220163c8..56deb9e91c 100644 --- a/hooks/src/hook_loader.rs +++ b/hooks/src/hook_loader.rs @@ -11,7 +11,7 @@ use super::HookManager; use super::lua_hook::LuaHook; use failure::Error; -use metaconfig::repoconfig::RepoConfig; +use metaconfig::repoconfig::{HookType, RepoConfig}; use std::collections::HashSet; use std::sync::Arc; @@ -21,8 +21,13 @@ pub fn load_hooks(hook_manager: &mut HookManager, config: RepoConfig) -> Result< let mut hook_set = HashSet::new(); for hook in hooks { let name = hook.name; - let hook = LuaHook::new(name.clone(), hook.code.clone()); - hook_manager.register_changeset_hook(&name, Arc::new(hook)); + let lua_hook = LuaHook::new(name.clone(), hook.code.clone()); + match hook.hook_type { + HookType::PerFile => hook_manager.register_file_hook(&name, Arc::new(lua_hook)), + HookType::PerChangeset => { + hook_manager.register_changeset_hook(&name, Arc::new(lua_hook)) + } + } hook_set.insert(name); } match config.bookmarks { @@ -86,14 +91,17 @@ mod test { HookParams { name: "hook1".into(), code: "hook1 code".into(), + hook_type: HookType::PerFile, }, HookParams { name: "hook2".into(), code: "hook2 code".into(), + hook_type: HookType::PerFile, }, HookParams { name: "hook3".into(), code: "hook3 code".into(), + hook_type: HookType::PerChangeset, }, ]), }; @@ -126,6 +134,7 @@ mod test { HookParams { name: "hook1".into(), code: "hook1 code".into(), + hook_type: HookType::PerFile, }, ]), }; diff --git a/metaconfig/src/repoconfig.rs b/metaconfig/src/repoconfig.rs index 96e86c6098..5bfa2f7434 100644 --- a/metaconfig/src/repoconfig.rs +++ b/metaconfig/src/repoconfig.rs @@ -65,11 +65,22 @@ pub struct BookmarkParams { pub hooks: Option>, } +/// The type of the hook +#[derive(Debug, Clone, Eq, PartialEq, Deserialize)] +pub enum HookType { + /// A hook that runs on the whole changeset + PerChangeset, + /// A hook that runs on a file in a changeset + PerFile, +} + /// Configuration for a hook #[derive(Debug, Clone, Eq, PartialEq)] pub struct HookParams { /// The name of the hook pub name: String, + /// The type of the hook + pub hook_type: HookType, /// The code of the hook pub code: String, } @@ -194,15 +205,15 @@ impl RepoConfigs { let hooks = raw_config.hooks.clone(); // Easier to deal with empty vector than Option let hooks = hooks.unwrap_or(Vec::new()); - future::join_all(hooks.into_iter().map(move |raw_hook_config| { let path = raw_hook_config.path.clone(); - let is_relative = path.starts_with("./"); + let relative_prefix = "./"; + let is_relative = path.starts_with(relative_prefix); let path_node; let path_adjusted; if is_relative { path_node = repo_dir.clone().into_node(); - path_adjusted = path.chars().skip(2).collect(); + path_adjusted = path.chars().skip(relative_prefix.len()).collect(); } else { path_node = root_node.clone(); path_adjusted = path; @@ -210,16 +221,14 @@ impl RepoConfigs { RepoConfigs::read_file( path_node, try_boxfuture!(MPath::new(path_adjusted.as_bytes().to_vec())), - ).then(|res| match res { - Ok(bytes) => { - let code = str::from_utf8(&bytes)?; - let code = code.to_string(); - Ok(HookParams { - name: raw_hook_config.name, - code, - }) - } - Err(e) => Err(e), + ).and_then(|bytes| { + let code = str::from_utf8(&bytes)?; + let code = code.to_string(); + Ok(HookParams { + name: raw_hook_config.name, + code, + hook_type: raw_hook_config.hook_type, + }) }) .boxify() })).map(|hook_params| (raw_config, hook_params)) @@ -382,6 +391,7 @@ struct RawBookmarkHook { struct RawHookConfig { name: String, path: String, + hook_type: HookType, } /// Types of repositories supported @@ -422,9 +432,11 @@ mod test { [[hooks]] name="hook1" path="common/hooks/hook1.lua" + hook_type="PerFile" [[hooks]] name="hook2" path="./hooks/hook2.lua" + hook_type="PerChangeset" "#; let www_content = r#" path="/tmp/www" @@ -468,10 +480,12 @@ mod test { HookParams { name: "hook1".to_string(), code: "this is hook1".to_string(), + hook_type: HookType::PerFile, }, HookParams { name: "hook2".to_string(), code: "this is hook2".to_string(), + hook_type: HookType::PerChangeset, }, ]), },