merging upstream changes

3-1-stable
Steven Verbeek 2012-03-19 21:57:29 -03:00
commit 35d0de8f36
49 changed files with 512 additions and 169 deletions

View File

@ -11,6 +11,7 @@
//= require jquery.tagify
//= require jquery.cookie
//= require jquery.endless-scroll
//= require jquery.highlight
//= require bootstrap-modal
//= require modernizr
//= require chosen

View File

@ -11,7 +11,7 @@ var MergeRequest = {
$(".tabs a.merge-notes-tab").live("click", function(e) {
$(".merge-request-diffs").hide();
$(".merge-request-notes").show();
$(".merge_request_notes").show();
e.preventDefault();
});
@ -19,7 +19,7 @@ var MergeRequest = {
if(!MergeRequest.diffs_loaded) {
MergeRequest.loadDiff();
}
$(".merge-request-notes").hide();
$(".merge_request_notes").hide();
$(".merge-request-diffs").show();
e.preventDefault();
});
@ -33,7 +33,7 @@ var MergeRequest = {
url: $(".merge-diffs-tab").attr("data-url"),
complete: function(){
MergeRequest.diffs_loaded = true;
$(".merge-request-notes").hide();
$(".merge_request_notes").hide();
$(".dashboard-loader").hide()},
dataType: "script"});
}

View File

