6fbf3f1 by Johan Sørensen at 2008-04-25 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
7b3e80c by Johan Sørensen at 2008-04-29 10
$stdout.sync = true
11
8776f60 by Johan Sørensen at 2008-04-27 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
6fbf3f1 by Johan Sørensen at 2008-04-25 24
8776f60 by Johan Sørensen at 2008-04-27 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
0bf5722 by David A. Cuadrado at 2008-04-27 36
8776f60 by Johan Sørensen at 2008-04-27 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
0bf5722 by David A. Cuadrado at 2008-04-27 56
  end
8776f60 by Johan Sørensen at 2008-04-27 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 = {}
0bf5722 by David A. Cuadrado at 2008-04-27 65
  
8776f60 by Johan Sørensen at 2008-04-27 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
7b3e80c by Johan Sørensen at 2008-04-29 70
    
8776f60 by Johan Sørensen at 2008-04-27 71
    users = User.find(:all, :conditions => ['email in (?)', users_commits.keys] )
72
    users.each do |user|
73
      commits = users_commits[user.email]
7b3e80c by Johan Sørensen at 2008-04-29 74
      puts "\nindexing #{commits.size} commits for #{user.email} in #{project.slug}/#{repo.name}:#{head.name}"
8776f60 by Johan Sørensen at 2008-04-27 75
      commits.each_index do |i|
76
        commit = commits[i]
77
        previous_commit = commits[i-1]
0bf5722 by David A. Cuadrado at 2008-04-27 78
      
8776f60 by Johan Sørensen at 2008-04-27 79
        newrev = commit.id
80
        next if parsed_commits.has_key?(newrev)
81
        parsed_commits[newrev] = true
0bf5722 by David A. Cuadrado at 2008-04-27 82
      
8776f60 by Johan Sørensen at 2008-04-27 83
        oldrev = previous_commit.id if previous_commit
84
        current_rev = newrev
85
        newtype = oldtype = current_rev_type = "commit"
6fbf3f1 by Johan Sørensen at 2008-04-25 86
      
8776f60 by Johan Sørensen at 2008-04-27 87
        type = repo.git.git.name_rev({}, newrev).last.split("/").first
88
        if type != "tags"
89
          type = "heads"
90
        end
0bf5722 by David A. Cuadrado at 2008-04-27 91
      
6fbf3f1 by Johan Sørensen at 2008-04-25 92
        action = :create
8776f60 by Johan Sørensen at 2008-04-27 93
        if !oldrev
94
          action = :create
6fbf3f1 by Johan Sørensen at 2008-04-25 95
        else
8776f60 by Johan Sørensen at 2008-04-27 96
          if commit.id =~ /^0+$/
97
            action = :delete
98
          else
99
            action = :update
100
          end
6fbf3f1 by Johan Sørensen at 2008-04-25 101
        end
0bf5722 by David A. Cuadrado at 2008-04-27 102
8776f60 by Johan Sørensen at 2008-04-27 103
        if action != :delete
104
          newtype = repo.git.git.cat_file({:t => true}, newrev)
105
        end
6fbf3f1 by Johan Sørensen at 2008-04-25 106
8776f60 by Johan Sørensen at 2008-04-27 107
        if action == :update
108
          oldtype = repo.git.git.cat_file({:t => true}, oldrev)
109
        end
0bf5722 by David A. Cuadrado at 2008-04-27 110
8776f60 by Johan Sørensen at 2008-04-27 111
        if action == :delete
112
            current_rev = oldrev
113
            current_rev_type = oldtype
114
        end
6fbf3f1 by Johan Sørensen at 2008-04-25 115
      
116
117
      
8776f60 by Johan Sørensen at 2008-04-27 118
        action_id = nil
119
        ref = nil
6fbf3f1 by Johan Sørensen at 2008-04-25 120
      
8776f60 by Johan Sørensen at 2008-04-27 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
6fbf3f1 by Johan Sørensen at 2008-04-25 142
          end
8776f60 by Johan Sørensen at 2008-04-27 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
6fbf3f1 by Johan Sørensen at 2008-04-25 152
          end
153
        end
154
      
7b3e80c by Johan Sørensen at 2008-04-29 155
        print "." if (i % 10 == 1)
156
        #puts "#{current_rev_type}#{action.inspect} in #{project.slug}/#{repo.name}:#{head.name}: #{commit.short_message}"
8776f60 by Johan Sørensen at 2008-04-27 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
a543a60 by Johan Sørensen at 2008-04-28 165
      commits = nil
7b3e80c by Johan Sørensen at 2008-04-29 166
      puts
6fbf3f1 by Johan Sørensen at 2008-04-25 167
    end
a543a60 by Johan Sørensen at 2008-04-28 168
    users_commits = nil
6fbf3f1 by Johan Sørensen at 2008-04-25 169
  end
a543a60 by Johan Sørensen at 2008-04-28 170
  parsed_commits = nil
8776f60 by Johan Sørensen at 2008-04-27 171
end
172
a543a60 by Johan Sørensen at 2008-04-28 173
def rebuild_project!(project)
174
  puts "Destroying existing events on #{project.slug}"
175
  project.events.destroy_all
8776f60 by Johan Sørensen at 2008-04-27 176
a543a60 by Johan Sørensen at 2008-04-28 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
8776f60 by Johan Sørensen at 2008-04-27 184
a543a60 by Johan Sørensen at 2008-04-28 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
8776f60 by Johan Sørensen at 2008-04-27 204
end
a543a60 by Johan Sørensen at 2008-04-28 205