Commit ae470168008a38c7f18a8620f0256e9533855b3f

Merge branch 'master' into archive

Commit diff

TODO.txt

 
1events:
2* 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).
3- 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
5
6new-ui:
7* show outstanding mergerequests on dashboard
8* mandatory project descriptions, at least a sentence or two
9* tweak fonts-sizes and line-heights
10* Clone stats graph on repositories#index
11* popular & active projects on frontpage
12* make the top-header smaller (move gitorious logo to footer?)
13
114(in no particular order)
215
316two from Yurii:
1919
2020* tree browser: deal better with funny characters: http://gitorious.org/projects/avara/repos/mainline/trees/master
2121* if you comment on a specific commit, you should get redirected back there
22* graphs should show username (if we have it) for avoiding confusion and for consistency
23** Repository#commit_graph_data_by_author should just use git-shortlog summary instead of jumping through hoops about it
2422
2523> If you do `git archive --format=tar --prefix=myproject/ HEAD | gzip >
2624> myproject.tar.gz`, when .gitattributes specifies files that have
2727> it'd be pretty nice if it did.
2828
2929* Deal gracefully with markdown errors (and/or look into using the other markdown libary instead)
30* Don't generate graphs with big "No Data", text even if there's no data
3130* Markdownify atom feed body for projects.atom
3231* Make the fact that you _can_ clone/fork any repo more visible, maybe reword it since people confuse it with local cloning
3332* Show the most recent mergerequests on users dashboard so they can track them
4242* Nicer diff stats
4343* more interesting project stats on frontpage
4444* parse git submodule data and link to project if submodule is in gitorious
45* link to users in gitorious in commmits if email match
4645* add mainline as a remote branch in clones
4746* timezone support
4847* Email source_repository owner about merge_request changes
toggle raw diff

app/controllers/comments_controller.rb

 
2929 @comment.project = @project
3030 respond_to do |format|
3131 if @comment.save
32 @project.create_event(Action::COMMENT, @comment, current_user)
3233 format.html do
3334 flash[:success] = "Your comment was added"
3435 redirect_to project_repository_comments_path(@project, @repository)
toggle raw diff

app/controllers/committers_controller.rb

 
2121
2222 respond_to do |format|
2323 if @repository.add_committer(@committer)
24 @committership = @repository.committerships.find_by_user_id(@committer.id)
25 @project.create_event(Action::ADD_COMMITTER, @committership, current_user)
2426 format.html { redirect_to([@repository.project, @repository]) }
2527 format.xml do
2628 render :xml => @committer
4040
4141 respond_to do |format|
4242 if @committership.destroy
43 @project.create_event(Action::REMOVE_COMMITTER, @repository, current_user, params[:id])
4344 flash[:success] = "User removed from repository"
4445 format.html { redirect_to [@repository.project, @repository] }
4546 format.xml { render :nothing, :status => :ok }
toggle raw diff

app/controllers/events_controller.rb

 
1class EventsController < ApplicationController
2 def index
3 @events = Event.paginate(:all, :order => "events.created_at desc",
4 :page => params[:page], :include => [:user])
5 @atom_auto_discovery_url = formatted_events_path(:atom)
6
7 respond_to do |if_format_is|
8 if_format_is.html {}
9 if_format_is.atom {}
10 end
11 end
12
13end
toggle raw diff

