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
|
# encoding: utf-8
#--
# Copyright (C) 2011 Gitorious AS
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
# This is required because ActiveMessaging actually forcefully loads
# all processors before initializers are run. Hopefully this can go away
# when the vendored ActiveMessaging plugin is removed.
require File.join(Rails.root, "config/initializers/messaging")
class PushProcessor
include Gitorious::Messaging::Consumer
consumes "/queue/GitoriousPush"
attr_reader :user, :repository, :spec
include Patchwork
include Emailer
PUSH_EVENT_GIT_OUTPUT_SEPARATOR = "\t"
PUSH_EVENT_GIT_OUTPUT_SEPARATOR_ESCAPED = "\\\t"
GIT_PRETTY_FORMAT = "format:#{['%H','%cn <%ce>','%at','%s','%an'].join(PUSH_EVENT_GIT_OUTPUT_SEPARATOR)}"
def on_message(message)
load_message(message)
log_message("Got payload: #{spec} from user #{user && user.login}")
if spec.merge_request?
log_message("Processing merge request")
process_merge_request
elsif repository.wiki?
log_message("Processing wiki update")
process_wiki_update
else
log_message("Processing regular push")
process_push
end
end
def process_merge_request
return if spec.action_delete?
merge_request.update_from_push!
end
def process_push
ensure_user
log = PushEventLogger.new(repository, spec, user)
log.create_push_event if log.create_push_event?
log.create_meta_event if log.create_meta_event?
repository.register_push
repository.save
trigger_hooks unless repository.hooks.blank?
if spec.head? && spec.action_update?
begin
notify
rescue => e
logger.error("Notification failed: #{e.class.name} #{e.message}:\n #{e.backtrace.join("\n ")}")
end
end
end
def notify
commits = []
repository.git.git.log(
{:pretty => GIT_PRETTY_FORMAT, :s => true, :timeout => false},
"#{spec.from_sha.sha}..#{spec.to_sha.sha}").split("\n").each do |commit|
sha, email, timestamp, message, author = commit.split(PUSH_EVENT_GIT_OUTPUT_SEPARATOR_ESCAPED)
commits.push({
:sha => sha,
:timestamp => Time.at(timestamp.to_i).utc,
:user => user,
:author => author,
:message => message,
})
end
notify_patchwork(repository, spec.ref.name, commits) if GitoriousConfig["patchwork"]
notify_emailer(repository, spec.ref.name, commits) if GitoriousConfig["emailer"]
end
def trigger_hooks
generator = Gitorious::WebHookGenerator.new(repository, spec, user)
generator.generate!
end
def process_wiki_update
ensure_user
logger = Gitorious::Wiki::UpdateEventLogger.new(repository, spec, user)
logger.create_wiki_events
end
def load_message(message)
@user = User.find_by_login(message["username"])
@repository = Repository.find_by_hashed_path(message["gitdir"])
@spec = PushSpecParser.new(*message["message"].split(" "))
end
private
def merge_request
@repository.merge_requests.find_by_sequence_number!(@spec.ref_name.to_i)
end
def ensure_user
raise "Username was nil" if user.nil?
end
def log_message(message)
logger.info("#{Time.now.to_s(:short)} #{message}")
end
end
|