@ -3,7 +3,7 @@ a {
color: $link_color;
&:hover {
text-decoration:none;
color: $style_color;
color: $blue_link;
}
&.btn {
@ -11,6 +11,18 @@ a {
}
}
.btn {
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), color-stop(25%, #f1f1f1), to(#e6e6e6));
background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: -ms-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: -o-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
&:hover {
}
}
a:focus {
outline: none;
}
@ -29,6 +41,29 @@ a:focus {
.label {
background-color: #474D57;
&.pushed {
background-color: $link_color;
}
}
.pretty_label {
@include round-borders-all(4px);
padding:2px 4px;
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
color: #777;
border: 1px solid #DEDFE1;
&.branch {
border:none;
font-size:13px;
background: #474D57;
color:#fff;
font-family: monospace;
}
}
.tabs > li > a, .pills > li > a {
@ -807,12 +842,19 @@ p.time {
width:840px;
margin:auto;
.wll {
padding:5px;
margin-top:5px;
.dash_project_item {
margin-bottom:10px;
border:none;
&:hover {
background:none;
h4 {
color:#2FA0BB;
.arrow {
background:#2FA0BB;
color:#fff;
}
}
}
h4 {
@ -887,7 +929,7 @@ p.time {
}
a:last-child h4 { border:none; }
a.active {
a:hover {
h4 {
color:#111;
border-right:4px solid $styled_border_color;
@ -974,3 +1016,32 @@ p.time {
}
}
}
.highlight_word {
background:#EEDC94;
}
.status_info {
font-size:14px;
padding:5px 15px;
line-height:24px;
width:60px;
text-align:center;
float:left;
margin-right:20px;
}
.merge_request_status_holder {
margin-bottom:20px;
}
.arrow{
float: right;
background: #E3E5EA;
padding: 10px;
border-radius: 5px;
text-shadow: none;
color: #999;
line-height: 16px;
font-weight:bold;
}

View File

@ -15,7 +15,7 @@ $app_padding:20px;
$bg_color: #FFF;
$styled_border_color: #2FA0BB;
$color: "#4BB8D2";
$blue_link: "#2fa0bb";
$blue_link: #2fa0bb;
/** Style colors **/

View File

@ -17,7 +17,7 @@
color: $link_color;
&:hover {
text-decoration:none;
color: $style_color;
color: $blue_link;
}
}

View File

@ -18,7 +18,7 @@ class DashboardController < ApplicationController
# Get authored or assigned open merge requests
def merge_requests
@projects = current_user.projects.all
@merge_requests = MergeRequest.where("author_id = :id or assignee_id = :id", :id => current_user.id).opened.order("created_at DESC").limit(40)
@merge_requests = current_user.cared_merge_requests.order("created_at DESC").limit(40)
end
# Get only assigned issues

View File

@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController
@note = @project.notes.new(:noteable => @merge_request)
@commits = @project.repo.
commits_between(@merge_request.target_branch, @merge_request.source_branch).
map {|c| Commit.new(c)}.
sort_by(&:created_at).
reverse
render_full_content
# Get commits from repository
# or from cache if already merged
@commits = @merge_request.commits
respond_to do |format|
format.html
@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController
respond_to do |format|
if @merge_request.save
@merge_request.reload_code
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' }
format.json { render json: @merge_request, status: :created, location: @merge_request }
else
@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController
def update
respond_to do |format|
if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id))
@merge_request.reload_code
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' }
format.json { head :ok }
else

View File

@ -13,6 +13,7 @@ class ProjectsController < ApplicationController
def index
@projects = current_user.projects
@projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse
@events = Event.where(:project_id => @projects.map(&:id)).recent.limit(40)
end
def new
@ -78,7 +79,6 @@ class ProjectsController < ApplicationController
render "projects/empty"
end
end
format.js
end
end

View File

@ -0,0 +1,12 @@
class SearchController < ApplicationController
def show
query = params[:search]
if query.blank?
@projects = []
@merge_requests = []
else
@projects = Project.search(query).limit(10)
@merge_requests = MergeRequest.search(query).limit(10)
end
end
end

View File

@ -7,6 +7,7 @@ class Event < ActiveRecord::Base
Reopened = 4
Pushed = 5
Commented = 6
Merged = 7
belongs_to :project
belongs_to :target, :polymorphic => true

View File

@ -1,9 +1,14 @@
require File.join(Rails.root, "app/models/commit")
class MergeRequest < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User"
has_many :notes, :as => :noteable, :dependent => :destroy
serialize :st_commits
serialize :st_diffs
attr_protected :author, :author_id, :project, :project_id
attr_accessor :author_id_of_changes
@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base
scope :closed, where(:closed => true)
scope :assigned, lambda { |u| where(:assignee_id => u.id)}
def self.search query
where("title like :query", :query => "%#{query}%")
end
def self.find_all_by_branch(branch_name)
where("source_branch like :branch or target_branch like :branch", :branch => branch_name)
end
def validate_branches
if target_branch == source_branch
@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base
end
end
def reload_code
self.reloaded_commits
self.reloaded_diffs
end
def new?
today? && created_at == updated_at
end
def diffs
st_diffs || []
end
def reloaded_diffs
if open? && unmerged_diffs.any?
self.st_diffs = unmerged_diffs
save
end
diffs
end
def unmerged_diffs
commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
end
def last_commit
project.commit(source_branch)
commits.first
end
def merged?
merged && merge_event
end
def merge_event
self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Merged).last
end
def closed_event
self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Closed).last
end
# Return the number of +1 comments (upvotes)
def upvotes
notes.select(&:upvote?).size
end
def commits
st_commits || []
end
def probably_merged?
unmerged_commits.empty? &&
commits.any? && open?
end
def open?
!closed
end
def mark_as_merged!
self.merged = true
self.closed = true
save
end
def reloaded_commits
if open? && unmerged_commits.any?
self.st_commits = unmerged_commits
save
end
commits
end
def unmerged_commits
self.project.repo.
commits_between(self.target_branch, self.source_branch).
map {|c| Commit.new(c)}.
sort_by(&:created_at).
reverse
end
def merge!(user_id)
self.mark_as_merged!
Event.create(
:project => self.project,
:action => Event::Merged,
:target_id => self.id,
:target_type => "MergeRequest",
:author_id => user_id
)
end
end
# == Schema Information
#

View File

@ -54,6 +54,10 @@ class Project < ActiveRecord::Base
UsersProject.access_roles
end
def self.search query
where("name like :query or code like :query or path like :query", :query => "%#{query}%")
end
def to_param
code
end
@ -73,6 +77,24 @@ class Project < ActiveRecord::Base
)
end
def update_merge_requests(oldrev, newrev, ref, author_key_id)
return true unless ref =~ /heads/
branch_name = ref.gsub("refs/heads/", "")
user = Key.find_by_identifier(author_key_id).user
c_ids = self.commits_between(oldrev, newrev).map(&:id)
# Update code for merge requests
mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
mrs.each { |merge_request| merge_request.reload_code }
# Close merge requests
mrs = self.merge_requests.opened.where(:target_branch => branch_name).all
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
mrs.each { |merge_request| merge_request.merge!(user.id) }
true
end
def execute_web_hooks(oldrev, newrev, ref, author_key_id)
ref_parts = ref.split('/')

View File

@ -86,6 +86,10 @@ class User < ActiveRecord::Base
)
end
end
def cared_merge_requests
MergeRequest.where("author_id = :id or assignee_id = :id", :id => self.id).opened
end
end
# == Schema Information
#

View File

@ -12,8 +12,8 @@
= @commit.committer_name
%small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm")
%hr
%pre.commit_message
%br
%pre.commit_message.prettyprint
= commit_msg_with_link_to_issues(@project, @commit.safe_message)
.clear
%br

View File

@ -1,2 +0,0 @@
= render @events

View File

@ -3,8 +3,10 @@
= link_to [issue.project, issue] do
%p
%strong
%span.label= issue.project.name
%span.pretty_label= issue.project.name
&ndash;
Issue #
= issue.id
= truncate issue.title, :length => 50
%span.right.cgray
= issue.updated_at.stamp("Aug 21, 2011")

View File

@ -3,8 +3,9 @@
= link_to [merge_request.project, merge_request] do
%p
%strong
%span.label= merge_request.project.name
%span.pretty_label= merge_request.project.name
&ndash;
Merge Request #
= merge_request.id
Merge Request ##{merge_request.id}
= truncate merge_request.title, :length => 50
%span.right.cgray
= merge_request.updated_at.stamp("Aug 21, 2011")

View File

@ -1,5 +1,5 @@
- @active_projects.first(5).each do |project|
.wll
- projects.first(5).each do |project|
%div.dash_project_item
= link_to project do
%h4
%span.ico.project
@ -7,3 +7,5 @@
%small
last activity at
= project.last_activity_date.stamp("Aug 25, 2011")
%span.right.arrow
&rarr;

View File

@ -20,7 +20,7 @@
.row
.dashboard_block
.row
.span10= render "dashboard/projects_feed"
.span10= render "dashboard/projects_feed", :projects => @active_projects
.span4.right
- if current_user.can_create_project?
.alert-message.block-message.warning
@ -65,4 +65,4 @@
%hr
.row
.dashboard_block= render "dashboard/events_feed"
.dashboard_block= render @events

View File

@ -1,10 +1,11 @@
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
- if event.closed?
closed
- else
reopened
issue
%span.label.important
- if event.closed?
closed
- else
reopened
&nbsp;issue
= link_to project_issue_path(event.project, event.issue) do
%strong= truncate event.issue_title
at

View File

@ -1,10 +1,11 @@
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
- if event.closed?
closed
- else
reopened
merge request
%span.label.important
- if event.closed?
closed
- else
reopened
&nbsp;merge request
= link_to project_merge_request_path(event.project, event.merge_request) do
%strong= truncate event.merge_request_title
at
@ -12,7 +13,6 @@ at
%span.cgray
= time_ago_in_words(event.created_at)
ago.
%br
%span.label= event.merge_request.source_branch
&rarr;
%span.label= event.merge_request.target_branch

View File

@ -1,6 +1,7 @@
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
created new issue
%span.label.success created
&nbsp;new issue
= link_to project_issue_path(event.project, event.issue) do
%strong= truncate event.issue_title
at

View File

@ -1,6 +1,7 @@
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
requested merge
%span.label.success requested
&nbsp;merge
= link_to project_merge_request_path(event.project, event.merge_request) do
%strong= truncate event.merge_request_title
at
@ -8,7 +9,6 @@ at
%span.cgray
= time_ago_in_words(event.created_at)
ago.
%br
%span.label= event.merge_request.source_branch
&rarr;
%span.label= event.merge_request.target_branch

View File

@ -1,7 +1,8 @@
- if event.new_branch? || event.new_tag?
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
pushed new
%span.label.pushed pushed
&nbsp;new
- if event.new_tag?
tag
= link_to project_commits_path(event.project, :ref => event.tag_name) do
@ -18,7 +19,8 @@
- else
= image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name}
pushed to
%span.label.pushed pushed
&nbsp;to
= link_to project_commits_path(event.project, :ref => event.branch_name) do
%strong= event.branch_name
at
@ -30,10 +32,10 @@
= link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do
Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]}
- @project = event.project
%ul.unstyled
- if event.commits.size > 4
= render event.commits[0..2]
%li ... and #{event.commits.size - 3} more commits
%ul.unstyled.event_commits
- if event.commits.size > 3
= render event.commits[0...2]
%li ... and #{event.commits.size - 2} more commits
- else
= render event.commits

