summaryrefslogtreecommitdiff
path: root/lib/gitlab/email/message/repository_push.rb
blob: ec412e7a8b1fd6008a105f498f998345b47e45e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# frozen_string_literal: true

module Gitlab
  module Email
    module Message
      class RepositoryPush
        attr_reader :author_id, :ref, :action

        include Gitlab::Routing
        include DiffHelper

        delegate :namespace, :name_with_namespace, to: :project, prefix: :project
        delegate :name, to: :author, prefix: :author
        delegate :username, to: :author, prefix: :author

        def initialize(notify, project_id, opts = {})
          raise ArgumentError, 'Missing options: author_id, ref, action' unless
            opts[:author_id] && opts[:ref] && opts[:action]

          @notify = notify
          @project_id = project_id
          @opts = opts.dup

          @author_id = @opts.delete(:author_id)
          @ref = @opts.delete(:ref)
          @action = @opts.delete(:action)
        end

        def project
          @project ||= Project.find(@project_id)
        end

        def author
          @author ||= User.find(@author_id)
        end

        def commits
          return unless compare

          @commits ||= compare.commits
        end

        def diffs
          return unless compare

          # This diff is more moderated in number of files and lines
          @diffs ||= compare.diffs(max_files: 30, max_lines: 5000, expanded: true).diff_files
        end

        def diffs_count
          diffs&.size
        end

        def compare
          @opts[:compare] if @opts[:compare]
        end

        def diff_refs
          @opts[:diff_refs]
        end

        def compare_timeout
          diffs&.overflow?
        end

        def reverse_compare?
          @opts[:reverse_compare] || false
        end

        def disable_diffs?
          @opts[:disable_diffs] || false
        end

        def send_from_committer_email?
          @opts[:send_from_committer_email] || false
        end

        def action_name
          @action_name ||=
            case @action
            when :create
              'pushed new'
            when :delete
              'deleted'
            else
              'pushed to'
            end
        end

        def ref_name
          @ref_name ||= Gitlab::Git.ref_name(@ref)
        end

        def ref_type
          @ref_type ||= Gitlab::Git.tag_ref?(@ref) ? 'tag' : 'branch'
        end

        def target_url
          if @action == :push && commits
            if commits.length > 1
              project_compare_url(project, from: compare.start_commit, to: compare.head_commit)
            else
              project_commit_url(project, commits.first)
            end
          else
            unless @action == :delete
              project_tree_url(project, ref_name)
            end
          end
        end

        def reply_to
          if send_from_committer_email? && @notify.can_send_from_user_email?(author)
            author.email
          else
            Gitlab.config.gitlab.email_reply_to
          end
        end

        def subject
          subject_text = ['[Git]']
          subject_text << "[#{project.full_path}]"
          subject_text << "[#{ref_name}]" if @action == :push
          subject_text << ' '

          if @action == :push && commits
            if commits.length > 1
              subject_text << "Deleted " if reverse_compare?
              subject_text << "#{commits.length} commits: #{commits.first.title}"
            else
              subject_text << "Deleted 1 commit: " if reverse_compare?
              subject_text << commits.first.title
            end
          else
            subject_action = action_name.dup
            subject_action[0] = subject_action[0].capitalize
            subject_text << "#{subject_action} #{ref_type} #{ref_name}"
          end

          subject_text.join
        end
      end
    end
  end
end