#!/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