diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-11-07 15:19:03 +0200 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-11-07 15:19:03 +0200 |
commit | ff9808c0f24ed562d6bacd1061f0f8e30a3452f3 (patch) | |
tree | ed5f44fa244d95ded39d70ab2691c3709868f272 /lib/gitlab_custom_hook.rb | |
parent | 00b3d2cb7095af3859734c88a7797182e598f047 (diff) | |
parent | b6d84f628489ebb6b8915dfa4808c552fe8e267b (diff) | |
download | gitlab-shell-ff9808c0f24ed562d6bacd1061f0f8e30a3452f3.tar.gz |
Merge pull request #190 from dblessing/feature/custom_hooks
Custom hooks
Diffstat (limited to 'lib/gitlab_custom_hook.rb')
-rw-r--r-- | lib/gitlab_custom_hook.rb | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/gitlab_custom_hook.rb b/lib/gitlab_custom_hook.rb new file mode 100644 index 0000000..ba11e29 --- /dev/null +++ b/lib/gitlab_custom_hook.rb @@ -0,0 +1,69 @@ +require 'open3' + +class GitlabCustomHook + def pre_receive(changes, repo_path) + hook = hook_file('pre-receive', repo_path) + return true if hook.nil? + if call_receive_hook(hook, changes) + return true + else + # reset GL_ID env since we stop git push here + ENV['GL_ID'] = nil + return false + end + end + + def post_receive(changes, repo_path) + hook = hook_file('post-receive', repo_path) + return true if hook.nil? + call_receive_hook(hook, changes) ? true : false + end + + def update(ref_name, old_value, new_value, repo_path) + hook = hook_file('update', repo_path) + return true if hook.nil? + system(hook, ref_name, old_value, new_value) ? true : false + end + + private + + def call_receive_hook(hook, changes) + # function will return true if succesful + exit_status = false + + # we combine both stdout and stderr as we don't know what stream + # will be used by the custom hook + Open3.popen2e (hook) do |stdin, stdout_stderr, wait_thr| + exit_status = true + stdin.sync = true + + # in git, pre- and post- receive hooks may just exit without + # reading stdin. We catch the exception to avoid a broken pipe + # warning + begin + # inject all the changes as stdin to the hook + changes.lines do |line| + stdin.puts (line) + end + rescue Errno::EPIPE + end + + # need to close stdin before reading stdout + stdin.close + + # only output stdut_stderr if scripts doesn't return 0 + unless wait_thr.value == 0 + exit_status = false + stdout_stderr.each_line { |line| puts line } + end + end + + exit_status + 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) + end +end |