85 lines
2.1 KiB
Ruby
85 lines
2.1 KiB
Ruby
module Gitlab
|
|
module Git
|
|
class Hook
|
|
GL_PROTOCOL = 'web'.freeze
|
|
attr_reader :name, :repo_path, :path
|
|
|
|
def initialize(name, repo_path)
|
|
@name = name
|
|
@repo_path = repo_path
|
|
@path = File.join(repo_path.strip, 'hooks', name)
|
|
end
|
|
|
|
def exists?
|
|
File.exist?(path)
|
|
end
|
|
|
|
def trigger(gl_id, oldrev, newrev, ref)
|
|
return [true, nil] unless exists?
|
|
|
|
case name
|
|
when "pre-receive", "post-receive"
|
|
call_receive_hook(gl_id, oldrev, newrev, ref)
|
|
when "update"
|
|
call_update_hook(gl_id, oldrev, newrev, ref)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def call_receive_hook(gl_id, oldrev, newrev, ref)
|
|
changes = [oldrev, newrev, ref].join(" ")
|
|
|
|
exit_status = false
|
|
exit_message = nil
|
|
|
|
vars = {
|
|
'GL_ID' => gl_id,
|
|
'PWD' => repo_path,
|
|
'GL_PROTOCOL' => GL_PROTOCOL
|
|
}
|
|
|
|
options = {
|
|
chdir: repo_path
|
|
}
|
|
|
|
Open3.popen3(vars, path, options) 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
|
|
|
|
stdin.close
|
|
|
|
unless wait_thr.value == 0
|
|
exit_status = false
|
|
exit_message = retrieve_error_message(stderr, stdout)
|
|
end
|
|
end
|
|
|
|
[exit_status, exit_message]
|
|
end
|
|
|
|
def call_update_hook(gl_id, oldrev, newrev, ref)
|
|
Dir.chdir(repo_path) do
|
|
stdout, stderr, status = Open3.capture3({ 'GL_ID' => gl_id }, path, ref, oldrev, newrev)
|
|
[status.success?, stderr.presence || stdout]
|
|
end
|
|
end
|
|
|
|
def retrieve_error_message(stderr, stdout)
|
|
err_message = stderr.gets
|
|
err_message.blank? ? stdout.gets : err_message
|
|
end
|
|
end
|
|
end
|
|
end
|