summaryrefslogtreecommitdiff
path: root/app/services/push_event_payload_service.rb
blob: b0a389c85f9a4bc55e026e3538d9da3647ead08a (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
# Service class for creating push event payloads as stored in the
# "push_event_payloads" table.
#
# Example:
#
#     data = Gitlab::DataBuilder::Push.build(...)
#     event = Event.create(...)
#
#     PushEventPayloadService.new(event, data).execute
class PushEventPayloadService
  # event - The event this push payload belongs to.
  # push_data - A Hash produced by `Gitlab::DataBuilder::Push.build` to use for
  #             building the push payload.
  def initialize(event, push_data)
    @event = event
    @push_data = push_data
  end

  # Creates and returns a new PushEventPayload row.
  #
  # This method will raise upon encountering validation errors.
  #
  # Returns an instance of PushEventPayload.
  def execute
    @event.build_push_event_payload(
      commit_count: commit_count,
      action: action,
      ref_type: ref_type,
      commit_from: commit_from_id,
      commit_to: commit_to_id,
      ref: trimmed_ref,
      commit_title: commit_title,
      event_id: @event.id
    )

    @event.push_event_payload.save!
    @event.push_event_payload
  end

  # Returns the commit title to use.
  #
  # The commit title is limited to the first line and a maximum of 70
  # characters.
  def commit_title
    commit = @push_data.fetch(:commits).last

    return nil unless commit && commit[:message]

    raw_msg = commit[:message]

    # Find where the first line ends, without turning the entire message into an
    # Array of lines (this is a waste of memory for large commit messages).
    index = raw_msg.index("\n")
    message = index ? raw_msg[0..index] : raw_msg

    message.strip.truncate(70)
  end

  def commit_from_id
    if create?
      nil
    else
      revision_before
    end
  end

  def commit_to_id
    if remove?
      nil
    else
      revision_after
    end
  end

  def commit_count
    @push_data.fetch(:total_commits_count)
  end

  def ref
    @push_data.fetch(:ref)
  end

  def revision_before
    @push_data.fetch(:before)
  end

  def revision_after
    @push_data.fetch(:after)
  end

  def trimmed_ref
    Gitlab::Git.ref_name(ref)
  end

  def create?
    Gitlab::Git.blank_ref?(revision_before)
  end

  def remove?
    Gitlab::Git.blank_ref?(revision_after)
  end

  def action
    if create?
      :created
    elsif remove?
      :removed
    else
      :pushed
    end
  end

  def ref_type
    if Gitlab::Git.tag_ref?(ref)
      :tag
    else
      :branch
    end
  end
end