Inline the gitlab-flowdock-git-hooks gem
This allows us to avoid one transitive dependency on gitlab-grit. The aim is to remove all transitive dependencies.
This commit is contained in:
parent
e347170cc5
commit
04aaf71932
6 changed files with 250 additions and 12 deletions
2
Gemfile
2
Gemfile
|
@ -210,7 +210,7 @@ gem 'hipchat', '~> 1.5.0'
|
|||
gem 'jira-ruby', '~> 1.4'
|
||||
|
||||
# Flowdock integration
|
||||
gem 'gitlab-flowdock-git-hook', '~> 1.0.1'
|
||||
gem 'flowdock', '~> 0.7'
|
||||
|
||||
# Slack integration
|
||||
gem 'slack-notifier', '~> 1.5.1'
|
||||
|
|
|
@ -278,10 +278,6 @@ GEM
|
|||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.10)
|
||||
github-markup (1.7.0)
|
||||
gitlab-flowdock-git-hook (1.0.1)
|
||||
flowdock (~> 0.7)
|
||||
gitlab-grit (>= 2.4.1)
|
||||
multi_json
|
||||
gitlab-gollum-lib (4.2.7.5)
|
||||
gemojione (~> 3.2)
|
||||
github-markup (~> 1.6)
|
||||
|
@ -1009,6 +1005,7 @@ DEPENDENCIES
|
|||
flipper (~> 0.13.0)
|
||||
flipper-active_record (~> 0.13.0)
|
||||
flipper-active_support_cache_store (~> 0.13.0)
|
||||
flowdock (~> 0.7)
|
||||
fog-aliyun (~> 0.2.0)
|
||||
fog-aws (~> 2.0.1)
|
||||
fog-core (~> 1.44)
|
||||
|
@ -1025,7 +1022,6 @@ DEPENDENCIES
|
|||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly-proto (~> 0.118.1)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-gollum-lib (~> 4.2)
|
||||
gitlab-markup (~> 1.6.4)
|
||||
gitlab-sidekiq-fetcher
|
||||
|
|
|
@ -281,10 +281,6 @@ GEM
|
|||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.10)
|
||||
github-markup (1.7.0)
|
||||
gitlab-flowdock-git-hook (1.0.1)
|
||||
flowdock (~> 0.7)
|
||||
gitlab-grit (>= 2.4.1)
|
||||
multi_json
|
||||
gitlab-gollum-lib (4.2.7.5)
|
||||
gemojione (~> 3.2)
|
||||
github-markup (~> 1.6)
|
||||
|
@ -1018,6 +1014,7 @@ DEPENDENCIES
|
|||
flipper (~> 0.13.0)
|
||||
flipper-active_record (~> 0.13.0)
|
||||
flipper-active_support_cache_store (~> 0.13.0)
|
||||
flowdock (~> 0.7)
|
||||
fog-aliyun (~> 0.2.0)
|
||||
fog-aws (~> 2.0.1)
|
||||
fog-core (~> 1.44)
|
||||
|
@ -1034,7 +1031,6 @@ DEPENDENCIES
|
|||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly-proto (~> 0.118.1)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-gollum-lib (~> 4.2)
|
||||
gitlab-markup (~> 1.6.4)
|
||||
gitlab-sidekiq-fetcher
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "flowdock-git-hook"
|
||||
require 'flowdock/git'
|
||||
|
||||
# Flow dock depends on Grit to compute the number of commits between two given
|
||||
# commits. To make this depend on Gitaly, a monkey patch is applied
|
||||
|
|
96
lib/flowdock/git.rb
Normal file
96
lib/flowdock/git.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
|
||||
require "multi_json"
|
||||
require "cgi"
|
||||
require "flowdock"
|
||||
require "flowdock/git/builder"
|
||||
|
||||
module Flowdock
|
||||
class Git
|
||||
class TokenError < StandardError; end
|
||||
|
||||
class << self
|
||||
def post(ref, from, to, options = {})
|
||||
Git.new(ref, from, to, options).post
|
||||
end
|
||||
|
||||
def background_post(ref, from, to, options = {})
|
||||
Git.new(ref, from, to, options).background_post
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(ref, from, to, options = {})
|
||||
@ref = ref
|
||||
@from = from
|
||||
@to = to
|
||||
@options = options
|
||||
@token = options[:token] || config["flowdock.token"] || raise(TokenError.new("Flowdock API token not found"))
|
||||
@commit_url = options[:commit_url] || config["flowdock.commit-url-pattern"] || nil
|
||||
@diff_url = options[:diff_url] || config["flowdock.diff-url-pattern"] || nil
|
||||
@repo_url = options[:repo_url] || config["flowdock.repository-url"] || nil
|
||||
@repo_name = options[:repo_name] || config["flowdock.repository-name"] || nil
|
||||
@permanent_refs = options[:permanent_refs] ||
|
||||
(config["flowdock.permanent-references"] || "refs/heads/master")
|
||||
.split(",")
|
||||
.map(&:strip)
|
||||
.map {|exp| Regexp.new(exp) }
|
||||
end
|
||||
|
||||
# Send git push notification to Flowdock
|
||||
def post
|
||||
messages.each do |message|
|
||||
Flowdock::Client.new(flow_token: @token).post_to_thread(message)
|
||||
end
|
||||
end
|
||||
|
||||
# Create and post notification in background process. Avoid blocking the push notification.
|
||||
def background_post
|
||||
pid = Process.fork
|
||||
if pid.nil?
|
||||
Grit::Git.with_timeout(600) do
|
||||
post
|
||||
end
|
||||
else
|
||||
Process.detach(pid) # Parent
|
||||
end
|
||||
end
|
||||
|
||||
def repo
|
||||
@repo ||= Grit::Repo.new(
|
||||
@options[:repo] || Dir.pwd,
|
||||
is_bare: @options[:is_bare] || false
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def messages
|
||||
Git::Builder.new(repo: @repo,
|
||||
ref: @ref,
|
||||
before: @from,
|
||||
after: @to,
|
||||
commit_url: @commit_url,
|
||||
branch_url: @branch_url,
|
||||
diff_url: @diff_url,
|
||||
repo_url: @repo_url,
|
||||
repo_name: @repo_name,
|
||||
permanent_refs: @permanent_refs,
|
||||
tags: tags
|
||||
).to_hashes
|
||||
end
|
||||
|
||||
# Flowdock tags attached to the push notification
|
||||
def tags
|
||||
if @options[:tags]
|
||||
@options[:tags]
|
||||
else
|
||||
config["flowdock.tags"].to_s.split(",").map(&:strip)
|
||||
end.map do |t|
|
||||
CGI.escape(t)
|
||||
end
|
||||
end
|
||||
|
||||
def config
|
||||
@config ||= Grit::Config.new(repo)
|
||||
end
|
||||
end
|
||||
end
|
150
lib/flowdock/git/builder.rb
Normal file
150
lib/flowdock/git/builder.rb
Normal file
|
@ -0,0 +1,150 @@
|
|||
require "grit"
|
||||
require 'cgi'
|
||||
require "securerandom"
|
||||
|
||||
module Flowdock
|
||||
class Git
|
||||
class Commit
|
||||
def initialize(external_thread_id, thread, tags, commit)
|
||||
@commit = commit
|
||||
@external_thread_id = external_thread_id
|
||||
@thread = thread
|
||||
@tags = tags
|
||||
end
|
||||
|
||||
def to_hash
|
||||
hash = {
|
||||
external_thread_id: @external_thread_id,
|
||||
event: "activity",
|
||||
author: {
|
||||
name: @commit[:author][:name],
|
||||
email: @commit[:author][:email]
|
||||
},
|
||||
title: title,
|
||||
thread: @thread,
|
||||
body: body
|
||||
}
|
||||
hash[:tags] = @tags if @tags
|
||||
encode(hash)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def encode(hash)
|
||||
return hash unless "".respond_to? :encode
|
||||
encode_as_utf8(hash)
|
||||
end
|
||||
|
||||
# This only works on Ruby 1.9
|
||||
def encode_as_utf8(obj)
|
||||
if obj.is_a? Hash
|
||||
obj.each_pair do |key, val|
|
||||
encode_as_utf8(val)
|
||||
end
|
||||
elsif obj.is_a?(Array)
|
||||
obj.each do |val|
|
||||
encode_as_utf8(val)
|
||||
end
|
||||
elsif obj.is_a?(String) && obj.encoding != Encoding::UTF_8
|
||||
if !obj.force_encoding("UTF-8").valid_encoding?
|
||||
obj.force_encoding("ISO-8859-1").encode!(Encoding::UTF_8, :invalid => :replace, :undef => :replace)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def body
|
||||
content = @commit[:message][first_line.size..-1]
|
||||
content.strip! if content
|
||||
"<pre>#{content}</pre>" unless content.empty?
|
||||
end
|
||||
|
||||
def first_line
|
||||
@first_line ||= (@commit[:message].split("\n")[0] || @commit[:message])
|
||||
end
|
||||
|
||||
def title
|
||||
commit_id = @commit[:id][0, 7]
|
||||
if @commit[:url]
|
||||
"<a href=\"#{@commit[:url]}\">#{commit_id}</a> #{message_title}"
|
||||
else
|
||||
"#{commit_id} #{message_title}"
|
||||
end
|
||||
end
|
||||
|
||||
def message_title
|
||||
CGI.escape_html(first_line.strip)
|
||||
end
|
||||
end
|
||||
|
||||
# Class used to build Git payload
|
||||
class Builder
|
||||
def initialize(opts)
|
||||
@repo = opts[:repo]
|
||||
@ref = opts[:ref]
|
||||
@before = opts[:before]
|
||||
@after = opts[:after]
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def commits
|
||||
@repo.commits_between(@before, @after).map do |commit|
|
||||
{
|
||||
url: if @opts[:commit_url] then @opts[:commit_url] % [commit.sha] end,
|
||||
id: commit.sha,
|
||||
message: commit.message,
|
||||
author: {
|
||||
name: commit.author.name,
|
||||
email: commit.author.email
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def ref_name
|
||||
@ref.to_s.sub(/\Arefs\/(heads|tags)\//, '')
|
||||
end
|
||||
|
||||
def to_hashes
|
||||
commits.map do |commit|
|
||||
Commit.new(external_thread_id, thread, @opts[:tags], commit).to_hash
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def thread
|
||||
@thread ||= {
|
||||
title: thread_title,
|
||||
external_url: @opts[:repo_url]
|
||||
}
|
||||
end
|
||||
|
||||
def permanent?
|
||||
@permanent ||= @opts[:permanent_refs].select do |regex|
|
||||
regex.match(@ref)
|
||||
end.size > 0
|
||||
end
|
||||
|
||||
def thread_title
|
||||
action = if permanent?
|
||||
"updated"
|
||||
end
|
||||
type = if @ref.match(%r(^refs/heads/))
|
||||
"branch"
|
||||
else
|
||||
"tag"
|
||||
end
|
||||
[@opts[:repo_name], type, ref_name, action].compact.join(" ")
|
||||
end
|
||||
|
||||
def external_thread_id
|
||||
@external_thread_id ||=
|
||||
if permanent?
|
||||
SecureRandom.hex
|
||||
else
|
||||
@ref
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue