output less from rebuild_events
[gitorious:yousource.git] / script / rebuild_events
1 #!/usr/bin/env ruby -KU
2
3 ENV["PATH"] = "/usr/local/bin/:/opt/local/bin:#{ENV["PATH"]}"
4 ENV["RAILS_ENV"] ||= "production"
5
6 require File.dirname(__FILE__) + "/../config/environment"
7
8 abort("Usage: #{$0} repo_id") unless ARGV[0]
9
10 $stdout.sync = true
11
12 def create_repo_creation_events_for(project)
13   project.repository_clones.each do |repo|
14     puts "creating Repository clone event in #{project.slug}/#{repo.name}"
15    project.events.create({
16      :action => Action::CLONE_REPOSITORY,
17      :target => repo,
18      :user => repo.user,
19      :data => repo.parent_id,
20      :created_at => repo.created_at
21    })
22   end
23 end
24
25 def create_comment_events_for(repo, project)
26   repo.comments.each do |comment| 
27     puts "creating Comment event on #{project.slug}/#{repo.name}"
28     project.events.create({
29       :action => Action::COMMENT,
30       :target => comment,
31       :user => comment.user,
32       :created_at => comment.created_at
33     })
34   end
35 end
36
37 def create_merge_request_events_for(repo, project)
38   repo.merge_requests.each do |mr|
39     puts "creating MergeRequest event on #{project.slug}/#{repo.name}"
40     project.events.create({
41       :action => Action::REQUEST_MERGE,
42       :target => mr,
43       :user => mr.user,
44       :created_at => mr.created_at,
45     })
46     unless mr.open?
47       puts "creating MergeRequest resolvement event on #{project.slug}/#{repo.name}"
48       project.events.create({
49         :action => Action::RESOLVE_MERGE_REQUEST,
50         :target => mr,
51         :user => mr.user,
52         :data => mr.status_string,
53         :created_at => mr.created_at,
54       })
55     end
56   end
57 end
58
59 def create_events_for_repository(repo, project)
60   tag_map = repo.git.tags.inject({}){|hsh, t| hsh[t.commit.id] = t.name;hsh}
61
62   parsed_commits = {} # Neccesary because of merge
63   repo.git.heads.each do |head|
64     users_commits = {}
65   
66     Grit::Commit.find_all(repo.git, head.name, {:since => "1 year ago"}).each do |commit|
67       users_commits[commit.committer.email] ||= []
68       users_commits[commit.committer.email] << commit
69     end
70     
71     users = User.find(:all, :conditions => ['email in (?)', users_commits.keys] )
72     users.each do |user|
73       commits = users_commits[user.email]
74       puts "\nindexing #{commits.size} commits for #{user.email} in #{project.slug}/#{repo.name}:#{head.name}"
75       commits.each_index do |i|
76         commit = commits[i]
77         previous_commit = commits[i-1]
78       
79         newrev = commit.id
80         next if parsed_commits.has_key?(newrev)
81         parsed_commits[newrev] = true
82       
83         oldrev = previous_commit.id if previous_commit
84         current_rev = newrev
85         newtype = oldtype = current_rev_type = "commit"
86       
87         type = repo.git.git.name_rev({}, newrev).last.split("/").first
88         if type != "tags"
89           type = "heads"
90         end
91       
92         action = :create
93         if !oldrev
94           action = :create
95         else
96           if commit.id =~ /^0+$/
97             action = :delete
98           else
99             action = :update
100           end
101         end
102
103         if action != :delete
104           newtype = repo.git.git.cat_file({:t => true}, newrev)
105         end
106
107         if action == :update
108           oldtype = repo.git.git.cat_file({:t => true}, oldrev)
109         end
110
111         if action == :delete
112             current_rev = oldrev
113             current_rev_type = oldtype
114         end
115       
116
117       
118         action_id = nil
119         ref = nil
120       
121         if current_rev_type == "commit"
122           if type == "heads"
123             case action
124               when :create
125                 action_id = Action::CREATE_BRANCH
126                 ref = head.name
127               when :update
128                 action_id = Action::COMMIT
129                 ref = current_rev
130               when :delete
131                 action_id = Action::DELETE_BRANCH
132                 ref = head.name
133             end
134           elsif type == "tags"
135             if action == :create
136               action_id = Action::CREATE_TAG
137               ref = tag_map[commit.id]
138             elsif action == :delete
139               action_id = Action::DELETE_TAG
140               ref = tag_map[commit.id]
141             end
142           end
143         elsif current_rev_type == "tag"
144           if type == "tags"
145             if action == :create
146               action_id = Action::CREATE_TAG
147               ref = tag_map[commit.id]
148             elsif action == :delete
149               action_id = Action::DELETE_TAG
150               ref = tag_map[commit.id]
151             end
152           end
153         end
154       
155         print "." if (i % 10 == 1)
156         #puts "#{current_rev_type}#{action.inspect} in #{project.slug}/#{repo.name}:#{head.name}: #{commit.short_message}"
157         project.events.create({
158           :action => action_id || Action::COMMIT, 
159           :target => repo, 
160           :user => user, 
161           :body => commit.message, 
162           :data => commit.id,
163           :created_at => commit.committed_date})
164       end
165       commits = nil
166       puts
167     end
168     users_commits = nil
169   end
170   parsed_commits = nil
171 end
172
173 def rebuild_project!(project)
174   puts "Destroying existing events on #{project.slug}"
175   project.events.destroy_all
176
177   project.repositories.each do |repo|
178     create_events_for_repository(repo, project)
179     create_comment_events_for(repo, project)
180     create_merge_request_events_for(repo, project)
181   end
182   create_repo_creation_events_for(project)
183 end
184
185 case ARGV[0]
186 when "all"
187   Project.find(:all).each do |project|
188     puts 
189     puts "rebuilding #{project.slug}"
190     puts
191     begin
192       rebuild_project!(project)
193       GC.start
194     rescue
195       puts "!!! failed to rebuild #{project.slug} !!!"
196       puts "#{e.class}:#{e.message} \n#{e.backtrace.join("\n  ")}"
197       puts
198       next
199     end
200   end
201 else
202   project = Project.find(ARGV[0])
203   rebuild_project!(project) if project
204 end
205