BigW Consortium Gitlab

push_data_builder.rb 3.59 KB
Newer Older
1 2
module Gitlab
  class PushDataBuilder
3 4 5 6 7 8 9 10 11
    class << self
      # Produce a hash of post-receive data
      #
      # data = {
      #   before: String,
      #   after: String,
      #   ref: String,
      #   user_id: String,
      #   user_name: String,
12
      #   user_email: String
13 14 15 16 17 18 19 20
      #   project_id: String,
      #   repository: {
      #     name: String,
      #     url: String,
      #     description: String,
      #     homepage: String,
      #   },
      #   commits: Array,
21 22 23 24
      #   total_commits_count: Fixnum,
      #   added: ["CHANGELOG"],
      #   modified: [],
      #   removed: ["tmp/file.txt"]
25 26
      # }
      #
27
      def build(project, user, oldrev, newrev, ref, commits = [], message = nil)
28 29
        # Total commits count
        commits_count = commits.size
30

31 32
        # Get latest 20 commits ASC
        commits_limited = commits.last(20)
33

34 35
        # For performance purposes maximum 20 latest commits
        # will be passed as post receive hook data.
36
        commit_attrs = commits_limited.map(&:hook_attrs)
37

38
        type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push"
39 40

        repo_changes = repo_changes(project, newrev, oldrev)
41 42
        # Hash to be passed as post_receive_data
        data = {
43
          object_kind: type,
44 45 46 47
          before: oldrev,
          after: newrev,
          ref: ref,
          checkout_sha: checkout_sha(project.repository, newrev, ref),
48
          message: message,
49 50
          user_id: user.id,
          user_name: user.name,
51
          user_email: user.email,
52 53 54 55 56 57
          project_id: project.id,
          repository: {
            name: project.name,
            url: project.url_to_repo,
            description: project.description,
            homepage: project.web_url,
58 59 60
            git_http_url: project.http_url_to_repo,
            git_ssh_url: project.ssh_url_to_repo,
            visibility_level: project.visibility_level
61
          },
62
          commits: commit_attrs,
63 64 65 66
          total_commits_count: commits_count,
          added: repo_changes[:added],
          modified: repo_changes[:modified],
          removed: repo_changes[:removed]
67
        }
68

69
        data
70 71
      end

72 73 74 75
      # This method provide a sample data generated with
      # existing project and commits to test web hooks
      def build_sample(project, user)
        commits = project.repository.commits(project.default_branch, nil, 3)
76 77
        ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{project.default_branch}"
        build(project, user, commits.last.id, commits.first.id, ref, commits)
78
      end
79

80
      def checkout_sha(repository, newrev, ref)
81 82 83
        # Checkout sha is nil when we remove branch or tag
        return if Gitlab::Git.blank_ref?(newrev)

84
        # Find sha for tag, except when it was deleted.
85
        if Gitlab::Git.tag_ref?(ref)
86
          tag_name = Gitlab::Git.ref_name(ref)
87
          tag = repository.find_tag(tag_name)
88 89 90 91 92

          if tag
            commit = repository.commit(tag.target)
            commit.try(:sha)
          end
93 94 95 96
        else
          newrev
        end
      end
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

      def repo_changes(project, newrev, oldrev)
        changes = { added: [], modified: [], removed: [] }
        compare_result = CompareService.new.
          execute(project, newrev, project, oldrev)

        if compare_result
          compare_result.diffs.each do |diff|
            case true
            when diff.deleted_file
              changes[:removed] << diff.old_path
            when diff.renamed_file, diff.new_file
              changes[:added] << diff.new_path
            else
              changes[:modified] << diff.new_path
            end
          end
        end

        changes
      end
118 119 120
    end
  end
end