Commit 35d0de8f authored by Steven Verbeek's avatar Steven Verbeek

merging upstream changes

parents 2a7cd2f1 cadf12c6
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
//= require jquery.tagify //= require jquery.tagify
//= require jquery.cookie //= require jquery.cookie
//= require jquery.endless-scroll //= require jquery.endless-scroll
//= require jquery.highlight
//= require bootstrap-modal //= require bootstrap-modal
//= require modernizr //= require modernizr
//= require chosen //= require chosen
......
...@@ -11,7 +11,7 @@ var MergeRequest = { ...@@ -11,7 +11,7 @@ var MergeRequest = {
$(".tabs a.merge-notes-tab").live("click", function(e) { $(".tabs a.merge-notes-tab").live("click", function(e) {
$(".merge-request-diffs").hide(); $(".merge-request-diffs").hide();
$(".merge-request-notes").show(); $(".merge_request_notes").show();
e.preventDefault(); e.preventDefault();
}); });
...@@ -19,7 +19,7 @@ var MergeRequest = { ...@@ -19,7 +19,7 @@ var MergeRequest = {
if(!MergeRequest.diffs_loaded) { if(!MergeRequest.diffs_loaded) {
MergeRequest.loadDiff(); MergeRequest.loadDiff();
} }
$(".merge-request-notes").hide(); $(".merge_request_notes").hide();
$(".merge-request-diffs").show(); $(".merge-request-diffs").show();
e.preventDefault(); e.preventDefault();
}); });
...@@ -33,7 +33,7 @@ var MergeRequest = { ...@@ -33,7 +33,7 @@ var MergeRequest = {
url: $(".merge-diffs-tab").attr("data-url"), url: $(".merge-diffs-tab").attr("data-url"),
complete: function(){ complete: function(){
MergeRequest.diffs_loaded = true; MergeRequest.diffs_loaded = true;
$(".merge-request-notes").hide(); $(".merge_request_notes").hide();
$(".dashboard-loader").hide()}, $(".dashboard-loader").hide()},
dataType: "script"}); dataType: "script"});
} }
......
...@@ -3,7 +3,7 @@ a { ...@@ -3,7 +3,7 @@ a {
color: $link_color; color: $link_color;
&:hover { &:hover {
text-decoration:none; text-decoration:none;
color: $style_color; color: $blue_link;
} }
&.btn { &.btn {
...@@ -11,6 +11,18 @@ a { ...@@ -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 { a:focus {
outline: none; outline: none;
} }
...@@ -29,6 +41,29 @@ a:focus { ...@@ -29,6 +41,29 @@ a:focus {
.label { .label {
background-color: #474D57; 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 { .tabs > li > a, .pills > li > a {
...@@ -807,12 +842,19 @@ p.time { ...@@ -807,12 +842,19 @@ p.time {
width:840px; width:840px;
margin:auto; margin:auto;
.wll { .dash_project_item {
padding:5px; margin-bottom:10px;
margin-top:5px;
border:none; border:none;
&:hover { &:hover {
background:none; background:none;
h4 {
color:#2FA0BB;
.arrow {
background:#2FA0BB;
color:#fff;
}
}
} }
h4 { h4 {
...@@ -887,7 +929,7 @@ p.time { ...@@ -887,7 +929,7 @@ p.time {
} }
a:last-child h4 { border:none; } a:last-child h4 { border:none; }
a.active { a:hover {
h4 { h4 {
color:#111; color:#111;
border-right:4px solid $styled_border_color; border-right:4px solid $styled_border_color;
...@@ -974,3 +1016,32 @@ p.time { ...@@ -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;
}
...@@ -15,7 +15,7 @@ $app_padding:20px; ...@@ -15,7 +15,7 @@ $app_padding:20px;
$bg_color: #FFF; $bg_color: #FFF;
$styled_border_color: #2FA0BB; $styled_border_color: #2FA0BB;
$color: "#4BB8D2"; $color: "#4BB8D2";
$blue_link: "#2fa0bb"; $blue_link: #2fa0bb;
/** Style colors **/ /** Style colors **/
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
color: $link_color; color: $link_color;
&:hover { &:hover {
text-decoration:none; text-decoration:none;
color: $style_color; color: $blue_link;
} }
} }
......
...@@ -18,7 +18,7 @@ class DashboardController < ApplicationController ...@@ -18,7 +18,7 @@ class DashboardController < ApplicationController
# Get authored or assigned open merge requests # Get authored or assigned open merge requests
def merge_requests def merge_requests
@projects = current_user.projects.all @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 end
# Get only assigned issues # Get only assigned issues
......
...@@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController ...@@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController
@note = @project.notes.new(:noteable => @merge_request) @note = @project.notes.new(:noteable => @merge_request)
@commits = @project.repo. # Get commits from repository
commits_between(@merge_request.target_branch, @merge_request.source_branch). # or from cache if already merged
map {|c| Commit.new(c)}. @commits = @merge_request.commits
sort_by(&:created_at).
reverse
render_full_content
respond_to do |format| respond_to do |format|
format.html format.html
...@@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController ...@@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController
respond_to do |format| respond_to do |format|
if @merge_request.save if @merge_request.save
@merge_request.reload_code
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' } format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' }
format.json { render json: @merge_request, status: :created, location: @merge_request } format.json { render json: @merge_request, status: :created, location: @merge_request }
else else
...@@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController ...@@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController
def update def update
respond_to do |format| respond_to do |format|
if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id)) 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.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' }
format.json { head :ok } format.json { head :ok }
else else
......
...@@ -13,6 +13,7 @@ class ProjectsController < ApplicationController ...@@ -13,6 +13,7 @@ class ProjectsController < ApplicationController
def index def index
@projects = current_user.projects @projects = current_user.projects
@projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse @projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse
@events = Event.where(:project_id => @projects.map(&:id)).recent.limit(40)
end end
def new def new
...@@ -78,7 +79,6 @@ class ProjectsController < ApplicationController ...@@ -78,7 +79,6 @@ class ProjectsController < ApplicationController
render "projects/empty" render "projects/empty"
end end
end end
format.js
end end
end end
......
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
...@@ -7,6 +7,7 @@ class Event < ActiveRecord::Base ...@@ -7,6 +7,7 @@ class Event < ActiveRecord::Base
Reopened = 4 Reopened = 4
Pushed = 5 Pushed = 5
Commented = 6 Commented = 6
Merged = 7
belongs_to :project belongs_to :project
belongs_to :target, :polymorphic => true belongs_to :target, :polymorphic => true
......
require File.join(Rails.root, "app/models/commit")
class MergeRequest < ActiveRecord::Base class MergeRequest < ActiveRecord::Base
belongs_to :project belongs_to :project
belongs_to :author, :class_name => "User" belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User" belongs_to :assignee, :class_name => "User"
has_many :notes, :as => :noteable, :dependent => :destroy has_many :notes, :as => :noteable, :dependent => :destroy
serialize :st_commits
serialize :st_diffs
attr_protected :author, :author_id, :project, :project_id attr_protected :author, :author_id, :project, :project_id
attr_accessor :author_id_of_changes attr_accessor :author_id_of_changes
...@@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base ...@@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base
scope :closed, where(:closed => true) scope :closed, where(:closed => true)
scope :assigned, lambda { |u| where(:assignee_id => u.id)} 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 def validate_branches
if target_branch == source_branch if target_branch == source_branch
...@@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base ...@@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base
end end
end end
def reload_code
self.reloaded_commits
self.reloaded_diffs
end
def new? def new?
today? && created_at == updated_at today? && created_at == updated_at
end end
def diffs 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)} 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 [] diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
end end
def last_commit 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 end
# Return the number of +1 comments (upvotes) # Return the number of +1 comments (upvotes)
def upvotes def upvotes
notes.select(&:upvote?).size notes.select(&:upvote?).size
end 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 end
# == Schema Information # == Schema Information
# #
......
...@@ -54,6 +54,10 @@ class Project < ActiveRecord::Base ...@@ -54,6 +54,10 @@ class Project < ActiveRecord::Base
UsersProject.access_roles UsersProject.access_roles
end end
def self.search query
where("name like :query or code like :query or path like :query", :query => "%#{query}%")
end
def to_param def to_param
code code
end end
...@@ -73,6 +77,24 @@ class Project < ActiveRecord::Base ...@@ -73,6 +77,24 @@ class Project < ActiveRecord::Base
) )
end 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) def execute_web_hooks(oldrev, newrev, ref, author_key_id)
ref_parts = ref.split('/') ref_parts = ref.split('/')
......
...@@ -86,6 +86,10 @@ class User < ActiveRecord::Base ...@@ -86,6 +86,10 @@ class User < ActiveRecord::Base
) )
end end
end end
def cared_merge_requests
MergeRequest.where("author_id = :id or assignee_id = :id", :id => self.id).opened
end
end end
# == Schema Information # == Schema Information
# #
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
= @commit.committer_name = @commit.committer_name
%small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm") %small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm")
%hr %br
%pre.commit_message %pre.commit_message.prettyprint
= commit_msg_with_link_to_issues(@project, @commit.safe_message) = commit_msg_with_link_to_issues(@project, @commit.safe_message)
.clear .clear
%br %br
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
= link_to [issue.project, issue] do = link_to [issue.project, issue] do
%p %p
%strong %strong
%span.label= issue.project.name %span.pretty_label= issue.project.name
&ndash; &ndash;
Issue # Issue #
= issue.id = issue.id
= truncate issue.title, :length => 50 = truncate issue.title, :length => 50
%span.right.cgray
= issue.updated_at.stamp("Aug 21, 2011")
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
= link_to [merge_request.project, merge_request] do = link_to [merge_request.project, merge_request] do
%p %p
%strong %strong
%span.label= merge_request.project.name %span.pretty_label= merge_request.project.name
&ndash; &ndash;
Merge Request # Merge Request ##{merge_request.id}
= merge_request.id
= truncate merge_request.title, :length => 50 = truncate merge_request.title, :length => 50
%span.right.cgray
= merge_request.updated_at.stamp("Aug 21, 2011")
- @active_projects.first(5).each do |project| - projects.first(5).each do |project|
.wll %div.dash_project_item
= link_to project do = link_to project do
%h4 %h4
%span.ico.project %span.ico.project
...@@ -7,3 +7,5 @@ ...@@ -7,3 +7,5 @@
%small %small
last activity at last activity at
= project.last_activity_date.stamp("Aug 25, 2011") = project.last_activity_date.stamp("Aug 25, 2011")
%span.right.arrow
&rarr;
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
.row .row
.dashboard_block .dashboard_block
.row .row
.span10= render "dashboard/projects_feed" .span10= render "dashboard/projects_feed", :projects => @active_projects
.span4.right .span4.right
- if current_user.can_create_project? - if current_user.can_create_project?
.alert-message.block-message.warning .alert-message.block-message.warning
...@@ -65,4 +65,4 @@ ...@@ -65,4 +65,4 @@
%hr %hr
.row .row
.dashboard_block= render "dashboard/events_feed" .dashboard_block= render @events
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
- if event.closed? %span.label.important
- if event.closed?
closed closed
- else - else
reopened reopened
issue &nbsp;issue
= link_to project_issue_path(event.project, event.issue) do = link_to project_issue_path(event.project, event.issue) do
%strong= truncate event.issue_title %strong= truncate event.issue_title
at at
......
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
- if event.closed? %span.label.important
- if event.closed?
closed closed
- else - else
reopened reopened
merge request &nbsp;merge request
= link_to project_merge_request_path(event.project, event.merge_request) do = link_to project_merge_request_path(event.project, event.merge_request) do
%strong= truncate event.merge_request_title %strong= truncate event.merge_request_title
at at
...@@ -12,7 +13,6 @@ at ...@@ -12,7 +13,6 @@ at
%span.cgray %span.cgray
= time_ago_in_words(event.created_at) = time_ago_in_words(event.created_at)
ago. ago.
%br
%span.label= event.merge_request.source_branch %span.label= event.merge_request.source_branch
&rarr; &rarr;
%span.label= event.merge_request.target_branch %span.label= event.merge_request.target_branch
......
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
created new issue %span.label.success created
&nbsp;new issue
= link_to project_issue_path(event.project, event.issue) do = link_to project_issue_path(event.project, event.issue) do
%strong= truncate event.issue_title %strong= truncate event.issue_title
at at
......
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
requested merge %span.label.success requested
&nbsp;merge
= link_to project_merge_request_path(event.project, event.merge_request) do = link_to project_merge_request_path(event.project, event.merge_request) do
%strong= truncate event.merge_request_title %strong= truncate event.merge_request_title
at at
...@@ -8,7 +9,6 @@ at ...@@ -8,7 +9,6 @@ at
%span.cgray %span.cgray
= time_ago_in_words(event.created_at) = time_ago_in_words(event.created_at)
ago. ago.
%br
%span.label= event.merge_request.source_branch %span.label= event.merge_request.source_branch
&rarr; &rarr;
%span.label= event.merge_request.target_branch %span.label= event.merge_request.target_branch
......
- if event.new_branch? || event.new_tag? - if event.new_branch? || event.new_tag?
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
pushed new %span.label.pushed pushed
&nbsp;new
- if event.new_tag? - if event.new_tag?
tag tag
= link_to project_commits_path(event.project, :ref => event.tag_name) do = link_to project_commits_path(event.project, :ref => event.tag_name) do
...@@ -18,7 +19,8 @@ ...@@ -18,7 +19,8 @@
- else - else
= image_tag gravatar_icon(event.author_email), :class => "avatar" = image_tag gravatar_icon(event.author_email), :class => "avatar"
%strong #{event.author_name} %strong #{event.author_name}
pushed to %span.label.pushed pushed
&nbsp;to
= link_to project_commits_path(event.project, :ref => event.branch_name) do = link_to project_commits_path(event.project, :ref => event.branch_name) do
%strong= event.branch_name %strong= event.branch_name
at at
...@@ -30,10 +32,10 @@ ...@@ -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 = 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]} Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]}
- @project = event.project - @project = event.project
%ul.unstyled %ul.unstyled.event_commits
- if event.commits.size > 4 - if event.commits.size > 3
= render event.commits[0..2] = render event.commits[0...2]
%li ... and #{event.commits.size - 3} more commits %li ... and #{event.commits.size - 2} more commits
- else - else
= render event.commits = render event.commits
......
%nav.main_menu %nav.main_menu
= render "layouts/const_menu_links" = render "layouts/const_menu_links"
= link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}" = 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 dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" do
= link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" 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"}" = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}"
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
%h1 %h1
GITLAB GITLAB
%h1.project_name= title %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? - if current_user.is_admin?
= link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do
= image_tag "admin.PNG", :width => 16 = image_tag "admin.PNG", :width => 16
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
.ui-box .ui-box
%h5 Commits %h5 Commits
.merge-request-commits .merge-request-commits
%ul.unstyled= render @commits %ul.unstyled
- @commits.each do |commit|
= render "commits/commit", :commit => commit
- else - else
%h5 %h5
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
:javascript :javascript
$(function(){ $(function(){
var modal = $('#modal_merge_info').modal({modal: true}); var modal = $('#modal_merge_info').modal({modal: true});
$('.info_link').bind("click", function(){ $('.how_to_merge_link').bind("click", function(){
modal.show(); modal.show();
}); });
$('.modal-header .close').bind("click", function(){ $('.modal-header .close').bind("click", function(){
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
= time_ago_in_words(merge_request.created_at) = time_ago_in_words(merge_request.created_at)
ago ago
- if merge_request.notes.any? - 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 - if merge_request.upvotes > 0
%span.label.success= "+#{merge_request.upvotes}" %span.label.success= "+#{merge_request.upvotes}"
.right .right
......
%h3 %h3
= "Merge Request ##{@merge_request.id}:" = "Merge Request ##{@merge_request.id}:"
&nbsp; &nbsp;
%span.label= @merge_request.source_branch %span.pretty_label.branch= @merge_request.source_branch
&rarr; &rarr;
%span.label= @merge_request.target_branch %span.pretty_label.branch= @merge_request.target_branch
%small %small
created at created at
...@@ -11,9 +11,7 @@ ...@@ -11,9 +11,7 @@
%span.right %span.right
- if can?(current_user, :modify_merge_request, @merge_request) - if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.closed - if @merge_request.open?
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "btn"
- else
= 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 '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 = link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do
Edit Edit
...@@ -28,17 +26,27 @@ ...@@ -28,17 +26,27 @@
%hr %hr
- if @merge_request.closed .merge_request_status_holder
.alert-message.error Closed - if @merge_request.closed
- else %h5
.alert-message.success .alert-message.error.status_info Closed
= link_to "#", :class => "info_link", :title => "How To Merge" do - if @merge_request.merged?
= image_tag "Info-UI.PNG" %span
Open 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" = render "merge_requests/how_to_merge"
%div.well %div.well.prettyprint
%div %div
%cite.cgray Created by %cite.cgray Created by
= image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av" = image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"
......
%h3 Password .row
%hr .span8
= form_for @user, :url => profile_password_path, :method => :put do |f| %h3 Password
%hr
= form_for @user, :url => profile_password_path, :method => :put do |f|
.data .data
.alert-message.block-message.warning .alert-message.block-message.warning
%p After successfull password update you will be redirected to login page where you should login with new password %p After successfull password update you will be redirected to login page where you should login with new password
...@@ -19,16 +21,18 @@ ...@@ -19,16 +21,18 @@
.actions .actions
= f.submit 'Save', :class => "btn" = f.submit 'Save', :class => "btn"
%h3 .span7.right
%h3
Private token Private token
%span.cred.right %span.cred.right
keep it in secret! keep it in secret!
%hr %hr
= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f| = form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
.data .data
.alert-message.block-message.warning
%p Private token used to access application resources without authentication. %p Private token used to access application resources without authentication.
%p For example its required to access commits feed.
%hr %hr
%p * required for rss feed
%p.cgray %p.cgray
- if current_user.private_token - if current_user.private_token
= text_field_tag "token", current_user.private_token = text_field_tag "token", current_user.private_token
......
%h4.title %h5.title
= @project.name = @project.name
%br %br
%div %div
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
%li Visit profile &rarr; keys and add public key of every machine you want to use for work with gitlabhq. %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 .alert-message.block-message.error
%ul.alert_holder %ul.unstyled.alert_holder
%li You should push repository to proceed. %li You should push repository to proceed.
%li After push you will be able to browse code, commits etc. %li After push you will be able to browse code, commits etc.
......
- if @projects.any? - if @projects.any?
.row .row
.span4 .span11
= render @events
.span5.right
%div.leftbar.ui-box %div.leftbar.ui-box
%h5 %h5
Projects Projects
%small
(#{@projects.count})
- if current_user.can_create_project? - if current_user.can_create_project?
%span.right %span.right
= link_to new_project_path, :class => "btn very_small info" do = link_to new_project_path, :class => "btn very_small info" do
New Project New Project
.content_list .content_list
- @projects.each do |project| - @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 %h4
%span.ico.project %span.ico.project
= truncate(project.name, :length => 22) = truncate(project.name, :length => 25)
.span12.right %span.right
.show_holder.ui-box.padded &rarr;
.loading
- else - else
%h3 Nothing here %h3 Nothing here
...@@ -31,20 +34,3 @@ ...@@ -31,20 +34,3 @@
New Project » New Project »
- else - else
If you will be added to project - it will be displayed here 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});
});
...@@ -21,9 +21,13 @@ ...@@ -21,9 +21,13 @@
= text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url" = text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url"
- if @project.description.present? - if @project.description.present?
= markdown @project.description .prettyprint= markdown @project.description
- unless @events.blank? - unless @events.blank?
%h5.cgray Recent Activity %br
%h5.cgray
%span.ico.activities
Recent Activity
%hr
.content_list= render @events .content_list= render @events
- 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'))}");
= 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]}");
})
...@@ -8,7 +8,13 @@ class PostReceive ...@@ -8,7 +8,13 @@ class PostReceive
# Ignore push from non-gitlab users # Ignore push from non-gitlab users
return false unless Key.find_by_identifier(author_key_id) return false unless Key.find_by_identifier(author_key_id)
# Create push event
project.observe_push(oldrev, newrev, ref, author_key_id) 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) project.execute_web_hooks(oldrev, newrev, ref, author_key_id)
end end
end end
Gitlab::Application.routes.draw do Gitlab::Application.routes.draw do
get 'search' => "search#show"
# Optionally, enable Resque here # Optionally, enable Resque here
require 'resque/server' require 'resque/server'
...@@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do ...@@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do
get "dashboard", :to => "dashboard#index" get "dashboard", :to => "dashboard#index"
get "dashboard/issues", :to => "dashboard#issues" get "dashboard/issues", :to => "dashboard#issues"
get "dashboard/merge_requests", :to => "dashboard#merge_requests" get "dashboard/merge_requests", :to => "dashboard#merge_requests"
get "dashboard/activities", :to => "dashboard#activities"
#get "profile/:id", :to => "profile#show" #get "profile/:id", :to => "profile#show"
......
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
class AddMergedToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :merged, :boolean, :null => false, :default => false
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # 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| create_table "events", :force => true do |t|
t.string "target_type" t.string "target_type"
...@@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do ...@@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do
t.boolean "closed", :default => false, :null => false t.boolean "closed", :default => false, :null => false
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_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 end
add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id"
......
...@@ -209,7 +209,7 @@ Application can be started with next command: ...@@ -209,7 +209,7 @@ Application can be started with next command:
cd /home/gitlab/gitlab cd /home/gitlab/gitlab
sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb 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: Edit /etc/nginx/nginx.conf. Add next code to **http** section:
...@@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab: ...@@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab:
NAME=unicorn NAME=unicorn
DESC="Gitlab service" DESC="Gitlab service"
PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
case "$1" in case "$1" in
start) start)
CD_TO_APP_DIR="cd /home/gitlab/gitlab" CD_TO_APP_DIR="cd /home/gitlab/gitlab"
START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS" START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS"
START_RESQUE_PROCESS="./resque.sh"
echo -n "Starting $DESC: " echo -n "Starting $DESC: "
if [ `whoami` = root ]; then 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 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 fi
echo "$NAME." echo "$NAME."
;; ;;
stop) stop)
echo -n "Stopping $DESC: " echo -n "Stopping $DESC: "
kill -QUIT `cat $PID` kill -QUIT `cat $PID`
kill -QUIT `cat $RESQUE_PID`
echo "$NAME." echo "$NAME."
;; ;;
restart) restart)
echo -n "Restarting $DESC: " echo -n "Restarting $DESC: "
kill -USR2 `cat $PID` kill -USR2 `cat $PID`
kill -USR2 `cat $RESQUE_PID`
echo "$NAME." echo "$NAME."
;; ;;
reload) reload)
echo -n "Reloading $DESC configuration: " echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID` kill -HUP `cat $PID`
kill -HUP `cat $RESQUE_PID`
echo "$NAME." echo "$NAME."
;; ;;
*) *)
......
mkdir tmp/pids 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
...@@ -160,6 +160,34 @@ describe Project do ...@@ -160,6 +160,34 @@ describe Project do
end end
end 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 end
# == Schema Information # == Schema Information
# #
......
require 'spec_helper' require 'spec_helper'
__END__
# Disabled for now
describe "Dashboard" do describe "Dashboard" do
before do before do
@project = Factory :project @project = Factory :project
...@@ -22,19 +20,7 @@ describe "Dashboard" do ...@@ -22,19 +20,7 @@ describe "Dashboard" do
end end
it "should have projects panel" do it "should have projects panel" do
within ".project-list" do
page.should have_content(@project.name) page.should have_content(@project.name)
end end
end 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 end
...@@ -42,7 +42,7 @@ describe "MergeRequests" do ...@@ -42,7 +42,7 @@ describe "MergeRequests" do
it { should have_content(@merge_request.title[0..10]) } it { should have_content(@merge_request.title[0..10]) }
it "Show page should inform user that merge request closed" do it "Show page should inform user that merge request closed" do
page.should have_content "Reopen" page.should have_content "Closed"
end end
end end
end end
......
/*
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();
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment