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
This commit is contained in:
Tim Fox 2018-07-05 03:06:36 -07:00 committed by Facebook Github Bot
parent c6009ab467
commit ccf594d858
2 changed files with 39 additions and 16 deletions

View File

@ -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,
},
]),
};

View File

@ -65,11 +65,22 @@ pub struct BookmarkParams {
pub hooks: Option<Vec<String>>,
}
/// 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,
},
]),
},