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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
#!/usr/bin/env ruby -KU
ENV["PATH"] = "/usr/local/bin/:/opt/local/bin:#{ENV["PATH"]}"
ENV["RAILS_ENV"] ||= "production"
require File.dirname(__FILE__) + "/../config/environment"
abort("Usage: #{$0} repo_id") unless ARGV[0]
$stdout.sync = true
def create_repo_creation_events_for(project)
project.repository_clones.each do |repo|
puts "creating Repository clone event in #{project.slug}/#{repo.name}"
project.events.create({
:action => Action::CLONE_REPOSITORY,
:target => repo,
:user => repo.user,
:data => repo.parent_id,
:created_at => repo.created_at
})
end
end
def create_comment_events_for(repo, project)
repo.comments.each do |comment|
puts "creating Comment event on #{project.slug}/#{repo.name}"
project.events.create({
:action => Action::COMMENT,
:target => comment,
:user => comment.user,
:created_at => comment.created_at
})
end
end
def create_merge_request_events_for(repo, project)
repo.merge_requests.each do |mr|
puts "creating MergeRequest event on #{project.slug}/#{repo.name}"
project.events.create({
:action => Action::REQUEST_MERGE,
:target => mr,
:user => mr.user,
:created_at => mr.created_at,
})
unless mr.open?
puts "creating MergeRequest resolvement event on #{project.slug}/#{repo.name}"
project.events.create({
:action => Action::RESOLVE_MERGE_REQUEST,
:target => mr,
:user => mr.user,
:data => mr.status_string,
:created_at => mr.created_at,
})
end
end
end
def create_events_for_repository(repo, project)
tag_map = repo.git.tags.inject({}){|hsh, t| hsh[t.commit.id] = t.name;hsh}
parsed_commits = {} # Neccesary because of merge
repo.git.heads.each do |head|
users_commits = {}
Grit::Commit.find_all(repo.git, head.name, {:since => "1 year ago"}).each do |commit|
users_commits[commit.committer.email] ||= []
users_commits[commit.committer.email] << commit
end
users = User.find(:all, :conditions => ['email in (?)', users_commits.keys] )
users.each do |user|
commits = users_commits[user.email]
puts "\nindexing #{commits.size} commits for #{user.email} in #{project.slug}/#{repo.name}:#{head.name}"
commits.each_index do |i|
commit = commits[i]
previous_commit = commits[i-1]
newrev = commit.id
next if parsed_commits.has_key?(newrev)
parsed_commits[newrev] = true
oldrev = previous_commit.id if previous_commit
current_rev = newrev
newtype = oldtype = current_rev_type = "commit"
type = repo.git.git.name_rev({}, newrev).last.split("/").first
if type != "tags"
type = "heads"
end
action = :create
if !oldrev
action = :create
else
if commit.id =~ /^0+$/
action = :delete
else
action = :update
end
end
if action != :delete
newtype = repo.git.git.cat_file({:t => true}, newrev)
end
if action == :update
oldtype = repo.git.git.cat_file({:t => true}, oldrev)
end
if action == :delete
current_rev = oldrev
current_rev_type = oldtype
end
action_id = nil
ref = nil
if current_rev_type == "commit"
if type == "heads"
case action
when :create
action_id = Action::CREATE_BRANCH
ref = head.name
when :update
action_id = Action::COMMIT
ref = current_rev
when :delete
action_id = Action::DELETE_BRANCH
ref = head.name
end
elsif type == "tags"
if action == :create
action_id = Action::CREATE_TAG
ref = tag_map[commit.id]
elsif action == :delete
action_id = Action::DELETE_TAG
ref = tag_map[commit.id]
end
end
elsif current_rev_type == "tag"
if type == "tags"
if action == :create
action_id = Action::CREATE_TAG
ref = tag_map[commit.id]
elsif action == :delete
action_id = Action::DELETE_TAG
ref = tag_map[commit.id]
end
end
end
print "." if (i % 10 == 1)
#puts "#{current_rev_type}#{action.inspect} in #{project.slug}/#{repo.name}:#{head.name}: #{commit.short_message}"
project.events.create({
:action => action_id || Action::COMMIT,
:target => repo,
:user => user,
:body => commit.message,
:data => commit.id,
:created_at => commit.committed_date})
end
commits = nil
puts
end
users_commits = nil
end
parsed_commits = nil
end
def rebuild_project!(project)
puts "Destroying existing events on #{project.slug}"
project.events.destroy_all
project.repositories.each do |repo|
create_events_for_repository(repo, project)
create_comment_events_for(repo, project)
create_merge_request_events_for(repo, project)
end
create_repo_creation_events_for(project)
end
case ARGV[0]
when "all"
Project.find(:all).each do |project|
puts
puts "rebuilding #{project.slug}"
puts
begin
rebuild_project!(project)
GC.start
rescue
puts "!!! failed to rebuild #{project.slug} !!!"
puts "#{e.class}:#{e.message} \n#{e.backtrace.join("\n ")}"
puts
next
end
end
else
project = Project.find(ARGV[0])
rebuild_project!(project) if project
end
|