88 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.2 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?
 | |
| 
 | |
|         Bundler.with_clean_env do
 | |
|           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
 | |
|       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
 |