Skip to content
Snippets Groups Projects
Select Git revision
  • move-gl-dropdown
  • improve-table-pagination-spec
  • move-markdown-preview
  • winh-fix-merge-request-spec
  • master default
  • index-namespaces-lower-name
  • winh-single-karma-test
  • 10-3-stable
  • 36782-replace-team-user-role-with-add_role-user-in-specs
  • winh-modal-internal-state
  • tz-ide-file-icons
  • 38869-milestone-select
  • update-autodevops-template
  • jivl-activate-repo-cookie-preferences
  • qa-add-deploy-key
  • docs-move-article-ldap
  • 40780-choose-file
  • 22643-manual-job-page
  • refactor-cluster-show-page-conservative
  • dm-sidekiq-versioning
  • v10.4.0.pre
  • v10.3.0
  • v10.3.0-rc5
  • v10.3.0-rc4
  • v10.3.0-rc3
  • v10.3.0-rc2
  • v10.2.5
  • v10.3.0-rc1
  • v10.0.7
  • v10.1.5
  • v10.2.4
  • v10.2.3
  • v10.2.2
  • v10.2.1
  • v10.3.0.pre
  • v10.2.0
  • v10.2.0-rc4
  • v10.2.0-rc3
  • v10.1.4
  • v10.2.0-rc2
40 results

hook.rb

Forked from GitLab.org / GitLab FOSS
20757 commits behind the upstream repository.
hook.rb 2.04 KiB
module Gitlab
  module Git
    class Hook
      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 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' => 'web'
        }

        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)
        status = nil

        Dir.chdir(repo_path) do
          status = system({ 'GL_ID' => gl_id }, path, ref, oldrev, newrev)
        end

        [status, nil]
      end

      def retrieve_error_message(stderr, stdout)
        err_message = stderr.gets
        err_message.blank? ? stdout.gets : err_message
      end
    end
  end
end