Commit 967ffa1d408f8ce441d4c2052dd06abb714f6a30

Merge commit 'johan/master'

* commit 'johan/master':
Fixed Repository#commit_graph_data_by_author edge case of the commit count being nil when multiple "authors" with the same name have different emails
Prefer String#constantize over eval
Remove ending parenthesis after 'Edit project'
Added script to destroy invalid events
Destroy events if associated project/user is deleted
Unify Project#slug usage on events display and reword mergerequest event text a bit
"Trees" context link renamed to "source tree" under repositories
Remove ending parenthesis after "Edit project"
made clone link text include project slug on users page, so that it makes more sense
We don't use that term here

Commit diff

TODO.txt

 
11events:
22* need to create user-less events even we don't find matching users, otherwise it gets weird whenever there's commits from non-registered gitorious users (or users commit from another email).
33- maybe save name+email in events table in that case, so we can hook them up to a user later if needed.
4* .hooks symlink need to go to $deploy_to/current, not the release dir
45
56new-ui:
7* show outstanding mergerequests on dashboard
68* mandatory project descriptions, at least a sentence or two
79* tweak fonts-sizes and line-heights
810* Clone stats graph on repositories#index
toggle raw diff

app/controllers/projects_controller.rb

 
8686 if @project.can_be_deleted_by?(current_user)
8787 project_title = @project.title
8888 @project.destroy
89 #current_user.create_event(Action::DELETE_PROJECT, nil, project_title)
89# Event.create(:action => Action::DELETE_PROJECT, :user => current_user, :data => project_title) # FIXME: project_id cannot be null
9090 else
9191 flash[:error] = "You're not the owner of this project, or the project has clones"
9292 end
toggle raw diff

