BigW Consortium Gitlab

irker_worker.rb 4.7 KB
Newer Older
Aorimn committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
require 'json'
require 'socket'

class IrkerWorker
  include Sidekiq::Worker

  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

22
    # First messages are for branch creation/deletion
Aorimn committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36
    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
37
    start_connection set['server_host'], set['server_port']
Aorimn committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
  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)
60
    if Gitlab::Git.blank_ref?(push_data['before'])
Aorimn committed
61
      send_new_branch project, repo_name, committer, branch
62
    elsif Gitlab::Git.blank_ref?(push_data['after'])
Aorimn committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
      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
86
    if Gitlab::Git.blank_ref?(push_data['before'])
Aorimn committed
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
      # 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)
140
    project.commit(id)
Aorimn committed
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
  end

  def files_count(commit)
    files = "#{commit.diffs.count} file"
    files += 's' if commit.diffs.count > 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