require 'json' require 'socket' class IrkerWorker include Sidekiq::Worker include DedicatedSidekiqQueue def perform(project_id, chans, colors, push_data, settings) project = Project.find(project_id) # Get config parameters return false unless init_perform settings, chans, colors 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, project, repo_name, committer, branch # Next messages are for commits send_commits push_data, project, repo_name, committer, branch close_connection true end private def init_perform(set, chans, colors) @colors = colors @channels = chans start_connection set['server_host'], set['server_port'] end 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 sendtoirker(privmsg) to_send = { to: @channels, privmsg: privmsg } @socket.puts JSON.dump(to_send) end def close_connection @socket.close end def send_branch_updates(push_data, project, repo_name, committer, branch) if Gitlab::Git.blank_ref?(push_data['before']) send_new_branch project, repo_name, committer, branch elsif Gitlab::Git.blank_ref?(push_data['after']) send_del_branch repo_name, committer, branch end end def send_new_branch(project, repo_name, committer, branch) repo_path = project.path_with_namespace newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/branches" newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors privmsg = "[#{repo_name}] #{committer} has created a new branch " privmsg += "#{branch}: #{newbranch}" sendtoirker privmsg end def send_del_branch(repo_name, committer, branch) privmsg = "[#{repo_name}] #{committer} has deleted the branch #{branch}" sendtoirker privmsg end def send_commits(push_data, project, repo_name, committer, branch) 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, project end send_commits_count(push_data, project, repo_name, committer, branch) # One message per commit, limited by 3 messages (same limit as the # github irc hook) commits = push_data['commits'].first(3) commits.each do |hook_attrs| send_one_commit project, hook_attrs, repo_name, branch end end def before_on_new_branch(push_data, project) commit = commit_from_id project, 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(data, project, repo, committer, branch) url = compare_url data, project.path_with_namespace commits = colorize_commits data['total_commits_count'] new_commits = 'new commit' new_commits += 's' if data['total_commits_count'] > 1 sendtoirker "[#{repo}] #{committer} pushed #{commits} #{new_commits} " \ "to #{branch}: #{url}" end def compare_url(data, repo_path) sha1 = Commit.truncate_sha(data['before']) sha2 = Commit.truncate_sha(data['after']) compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/compare" compare_url += "/#{sha1}...#{sha2}" colorize_url compare_url end def send_one_commit(project, hook_attrs, repo_name, branch) commit = commit_from_id project, hook_attrs['id'] sha = colorize_sha Commit.truncate_sha(hook_attrs['id']) author = hook_attrs['author']['name'] files = colorize_nb_files(files_count commit) title = commit.title sendtoirker "#{repo_name}/#{branch} #{sha} #{author} (#{files}): #{title}" end def commit_from_id(project, id) project.commit(id) end def files_count(commit) diffs = commit.raw_diffs(deltas_only: true) files = "#{diffs.real_size} file" files += 's' if diffs.size > 1 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