View File

@ -1,6 +1,11 @@
%nav.main_menu
= render "layouts/const_menu_links"
= link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}"
= link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide"
= link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide"
= link_to dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" do
Issues
%span.count= current_user.assigned_issues.opened.count
= link_to dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" do
Requests
%span.count= current_user.cared_merge_requests.count
= link_to "Search", search_path, :class => "#{"current" if current_page?(search_path)}"
= link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}"

View File

@ -7,7 +7,9 @@
%h1
GITLAB
%h1.project_name= title
.search= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
.search
= form_tag search_path, :method => :get do |f|
= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
- if current_user.is_admin?
= link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do
= image_tag "admin.PNG", :width => 16

View File

@ -2,7 +2,9 @@
.ui-box
%h5 Commits
.merge-request-commits
%ul.unstyled= render @commits
%ul.unstyled
- @commits.each do |commit|
= render "commits/commit", :commit => commit
- else
%h5

View File

@ -15,7 +15,7 @@
:javascript
$(function(){
var modal = $('#modal_merge_info').modal({modal: true});
$('.info_link').bind("click", function(){
$('.how_to_merge_link').bind("click", function(){
modal.show();
});
$('.modal-header .close').bind("click", function(){

View File

@ -6,7 +6,7 @@
= time_ago_in_words(merge_request.created_at)
ago
- if merge_request.notes.any?
%span.label= pluralize merge_request.notes.count, 'note'
%span.pretty_label= pluralize merge_request.notes.count, 'note'
- if merge_request.upvotes > 0
%span.label.success= "+#{merge_request.upvotes}"
.right

View File

@ -1,9 +1,9 @@
%h3
= "Merge Request ##{@merge_request.id}:"
&nbsp;
%span.label= @merge_request.source_branch
%span.pretty_label.branch= @merge_request.source_branch
&rarr;
%span.label= @merge_request.target_branch
%span.pretty_label.branch= @merge_request.target_branch
%small
created at
@ -11,12 +11,10 @@
%span.right
- if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.closed
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "btn"
- else
- if @merge_request.open?
= link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close merge request"
= link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do
Edit
= link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do
Edit
%br
- if @merge_request.upvotes > 0
@ -28,17 +26,27 @@
%hr
- if @merge_request.closed
.alert-message.error Closed
- else
.alert-message.success
= link_to "#", :class => "info_link", :title => "How To Merge" do
= image_tag "Info-UI.PNG"
Open
.merge_request_status_holder
- if @merge_request.closed
%h5
.alert-message.error.status_info Closed
- if @merge_request.merged?
%span
Merged by #{@merge_request.merge_event.author_name}
%small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
- elsif @merge_request.closed_event
%span
Closed by #{@merge_request.closed_event.author_name}
%small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago.
%br
- else
%h5
.alert-message.success.status_info Open
= link_to "How to merge", "#", :class => "vlink how_to_merge_link", :title => "How To Merge"
= render "merge_requests/how_to_merge"
%div.well
%div.well.prettyprint
%div
%cite.cgray Created by
= image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"

View File

@ -1,42 +1,46 @@
%h3 Password
%hr
= form_for @user, :url => profile_password_path, :method => :put do |f|
.data
.alert-message.block-message.warning
%p After successfull password update you will be redirected to login page where you should login with new password
-if @user.errors.any?
.alert-message.block-message.error
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
.clearfix
= f.label :password
.input= f.password_field :password
.clearfix
= f.label :password_confirmation
.input= f.password_field :password_confirmation
.actions
= f.submit 'Save', :class => "btn"
%h3
Private token
%span.cred.right
keep it in secret!
%hr
= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
.data
%p Private token used to access application resources without authentication.
%p For example its required to access commits feed.
.row
.span8
%h3 Password
%hr
%p.cgray
- if current_user.private_token
= text_field_tag "token", current_user.private_token
- else
You don`t have one yet. Click generate to fix it.
.actions
- if current_user.private_token
= f.submit 'Reset', :confirm => "Are you sure?", :class => "btn"
- else
= f.submit 'Generate', :class => "btn"
= form_for @user, :url => profile_password_path, :method => :put do |f|
.data
.alert-message.block-message.warning
%p After successfull password update you will be redirected to login page where you should login with new password
-if @user.errors.any?
.alert-message.block-message.error
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
.clearfix
= f.label :password
.input= f.password_field :password
.clearfix
= f.label :password_confirmation
.input= f.password_field :password_confirmation
.actions
= f.submit 'Save', :class => "btn"
.span7.right
%h3
Private token
%span.cred.right
keep it in secret!
%hr
= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
.data
.alert-message.block-message.warning
%p Private token used to access application resources without authentication.
%hr
%p * required for rss feed
%p.cgray
- if current_user.private_token
= text_field_tag "token", current_user.private_token
- else
You don`t have one yet. Click generate to fix it.
.actions
- if current_user.private_token
= f.submit 'Reset', :confirm => "Are you sure?", :class => "btn"
- else
= f.submit 'Generate', :class => "btn"

View File

@ -1,4 +1,4 @@
%h4.title
%h5.title
= @project.name
%br
%div

View File

@ -6,7 +6,7 @@
%li Visit profile &rarr; keys and add public key of every machine you want to use for work with gitlabhq.
.alert-message.block-message.error
%ul.alert_holder
%ul.unstyled.alert_holder
%li You should push repository to proceed.
%li After push you will be able to browse code, commits etc.

View File

@ -1,22 +1,25 @@
- if @projects.any?
.row
.span4
.span11
= render @events
.span5.right
%div.leftbar.ui-box
%h5
Projects
%small
(#{@projects.count})
- if current_user.can_create_project?
%span.right
= link_to new_project_path, :class => "btn very_small info" do
New Project
.content_list
- @projects.each do |project|
= link_to project_path(project), :remote => true, :class => dom_class(project) do
= link_to project_path(project), :class => dom_class(project) do
%h4
%span.ico.project
= truncate(project.name, :length => 22)
.span12.right
.show_holder.ui-box.padded
.loading
= truncate(project.name, :length => 25)
%span.right
&rarr;
- else
%h3 Nothing here
@ -31,20 +34,3 @@
New Project »
- else
If you will be added to project - it will be displayed here
:javascript
$(function(){
$("a.project").live("ajax:before", function() {
$(".show_holder").html("<div class='loading'>");
$('a.project').removeClass("active");
$(this).addClass("active");
});
$('a.project:first-child').trigger("click");
});
- if @projects.count == @limit
:javascript
$(function(){
Pager.init(#{@limit});
});

View File

@ -21,9 +21,13 @@
= text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url"
- if @project.description.present?
= markdown @project.description
.prettyprint= markdown @project.description
- unless @events.blank?
%h5.cgray Recent Activity
%br
%h5.cgray
%span.ico.activities
Recent Activity
%hr
.content_list= render @events

View File

@ -1,7 +0,0 @@
- if @project.repo_exists? && @project.has_commits?
:plain
$(".show_holder").html("#{escape_javascript(render(:partial => 'projects/show'))}");
- else
:plain
$(".show_holder").html("#{escape_javascript(render(:template => 'projects/empty'))}");

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,41 @@
= form_tag search_path, :method => :get do |f|
.padded
= label_tag :search, "Looking for"
.input
= text_field_tag :search, params[:search],:placeholder => "issue 143", :class => "xxlarge"
= submit_tag 'Search', :class => "btn primary"
- if params[:search].present?
%br
%h3 Search results
%hr
.search_results
- if @projects.empty? && @merge_requests.empty?
%h3
%small Nothing here
- else
- if @projects.any?
- @projects.each do |project|
= link_to project do
%h4
%span.ico.project
= project.name
%small
last activity at
= project.last_activity_date.stamp("Aug 25, 2011")
- if @merge_requests.any?
- @merge_requests.each do |merge_request|
= link_to [merge_request.project, merge_request] do
%h5
Merge Request #
= merge_request.id
&ndash;
= truncate merge_request.title, :length => 50
%small
updated at
= merge_request.updated_at.stamp("Aug 25, 2011")
%strong
%span.label= merge_request.project.name
:javascript
$(function() {
$(".search_results").highlight("#{params[:search]}");
})

View File

@ -8,7 +8,13 @@ class PostReceive
# Ignore push from non-gitlab users
return false unless Key.find_by_identifier(author_key_id)
# Create push event
project.observe_push(oldrev, newrev, ref, author_key_id)
# Close merged MR
project.update_merge_requests(oldrev, newrev, ref, author_key_id)
# Execute web hooks
project.execute_web_hooks(oldrev, newrev, ref, author_key_id)
end
end

View File

@ -1,5 +1,5 @@
Gitlab::Application.routes.draw do
get 'search' => "search#show"
# Optionally, enable Resque here
require 'resque/server'
@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do
get "dashboard", :to => "dashboard#index"
get "dashboard/issues", :to => "dashboard#issues"
get "dashboard/merge_requests", :to => "dashboard#merge_requests"
get "dashboard/activities", :to => "dashboard#activities"
#get "profile/:id", :to => "profile#show"

View File

@ -0,0 +1,6 @@
class AddCommitsDiffStoreToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :st_commits, :text, :null => true
add_column :merge_requests, :st_diffs, :text, :null => true
end
end

View File

@ -0,0 +1,5 @@
class AddMergedToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :merged, :boolean, :null => false, :default => false
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120307095918) do
ActiveRecord::Schema.define(:version => 20120315132931) do
create_table "events", :force => true do |t|
t.string "target_type"
@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do
t.boolean "closed", :default => false, :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.text "st_commits"
t.text "st_diffs"
t.boolean "merged", :default => false, :null => false
end
add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id"

View File

@ -209,7 +209,7 @@ Application can be started with next command:
cd /home/gitlab/gitlab
sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb
sudo -u gitlab unicorn_rails -c config/unicorn.rb -E production -D
sudo -u gitlab bundle exec unicorn_rails -c config/unicorn.rb -E production -D
Edit /etc/nginx/nginx.conf. Add next code to **http** section:
@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab:
NAME=unicorn
DESC="Gitlab service"
PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
case "$1" in
start)
CD_TO_APP_DIR="cd /home/gitlab/gitlab"
START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS"
START_RESQUE_PROCESS="./resque.sh"
echo -n "Starting $DESC: "
if [ `whoami` = root ]; then
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS"
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS"
else
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
kill -QUIT `cat $PID`
kill -QUIT `cat $RESQUE_PID`
echo "$NAME."
;;
restart)
echo -n "Restarting $DESC: "
kill -USR2 `cat $PID`
kill -USR2 `cat $RESQUE_PID`
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID`
kill -HUP `cat $RESQUE_PID`
echo "$NAME."
;;
*)

View File

@ -1,2 +1,2 @@
mkdir tmp/pids
nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid & >> log/resque_worker.log 2>&1

View File

@ -160,6 +160,34 @@ describe Project do
end
end
end
describe :update_merge_requests do
let(:project) { Factory :project }
before do
@merge_request = Factory :merge_request,
:project => project,
:merged => false,
:closed => false
@key = Factory :key, :user_id => project.owner.id
end
it "should close merge request if last commit from source branch was pushed to target branch" do
@merge_request.reloaded_commits
@merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.identifier)
@merge_request.reload
@merge_request.merged.should be_true
@merge_request.closed.should be_true
end
it "should update merge request commits with new one if pushed to source branch" do
@merge_request.last_commit.should == nil
project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.identifier)
@merge_request.reload
@merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
end
end
end
# == Schema Information
#

View File

@ -1,6 +1,4 @@
require 'spec_helper'
__END__
# Disabled for now
describe "Dashboard" do
before do
@project = Factory :project
@ -22,19 +20,7 @@ describe "Dashboard" do
end
it "should have projects panel" do
within ".project-list" do
page.should have_content(@project.name)
end
page.should have_content(@project.name)
end
# Temporary disabled cause of travis
# TODO: fix or rewrite
#it "should have news feed" do
#within "#news-feed" do
#page.should have_content("commit")
#page.should have_content(@project.commit.author.name)
#page.should have_content(@project.commit.safe_message)
#end
#end
end
end

View File

@ -42,7 +42,7 @@ describe "MergeRequests" do
it { should have_content(@merge_request.title[0..10]) }
it "Show page should inform user that merge request closed" do
page.should have_content "Reopen"
page.should have_content "Closed"
end
end
end

View File

@ -0,0 +1,53 @@
/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight_word';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.each(function() {
innerHighlight(this, pat.toUpperCase());
});
};
jQuery.fn.removeHighlight = function() {
return this.find("span.highlight").each(function() {
this.parentNode.firstChild.nodeName;
with (this.parentNode) {
replaceChild(this.firstChild, this);
normalize();
}
}).end();
};