app/controllers/merge_requests_controller.rb

 
3131 @merge_request.user = current_user
3232 respond_to do |format|
3333 if @merge_request.save
34 @project.create_event(Action::REQUEST_MERGE, @merge_request, current_user)
3435 format.html {
3536 flash[:success] = %Q{You sent a merge request to "#{@merge_request.target_repository.name}"}
3637 redirect_to project_repository_path(@project, @repository) and return
5151 # TODO: put to change status
5252 @merge_request.status = params[:merge_request][:status]
5353 if @merge_request.save
54 @project.create_event(Action::RESOLVE_MERGE_REQUEST, @merge_request, current_user)
5455 flash[:notice] = "The merge request was marked as #{@merge_request.status_string}"
5556 end
5657 redirect_to [@project, @repository, @merge_request]
6464 def update
6565 @merge_request.attributes = params[:merge_request]
6666 if @merge_request.save
67 @project.create_event(Action::UPDATE_MERGE_REQUEST, @merge_request, current_user)
6768 flash[:success] = "Merge request was updated"
6869 redirect_to [@project, @repository, @merge_request]
6970 else
7575
7676 def destroy
7777 @merge_request.destroy
78 @project.create_event(Action::DELETE_MERGE_REQUEST, @repository, current_user)
7879 flash[:success] = "Merge request was retracted"
7980 redirect_to project_repository_path(@project, @repository)
8081 end
toggle raw diff

app/controllers/projects_controller.rb

 
3131
3232 def show
3333 @project = Project.find_by_slug!(params[:id], :include => [:repositories])
34 @repositories = @project.repositories
34 @mainline_repository = @project.mainline_repository
35 @repositories = @project.repository_clones
36 @events = @project.events.paginate(:all, :page => params[:page],
37 :order => "created_at desc", :include => [:user, :project])
38 @atom_auto_discovery_url = formatted_project_path(@project, :atom)
3539
3640 respond_to do |format|
3741 format.html
38 format.xml { render :xml => @project }
42 format.xml { render :xml => @project }
43 format.atom { }
3944 end
4045 end
4146
5151 @project = Project.new(params[:project])
5252 @project.user = current_user
5353 if @project.save
54 @project.create_event(Action::CREATE_PROJECT, @project, current_user)
5455 redirect_to projects_path
5556 else
5657 render :action => 'new'
7070 end
7171 @project.attributes = params[:project]
7272 if @project.save
73 @project.create_event(Action::UPDATE_PROJECT, @project, current_user)
7374 redirect_to project_path(@project)
7475 else
7576 render :action => 'new'
8484 def destroy
8585 @project = Project.find_by_slug!(params[:id])
8686 if @project.can_be_deleted_by?(current_user)
87 project_title = @project.title
8788 @project.destroy
89 #current_user.create_event(Action::DELETE_PROJECT, nil, project_title)
8890 else
8991 flash[:error] = "You're not the owner of this project, or the project has clones"
9092 end
toggle raw diff

app/controllers/repositories_controller.rb

 
66 session :off, :only => [:writable_by]
77
88 def index
9 redirect_to(project_path(@project))
9 @repositories = @project.repositories.find(:all, :include => [:user, :events, :project])
1010 end
1111
1212 def show
1313 @repository = @project.repositories.find_by_name!(params[:id])
14 @comment_count = @repository.comments.count
15 @merge_request_count = @repository.merge_requests.count_open
16 if @repository.has_commits?
17 @commits = @repository.paginated_commits(@repository.head_candidate.name, page=1)
18 else
19 @commits = []
20 end
14 @events = @repository.events.paginate(:all, :page => params[:page],
15 :order => "created_at desc")
2116
2217 @atom_auto_discovery_url = formatted_project_repository_path(@project, @repository, :atom)
2318 respond_to do |format|
2419 format.html
2520 format.xml { render :xml => @repository }
26 format.atom { render :template => "logs/feed.atom.builder" }
21 format.atom { }
2722 end
2823 end
2924
5656
5757 respond_to do |format|
5858 if @repository.save
59 @project.create_event(Action::CLONE_REPOSITORY, @repository, current_user, @repository_to_clone.id)
60
5961 location = project_repository_path(@project, @repository)
6062 format.html { redirect_to location }
6163 format.xml { render :xml => @repository, :status => :created, :location => location }
8686 def destroy
8787 @repository = @project.repositories.find_by_name!(params[:id])
8888 if @repository.can_be_deleted_by?(current_user)
89 repo_name = @repository.name
8990 flash[:notice] = "The repository was deleted"
9091 @repository.destroy
92 @project.create_event(Action::DELETE_REPOSITORY, @project, current_user, repo_name)
9193 else
9294 flash[:error] = "You're not the owner of this repository"
9395 end
toggle raw diff

app/controllers/site_controller.rb

 
77
88 def dashboard
99 @projects = current_user.projects
10 project_ids = @projects.map(&:id)
11 @recent_comments = Comment.find(:all, :limit => 10,
12 :conditions => ["comments.project_id in (?)", project_ids],
13 :order => "comments.created_at desc", :include => [:user, :repository])
14 @repository_clones = Repository.find(:all, :order => "created_at desc",
15 :conditions => ["project_id in (?) and mainline = ?", project_ids, false])
16
17 @repositories = current_user.repositories.find(:all, :conditions => ["mainline = ?", false])
10 @repositories = current_user.repositories.find(:all,
11 :conditions => ["mainline = ?", false])
12 event_project_ids = (@projects.map(&:id) + @repositories.map(&:project_id)).uniq
13 @events = Event.paginate(:all,
14 :page => params[:page],
15 :conditions => ["events.project_id in (?)", event_project_ids],
16 :order => "events.created_at desc",
17 :include => [:user, :project])
1818 end
1919
2020 def about
toggle raw diff

app/controllers/users_controller.rb

 
77 @user = User.find_by_login!(params[:id])
88 @projects = @user.projects.find(:all, :include => [:tags, { :repositories => :project }])
99 @repositories = @user.repositories.find(:all, :conditions => ["mainline = ?", false])
10 @events = @user.events.paginate(:all,
11 :page => params[:page],
12 :order => "events.created_at desc",
13 :include => [:user, :project])
1014
11 @commits_last_week = 0
12 @projects.map{|p| p.repositories.first }.concat(@repositories).each do |repo|
13 @commits_last_week += repo.count_commits_from_last_week_by_user(@user)
15 @commits_last_week = @user.events.count(:all,
16 :conditions => ["created_at > ? AND action = ?", 7.days.ago, Action::COMMIT])
17 @atom_auto_discovery_url = formatted_feed_user_path(@user, :atom)
18
19 respond_to do |format|
20 format.html { }
21 format.atom { redirect_to formatted_feed_user_path(@user, :atom) }
22 end
23 end
24
25 def feed
26 @user = User.find_by_login!(params[:id])
27 @events = @user.events.find(:all, :order => "events.created_at desc",
28 :include => [:user, :project], :limit => 30)
29 respond_to do |format|
30 format.html { redirect_to user_path(@user) }
31 format.atom { }
1432 end
1533 end
1634
toggle raw diff

app/helpers/application_helper.rb

 
22module ApplicationHelper
33 include TagsHelper
44
5 def feed_icon(url, alt_title = "Atom feed", size = :small)
6 link_to image_tag("feed_12.png", :class => "feed_icon"), url,
7 :alt => alt_title, :title => alt_title
8 end
9
510 def default_css_tag_sizes
611 %w(tag_size_1 tag_size_2 tag_size_3 tag_size_4)
712 end
4343 end
4444 end
4545
46 def submenu_selected_class_if_current?(section)
47 case section
48 when :overview
49 if %w[projects].include?(controller.controller_name )
50 return "selected"
51 end
52 when :repositories
53 if %w[repositories trees logs commits comitters comments merge_requests
54 blobs committers].include?(controller.controller_name )
55 return "selected"
56 end
57 end
58 end
59
4660 def link_to_with_selected(name, options = {}, html_options = nil)
4761 html_options = current_page?(options) ? {:class => "selected"} : nil
4862 link_to(name, options = {}, html_options)
120120 image_tag("graphs/#{filename}")
121121 end
122122 end
123
124 def action_and_body_for_event(event)
125 target = event.target
126 action = ""
127 body = ""
128 category = ""
129 case event.action
130 when Action::CREATE_PROJECT
131 action = "<strong>created project</strong> #{link_to h(target.title), project_path(target)}"
132 body = truncate(target.stripped_description, 100)
133 category = "project"
134 when Action::DELETE_PROJECT
135 action = "<strong>deleted project</strong> #{h(event.data)}"
136 category = "project"
137 when Action::UPDATE_PROJECT
138 action = "<strong>updated project</strong> #{link_to h(target.title), project_path(target)}"
139 category = "project"
140 when Action::CLONE_REPOSITORY
141 original_repo = Repository.find_by_id(event.data.to_i)
142 next if original_repo.nil?
143
144 project = target.project
145
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)}"
147 category = "repository"
148 when Action::DELETE_REPOSITORY
149 action = "<strong>deleted repository</strong> #{link_to h(target.title), project_path(target)}/#{event.data}"
150 category = "project"
151 when Action::COMMIT
152 project = event.project
153 action = "<strong>committed</strong> #{link_to event.data[0,8], project_repository_commit_path(project, target, event.data)} to #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
154 body = link_to(h(truncate(event.body, 150)), project_repository_commit_path(project, target, event.data))
155 category = "commit"
156 when Action::CREATE_BRANCH
157 project = target.project
158 if event.data == "master"
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)}"
160 body = event.body
161 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.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
163 end
164 category = "commit"
165 when Action::DELETE_BRANCH
166 project = target.project
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)}"
168 category = "commit"
169 when Action::CREATE_TAG
170 project = target.project
171 action = "<strong>tagged</strong> #{link_to h(project.slug), project_path(project)}/#{link_to h(target.name), project_repository_url(project, target)}"
172 body = "#{link_to event.data, project_repository_commit_path(project, target, event.data)}<br/>#{event.body}"
173 category = "commit"
174 when Action::DELETE_TAG
175 project = target.project
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)}"
177 category = "commit"
178 when Action::ADD_COMMITTER
179 user = target.user
180 repo = target.repository
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)}"
182 category = "repository"
183 when Action::REMOVE_COMMITTER
184 user = User.find_by_id(event.data.to_i)
185 next unless user
186
187 project = target.project
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)}"
189 category = "repository"
190 when Action::COMMENT
191 project = target.project
192 repo = target.repository
193
194 action = "<strong>commented</strong> on #{link_to h(project.slug), project_path(project)}/#{link_to h(repo.name), project_repository_url(project, repo)}"
195 body = truncate(h(target.body), 150)
196 category = "comment"
197 when Action::REQUEST_MERGE
198 source_repository = target.source_repository
199 project = source_repository.project
200 target_repository = target.target_repository
201
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"
205 when Action::RESOLVE_MERGE_REQUEST
206 source_repository = target.source_repository
207 project = source_repository.project
208 target_repository = target.target_repository
209
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]}"
212 category = "merge_request"
213 when Action::UPDATE_MERGE_REQUEST
214 source_repository = target.source_repository
215 project = source_repository.project
216 target_repository = target.target_repository
217
218 action = "<strong>updated merge request</strong> from #{link_to h(project.title), project_path(project)}/#{link_to h(source_repository.name), project_repository_url(project, source_repository)}"
219 category = "merge_request"
220 when Action::DELETE_MERGE_REQUEST
221 project = target.project
222
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)}"
224 category = "merge_request"
225 end
226
227 [action, body, category]
228 end
229
230 def sidebar_content?
231 !@content_for_sidebar.blank?
232 end
233
234 def render_readme(repository)
235 possibilities = []
236 repository.git.git.ls_tree({:name_only => true}, "master").each do |line|
237 possibilities << line[0, line.length-1] if line =~ /README.*/
238 end
239
240 return "" if possibilities.empty?
241 text = repository.git.git.show({}, "master:#{possibilities.first}")
242 markdown(text) rescue simple_format(sanitize(text))
243 end
244
245 def file_path(repository, filename, head = "master")
246 project_repository_blob_path(repository.project, repository, head, filename)
247 end
123248end
toggle raw diff