app/helpers/application_helper.rb

 
143143
144144 project = target.project
145145
146 action = "<strong>forked</strong> #{link_to h(project.title), project_path(project)}/#{link_to h(original_repo.name), project_repository_url(project, original_repo)} in #{link_to h(target.name), project_repository_url(project, target)}"
146 action = "<strong>cloned</strong> #{link_to h(project.slug), project_path(project)}/#{link_to h(original_repo.name), project_repository_url(project, original_repo)} in #{link_to h(target.name), project_repository_url(project, target)}"
147147 category = "repository"
148148 when Action::DELETE_REPOSITORY
149149 action = "<strong>deleted repository</strong> #{link_to h(target.title), project_path(target)}/#{event.data}"
156156 when Action::CREATE_BRANCH
157157 project = target.project
158158 if event.data == "master"
159 action = "<strong>started development</strong> of #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
159 action = "<strong>started development</strong> of #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
160160 body = event.body
161161 else
162 action = "<strong>created branch</strong> #{link_to h(event.data), project_repository_tree_path(project, target, event.data)} on #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
162 action = "<strong>created branch</strong> #{link_to h(event.data), project_repository_tree_path(project, target, event.data)} on #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
163163 end
164164 category = "commit"
165165 when Action::DELETE_BRANCH
166166 project = target.project
167 action = "<strong>deleted branch</strong> #{event.data} on #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
167 action = "<strong>deleted branch</strong> #{event.data} on #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
168168 category = "commit"
169169 when Action::CREATE_TAG
170170 project = target.project
171 action = "<strong>tagged</strong> #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
171 action = "<strong>tagged</strong> #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
172172 body = "#{link_to event.data, project_repository_commit_path(project, target, event.data)}<br/>#{event.body}"
173173 category = "commit"
174174 when Action::DELETE_TAG
175175 project = target.project
176 action = "<strong>deleted tag</strong> #{event.data} on #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
176 action = "<strong>deleted tag</strong> #{event.data} on #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
177177 category = "commit"
178178 when Action::ADD_COMMITTER
179179 user = target.user
180180 repo = target.repository
181 action = "<strong>added committer</strong> #{link_to user.login, user_path(user)} to #{link_to h(repo.project.title), project_path(repo.project)}/#{link_to h(repo.name), project_repository_url(repo.project, repo)}"
181 action = "<strong>added committer</strong> #{link_to user.login, user_path(user)} to #{link_to h(repo.project.slug), project_path(repo.project)}/#{link_to h(repo.name), project_repository_url(repo.project, repo)}"
182182 category = "repository"
183183 when Action::REMOVE_COMMITTER
184184 user = User.find_by_id(event.data.to_i)
185185 next unless user
186186
187187 project = target.project
188 action = "<strong>removed committer</strong> #{link_to user.login, user_path(user)} from #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
188 action = "<strong>removed committer</strong> #{link_to user.login, user_path(user)} from #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
189189 category = "repository"
190190 when Action::COMMENT
191191 project = target.project
192192 repo = target.repository
193193
194 action = "<strong>commented</strong> on #{link_to h(project.title), project_path(project)}/#{link_to h(repo.name), project_repository_url(project, repo)}"
194 action = "<strong>commented</strong> on #{link_to h(project.slug), project_path(project)}/#{link_to h(repo.name), project_repository_url(project, repo)}"
195195 body = truncate(h(target.body), 150)
196196 category = "comment"
197197 when Action::REQUEST_MERGE
199199 project = source_repository.project
200200 target_repository = target.target_repository
201201
202 action = "<strong>requested merge</strong> #{link_to h(project.title), project_path(project)}/#{link_to h(source_repository.name), project_repository_url(project, source_repository)} to #{link_to h(project.title), project_path(project)}/#{link_to h(target_repository.name)}"
203 body = "#{link_to "review", [project, target_repository, target]}<br/>#{truncate(h(target.proposal), 100)}"
204 category = "merge request"
202 action = "<strong>requested a merge of</strong> #{link_to h(project.slug), project_path(project)}/#{link_to h(source_repository.name), project_repository_url(project, source_repository)} with #{link_to h(project.slug), project_path(project)}/#{link_to h(target_repository.name)}"
203 body = "#{link_to truncate(h(target.proposal), 100), [project, target_repository, target]}"
204 category = "merge_request"
205205 when Action::RESOLVE_MERGE_REQUEST
206206 source_repository = target.source_repository
207207 project = source_repository.project
208208 target_repository = target.target_repository
209209
210 action = "<strong>resolved merge request </strong>to [#{target.status_string}] from #{link_to h(project.title), project_path(project)}/#{link_to h(source_repository.name), project_repository_url(project, source_repository)}"
210 action = "<strong>resolved merge request</strong> as [#{target.status_string}] from #{link_to h(project.slug), project_path(project)}/#{link_to h(source_repository.name), project_repository_url(project, source_repository)}"
211 body = "#{link_to truncate(h(target.proposal), 100), [project, target_repository, target]}"
211212 category = "merge_request"
212213 when Action::UPDATE_MERGE_REQUEST
213214 source_repository = target.source_repository
220220 when Action::DELETE_MERGE_REQUEST
221221 project = target.project
222222
223 action = "<strong>deleted merge request</strong> from #{link_to h(project.title), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
223 action = "<strong>deleted merge request</strong> from #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
224224 category = "merge_request"
225225 end
226226
toggle raw diff

