diff options
author | Rémy Coutable <remy@rymai.me> | 2016-12-06 16:43:29 +0000 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2016-12-06 16:43:29 +0000 |
commit | e1b0aca197cb61a4ee33b8de37b79c57bb3369ad (patch) | |
tree | cf0170fc1b87fd4f4d28ec2e9860febcd9d89d78 /lib/gitlab_custom_hook.rb | |
parent | d4f2f5bae9808dd08b67f04cf928dab3a5f04f13 (diff) | |
parent | b77f6530b96c520ef8637ceba4ef2889a008d383 (diff) | |
download | gitlab-shell-e1b0aca197cb61a4ee33b8de37b79c57bb3369ad.tar.gz |
Merge branch 'glensc/gitlab-shell-pr-245' into 'master'
Chained global hooks
Closes #32. Docs MR: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6721
See merge request !111
Diffstat (limited to 'lib/gitlab_custom_hook.rb')
-rw-r--r-- | lib/gitlab_custom_hook.rb | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/lib/gitlab_custom_hook.rb b/lib/gitlab_custom_hook.rb index 25385cf..a48ad12 100644 --- a/lib/gitlab_custom_hook.rb +++ b/lib/gitlab_custom_hook.rb @@ -5,29 +5,33 @@ require_relative 'gitlab_metrics' class GitlabCustomHook attr_reader :vars - def initialize(key_id) + def initialize(repo_path, key_id) + @repo_path = repo_path @vars = { 'GL_ID' => key_id } end - def pre_receive(changes, repo_path) - hook = hook_file('pre-receive', repo_path) - return true if hook.nil? - - GitlabMetrics.measure("pre-receive-hook") { call_receive_hook(hook, changes) } + def pre_receive(changes) + GitlabMetrics.measure("pre-receive-hook") do + find_hooks('pre-receive').all? do |hook| + call_receive_hook(hook, changes) + end + end end - def post_receive(changes, repo_path) - hook = hook_file('post-receive', repo_path) - return true if hook.nil? - - GitlabMetrics.measure("post-receive-hook") { call_receive_hook(hook, changes) } + def post_receive(changes) + GitlabMetrics.measure("post-receive-hook") do + find_hooks('post-receive').all? do |hook| + call_receive_hook(hook, changes) + end + end end - def update(ref_name, old_value, new_value, repo_path) - hook = hook_file('update', repo_path) - return true if hook.nil? - - GitlabMetrics.measure("update-hook") { system(vars, hook, ref_name, old_value, new_value) } + def update(ref_name, old_value, new_value) + GitlabMetrics.measure("update-hook") do + find_hooks('update').all? do |hook| + system(vars, hook, ref_name, old_value, new_value) + end + end end private @@ -53,9 +57,40 @@ class GitlabCustomHook $?.success? end - def hook_file(hook_type, repo_path) - hook_path = File.join(repo_path.strip, 'custom_hooks') - hook_file = "#{hook_path}/#{hook_type}" - hook_file if File.exist?(hook_file) + # lookup hook files in this order: + # + # 1. <repository>.git/custom_hooks/<hook_name> - per project hook + # 2. <repository>.git/custom_hooks/<hook_name>.d/* - per project hooks + # 3. <repository>.git/hooks/<hook_name>.d/* - global hooks + # + def find_hooks(hook_name) + hook_files = [] + + # <repository>.git/custom_hooks/<hook_name> + hook_file = File.join(@repo_path, 'custom_hooks', hook_name) + hook_files.push(hook_file) if File.executable?(hook_file) + + # <repository>.git/custom_hooks/<hook_name>.d/* + hook_path = File.join(@repo_path, 'custom_hooks', "#{hook_name}.d") + hook_files += match_hook_files(hook_path) + + # <repository>.git/hooks/<hook_name>.d/* + hook_path = File.join(@repo_path, 'hooks', "#{hook_name}.d") + hook_files += match_hook_files(hook_path) + + hook_files + end + + # match files from path: + # 1. file must be executable + # 2. file must not match backup file + # + # the resulting list is sorted + def match_hook_files(path) + return [] unless Dir.exist?(path) + + Dir["#{path}/*"].select do |f| + !f.end_with?('~') && File.executable?(f) + end.sort end end |