app/helpers/events_helper.rb

 
1module EventsHelper
2end
toggle raw diff

app/models/action.rb

 
1class Action
2 CREATE_PROJECT = 0
3 DELETE_PROJECT = 1
4 UPDATE_PROJECT = 2
5 CLONE_REPOSITORY = 3
6 DELETE_REPOSITORY = 4
7 COMMIT = 5
8 CREATE_BRANCH = 6
9 DELETE_BRANCH = 7
10 CREATE_TAG = 8
11 DELETE_TAG = 9
12 ADD_COMMITTER = 10
13 REMOVE_COMMITTER = 11
14 COMMENT = 12
15 REQUEST_MERGE = 13
16 RESOLVE_MERGE_REQUEST = 14
17 UPDATE_MERGE_REQUEST = 15
18 DELETE_MERGE_REQUEST = 16
19
20 def self.name(action_id)
21 case action_id
22 when CREATE_PROJECT
23 "create project"
24 when DELETE_PROJECT
25 "delete project"
26 when UPDATE_PROJECT
27 "update project"
28 when CLONE_REPOSITORY
29 "clone repository"
30 when DELETE_REPOSITORY
31 "delete repository"
32 when COMMIT
33 "commit"
34 when CREATE_BRANCH
35 "create branch"
36 when DELETE_BRANCH
37 "delete branch"
38 when CREATE_TAG
39 "create tag"
40 when DELETE_TAG
41 "delete tag"
42 when ADD_COMMITTER
43 "add committer"
44 when REMOVE_COMMITTER
45 "remove committer"
46 when COMMENT
47 "comment"
48 when REQUEST_MERGE
49 "request merge"
50 when RESOLVE_MERGE_REQUEST
51 "resolve merge request"
52 when UPDATE_MERGE_REQUEST
53 "update merge request"
54 when DELETE_MERGE_REQUEST
55 "delete merge request"
56 end
57 end
58end
toggle raw diff