diff options
author | jkbzh <jkgh@w3.org> | 2014-11-06 03:01:29 +0100 |
---|---|---|
committer | Drew Blessing <drew.blessing@me.com> | 2014-11-06 13:25:52 -0600 |
commit | b6d84f628489ebb6b8915dfa4808c552fe8e267b (patch) | |
tree | ed5f44fa244d95ded39d70ab2691c3709868f272 /lib/gitlab_custom_hook.rb | |
parent | 3ef7cdf9f94035da5640a585b8c49b0693af2090 (diff) | |
download | gitlab-shell-b6d84f628489ebb6b8915dfa4808c552fe8e267b.tar.gz |
Fix the calls to pre- and post-receive custom hooks
- Reset G_ID if the custom pre-receive hook fails
- Use a pipe to feed stdin to the custom pre- and post-receive
hooks, in the same way that the standalone git works
Diffstat (limited to 'lib/gitlab_custom_hook.rb')
-rw-r--r-- | lib/gitlab_custom_hook.rb | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lib/gitlab_custom_hook.rb b/lib/gitlab_custom_hook.rb index d6fa83d..ba11e29 100644 --- a/lib/gitlab_custom_hook.rb +++ b/lib/gitlab_custom_hook.rb @@ -1,6 +1,10 @@ +require 'open3' + class GitlabCustomHook - def pre_receive(refs, repo_path) - if receive('pre-receive', refs, repo_path) + 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 @@ -9,29 +13,52 @@ class GitlabCustomHook end end - def post_receive(refs, repo_path) - receive('post-receive', refs, repo_path) + 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 + system(hook, ref_name, old_value, new_value) ? true : false end private - def receive(type, refs, repo_path) - unless type == 'pre-receive' || type == 'post-receive' - puts 'GitLab: An unexpected error occurred ' \ - '(invalid pre/post-receive hook type)' - return false + 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 - hook = hook_file(type, repo_path) - return true if hook.nil? - cmd = "#{hook} #{refs}" - system(*cmd) ? true : false + exit_status end def hook_file(hook_type, repo_path) |