diff options
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) |