app/models/project.rb

 
99 :class_name => "Repository"
1010 has_many :repository_clones, :conditions => ["mainline = ?", false],
1111 :class_name => "Repository"
12 has_many :events, :order => "created_at asc"
12 has_many :events, :order => "created_at asc", :dependent => :destroy
1313
1414 is_indexed :fields => ["title", "description", "slug"],
1515 :concatenate => [
toggle raw diff

app/models/repository.rb

 
181181 def commit_graph_data_by_author(head = "master")
182182 h = {}
183183 emails = {}
184 count_author_regexp = /^\s+(\d+)\s(.+)\s\<(\S+)\>$/.freeze
185184 data = self.git.git.shortlog({:e => true, :s => true }, head)
186185 data.each_line do |line|
187 if line =~ count_author_regexp
188 count = $1.to_i
189 author = $2
190 email = $3
191
192 h[author] ||= 0
193 h[author] += count
194
195 emails[email] = author
196 end
186 count, actor = line.split("\t")
187 actor = Grit::Actor.from_string(actor)
188
189 h[actor.name] ||= 0
190 h[actor.name] += count.to_i
191 emails[actor.email] = actor.name
197192 end
198193
199194 users = User.find(:all, :conditions => ["email in (?)", emails.keys])
200195 users.each do |user|
201196 author_name = emails[user.email]
202 h[user.login] = h.delete(author_name)
197 if h[author_name] # in the event that a user with the same name has used two different emails, he'd be gone by now
198 h[user.login] = h.delete(author_name)
199 end
203200 end
204201
205202 h
toggle raw diff

app/models/user.rb

 
66 has_many :repositories, :through => :committerships
77 has_many :ssh_keys, :order => "id desc"
88 has_many :comments
9 has_many :events, :order => "events.created_at asc"
9 has_many :events, :order => "events.created_at asc", :dependent => :destroy
1010
1111 # Virtual attribute for the unencrypted password
1212 attr_accessor :password, :current_password
toggle raw diff

app/views/projects/confirm_delete.html.erb

 
99</p>
1010
1111<% content_for :submenu do -%>
12 <li class="selected"><%= link_to "Edit project", edit_project_path(@project) -%>)</li>
12 <li class="selected"><%= link_to "Edit project", edit_project_path(@project) -%></li>
1313<% end -%>
1414
1515<% content_for :sidebar do -%>
toggle raw diff

app/views/projects/edit.html.erb

 
77<% end -%>
88
99<% content_for :submenu do -%>
10 <li class="selected"><%= link_to "Edit project", edit_project_path(@project) -%>)</li>
10 <li class="selected"><%= link_to "Edit project", edit_project_path(@project) -%></li>
1111<% end -%>
1212
1313<% content_for :sidebar do -%>
toggle raw diff

app/views/repositories/_context_menu.html.erb

 
11<li><%= link_to "Overview", [@project, @repository] -%></li>
22<li><%= link_to "Commits",
33 project_repository_logs_path(@project, @repository) -%></li>
4<li><%= link_to "Trees",
4<li><%= link_to "Source Tree",
55 project_repository_trees_path(@project, @repository) -%></li>
66<li><%= link_to "Comments (#{@repository.comments.count})",
77 project_repository_comments_path(@project, @repository) -%></li>
toggle raw diff

app/views/users/show.html.erb

 
3535 <h4>Repository clones</h4>
3636 <ul>
3737 <% @repositories.each do |repo| -%>
38 <li><%= link_to h(repo.name), [repo.project, repo] -%></li>
38 <li><%= link_to h("#{repo.project.slug}/#{repo.name}"), [repo.project, repo] -%></li>
3939 <% end -%>
4040 </ul>
4141 <% end -%>
toggle raw diff

data/hooks/post-receive

 
7272 user = User.find_by_email(hash[:email])
7373 if user.nil?
7474 # TODO: no user should be ok, no need to skip
75 $stdout.puts "** The email '#{hash[:email]}' is not registered."
75 # $stdout.puts "** The email '#{hash[:email]}' is not registered."
7676 next
7777 end
7878
toggle raw diff

script/destroy_invalid_events

 
1#!/usr/bin/env ruby
2
3ENV["RAILS_ENV"] ||= "production"
4require File.dirname(__FILE__)+'/../config/environment'
5
6Event.find(:all).each do |event|
7 begin
8 event.target_type.constantize.find(event.target_id)
9 Project.find(event.project_id)
10 rescue ActiveRecord::RecordNotFound
11 puts "Destroying invalid event '#{event.id}:#{Action.name(event.action)}'"
12 event.destroy
13 end
14end
15
16
toggle raw diff