summaryrefslogtreecommitdiff
path: root/lib/gitlab_custom_hook.rb
diff options
context:
space:
mode:
authorjkbzh <jkgh@w3.org>2014-11-06 03:01:29 +0100
committerDrew Blessing <drew.blessing@me.com>2014-11-06 13:25:52 -0600
commitb6d84f628489ebb6b8915dfa4808c552fe8e267b (patch)
treeed5f44fa244d95ded39d70ab2691c3709868f272 /lib/gitlab_custom_hook.rb
parent3ef7cdf9f94035da5640a585b8c49b0693af2090 (diff)
downloadgitlab-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.rb55
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)