103 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# Gitaly note: JV: looks like this is only used by Gitlab::Git::HooksService in
 | 
						|
# app/services. We shouldn't bother migrating this until we know how
 | 
						|
# Gitlab::Git::HooksService will be migrated.
 | 
						|
 | 
						|
module Gitlab
 | 
						|
  module Git
 | 
						|
    class Hook
 | 
						|
      GL_PROTOCOL = 'web'.freeze
 | 
						|
      attr_reader :name, :path, :repository
 | 
						|
 | 
						|
      def initialize(name, repository)
 | 
						|
        @name = name
 | 
						|
        @repository = repository
 | 
						|
        @path = File.join(repo_path.strip, 'hooks', name)
 | 
						|
      end
 | 
						|
 | 
						|
      def repo_path
 | 
						|
        repository.path
 | 
						|
      end
 | 
						|
 | 
						|
      def exists?
 | 
						|
        File.exist?(path)
 | 
						|
      end
 | 
						|
 | 
						|
      def trigger(gl_id, gl_username, 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, gl_username, oldrev, newrev, ref)
 | 
						|
          when "update"
 | 
						|
            call_update_hook(gl_id, gl_username, oldrev, newrev, ref)
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      private
 | 
						|
 | 
						|
      def call_receive_hook(gl_id, gl_username, oldrev, newrev, ref)
 | 
						|
        changes = [oldrev, newrev, ref].join(" ")
 | 
						|
 | 
						|
        exit_status = false
 | 
						|
        exit_message = nil
 | 
						|
 | 
						|
        vars = {
 | 
						|
          'GL_ID' => gl_id,
 | 
						|
          'GL_USERNAME' => gl_username,
 | 
						|
          'PWD' => repo_path,
 | 
						|
          'GL_PROTOCOL' => GL_PROTOCOL,
 | 
						|
          'GL_REPOSITORY' => repository.gl_repository
 | 
						|
        }
 | 
						|
 | 
						|
        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, gl_username, oldrev, newrev, ref)
 | 
						|
        Dir.chdir(repo_path) do
 | 
						|
          env = {
 | 
						|
            'GL_ID' => gl_id,
 | 
						|
            'GL_USERNAME' => gl_username
 | 
						|
          }
 | 
						|
          stdout, stderr, status = Open3.capture3(env, path, ref, oldrev, newrev)
 | 
						|
          [status.success?, (stderr.presence || stdout).gsub(/\R/, "<br>").html_safe]
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      def retrieve_error_message(stderr, stdout)
 | 
						|
        err_message = stderr.read
 | 
						|
        err_message = err_message.blank? ? stdout.read : err_message
 | 
						|
        err_message.gsub(/\R/, "<br>").html_safe
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |