Commit b6d84f62 authored by jkbzh's avatar jkbzh Committed by Drew Blessing

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
parent 3ef7cdf9
require 'open3'
class GitlabCustomHook class GitlabCustomHook
def pre_receive(refs, repo_path) def pre_receive(changes, repo_path)
if receive('pre-receive', refs, repo_path) hook = hook_file('pre-receive', repo_path)
return true if hook.nil?
if call_receive_hook(hook, changes)
return true return true
else else
# reset GL_ID env since we stop git push here # reset GL_ID env since we stop git push here
...@@ -9,29 +13,52 @@ class GitlabCustomHook ...@@ -9,29 +13,52 @@ class GitlabCustomHook
end end
end end
def post_receive(refs, repo_path) def post_receive(changes, repo_path)
receive('post-receive', refs, repo_path) hook = hook_file('post-receive', repo_path)
return true if hook.nil?
call_receive_hook(hook, changes) ? true : false
end end
def update(ref_name, old_value, new_value, repo_path) def update(ref_name, old_value, new_value, repo_path)
hook = hook_file('update', repo_path) hook = hook_file('update', repo_path)
return true if hook.nil? 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 end
private private
def receive(type, refs, repo_path) def call_receive_hook(hook, changes)
unless type == 'pre-receive' || type == 'post-receive' # function will return true if succesful
puts 'GitLab: An unexpected error occurred ' \ exit_status = false
'(invalid pre/post-receive hook type)'
return 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 end
hook = hook_file(type, repo_path) exit_status
return true if hook.nil?
cmd = "#{hook} #{refs}"
system(*cmd) ? true : false
end end
def hook_file(hook_type, repo_path) def hook_file(hook_type, repo_path)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment