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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# frozen_string_literal: true
require 'json'
require 'socket'
class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :integrations
def perform(project_id, channels, colors, push_data, settings)
# Establish connection to irker server
return false unless start_connection(settings['server_host'],
settings['server_port'])
@project = Project.find(project_id)
@colors = colors
@channels = channels
@repo_path = @project.full_path
@repo_name = push_data['repository']['name']
@committer = push_data['user_name']
@branch = push_data['ref'].gsub(%r'refs/[^/]*/', '')
if @colors
@repo_name = "\x0304#{@repo_name}\x0f"
@branch = "\x0305#{@branch}\x0f"
end
# First messages are for branch creation/deletion
send_branch_updates(push_data)
# Next messages are for commits
send_commits(push_data)
close_connection
true
end
private
def start_connection(irker_server, irker_port)
begin
@socket = TCPSocket.new irker_server, irker_port
rescue Errno::ECONNREFUSED => e
logger.fatal "Can't connect to Irker daemon: #{e}"
return false
end
true
end
def send_to_irker(privmsg)
to_send = { to: @channels, privmsg: privmsg }
@socket.puts Gitlab::Json.dump(to_send)
end
def close_connection
@socket.close
end
def send_branch_updates(push_data)
message =
if Gitlab::Git.blank_ref?(push_data['before'])
new_branch_message
elsif Gitlab::Git.blank_ref?(push_data['after'])
delete_branch_message
end
send_to_irker(message)
end
def new_branch_message
newbranch = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/branches"
newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors
"[#{@repo_name}] #{@committer} has created a new branch #{@branch}: #{newbranch}"
end
def delete_branch_message
"[#{@repo_name}] #{@committer} has deleted the branch #{@branch}"
end
def send_commits(push_data)
return if push_data['total_commits_count'] == 0
# Next message is for number of commit pushed, if any
if Gitlab::Git.blank_ref?(push_data['before'])
# Tweak on push_data["before"] in order to have a nice compare URL
push_data['before'] = before_on_new_branch(push_data)
end
send_commits_count(push_data)
# One message per commit, limited by 3 messages (same limit as the
# github irc hook)
commits = push_data['commits'].first(3)
commits.each do |commit_attrs|
send_one_commit(commit_attrs)
end
end
def before_on_new_branch(push_data)
commit = commit_from_id(push_data['commits'][0]['id'])
parents = commit.parents
# Return old value if there's no new one
return push_data['before'] if parents.empty?
# Or return the first parent-commit
parents[0].id
end
def send_commits_count(push_data)
url = compare_url(push_data['before'], push_data['after'])
commits = colorize_commits(push_data['total_commits_count'])
new_commits = 'new commit'.pluralize(push_data['total_commits_count'])
send_to_irker("[#{@repo_name}] #{@committer} pushed #{commits} #{new_commits} " \
"to #{@branch}: #{url}")
end
def compare_url(sha_before, sha_after)
sha1 = Commit.truncate_sha(sha_before)
sha2 = Commit.truncate_sha(sha_after)
compare_url = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/compare" \
"/#{sha1}...#{sha2}"
colorize_url(compare_url)
end
def send_one_commit(commit_attrs)
commit = commit_from_id(commit_attrs['id'])
sha = colorize_sha(Commit.truncate_sha(commit_attrs['id']))
author = commit_attrs['author']['name']
files = colorize_nb_files(files_count(commit))
title = commit.title
send_to_irker("#{@repo_name}/#{@branch} #{sha} #{author} (#{files}): #{title}")
end
def commit_from_id(id)
@project.commit(id)
end
def files_count(commit)
diff_size = commit.raw_deltas.size
files = "#{diff_size} file".pluralize(diff_size)
files
end
def colorize_sha(sha)
sha = "\x0314#{sha}\x0f" if @colors
sha
end
def colorize_nb_files(nb_files)
nb_files = "\x0312#{nb_files}\x0f" if @colors
nb_files
end
def colorize_url(url)
url = "\x0302\x1f#{url}\x0f" if @colors
url
end
def colorize_commits(commits)
commits = "\x02#{commits}\x0f" if @colors
commits
end
end
|