Skip to content
Snippets Groups Projects
Commit 6d460aa2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

merge request entity

parent 22442039
No related branches found
No related tags found
No related merge requests found
Showing
with 311 additions and 37 deletions
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
Loading
@@ -58,6 +58,8 @@
Loading
@@ -58,6 +58,8 @@
padding: 0; padding: 0;
} }
   
body.project-page .merge-request-form-holder table.no-borders tr,
body.project-page .merge-request-form-holder table.no-borders td,
body.project-page .issue-form-holder table.no-borders tr, body.project-page .issue-form-holder table.no-borders tr,
body.project-page .issue-form-holder table.no-borders td, body.project-page .issue-form-holder table.no-borders td,
body.project-page .new_snippet table tr, body.project-page .new_snippet table tr,
Loading
Loading
// Place all the styles related to the MergeRequests controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.merge-request-form-holder {
select {
width:300px;
}
}
Loading
@@ -155,6 +155,8 @@ input.ssh_project_url {
Loading
@@ -155,6 +155,8 @@ input.ssh_project_url {
} }
   
/** FORM INPUTS **/ /** FORM INPUTS **/
.new_merge_request,
.edit_merge_request,
.user_new, .user_new,
.new_key, .new_key,
.new_issue, .new_issue,
Loading
@@ -384,6 +386,19 @@ body.dashboard.project-page .news-feed .project-updates a.project-update span.up
Loading
@@ -384,6 +386,19 @@ body.dashboard.project-page .news-feed .project-updates a.project-update span.up
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;} body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
/* eo Dashboard Page */ /* eo Dashboard Page */
   
/** Merge requests */
body.project-page .merge-request-commits {margin-bottom: 20px; display: block; width: 100%;}
body.project-page .merge-request-commits .data{ padding: 0}
body.project-page .merge-request-commits a.commit {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.project-page .merge-request-commits a.commit:last-child{border-bottom: 0}
body.project-page .merge-request-commits a.commit img{float: left; margin-right: 10px;}
body.project-page .merge-request-commits a.commit span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
body.project-page .merge-request-commits a.commit span.update-title{margin-bottom: 10px}
body.project-page .merge-request-commits a.commit span.update-author{color: #999; font-weight: normal; font-style: italic;}
body.project-page .merge-request-commits a.commit span.update-author strong{font-weight: bold; font-style: normal;}
body.project-page .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; } body.project-page .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
   
body.projects-page input.text.git-url.project_list_url { width:165px; } body.projects-page input.text.git-url.project_list_url { width:165px; }
Loading
Loading
class MergeRequestsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :merge_request, :only => [:edit, :update, :destroy, :show]
layout "project"
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
before_filter :authorize_write_project!, :only => [:new, :create, :edit, :update]
def index
@merge_requests = @project.merge_requests.all
end
def show
unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) &&
@project.repo.heads.map(&:name).include?(@merge_request.source_branch)
head(404)and return
end
@commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)}
end
def new
@merge_request = @project.merge_requests.new
end
def edit
end
def create
@merge_request = @project.merge_requests.new(params[:merge_request])
@merge_request.author = current_user
respond_to do |format|
if @merge_request.save
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
format.html { render action: "new" }
format.json { render json: @merge_request.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @merge_request.update_attributes(params[:merge_request])
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @merge_request.errors, status: :unprocessable_entity }
end
end
end
def destroy
@merge_request.destroy
respond_to do |format|
format.html { redirect_to project_merge_requests_url(@project) }
format.json { head :ok }
end
end
protected
def merge_request
@merge_request ||= @project.merge_requests.find(params[:id])
end
end
module MergeRequestsHelper
end
Loading
@@ -17,6 +17,7 @@ class Ability
Loading
@@ -17,6 +17,7 @@ class Ability
:read_issue, :read_issue,
:read_snippet, :read_snippet,
:read_team_member, :read_team_member,
:read_merge_request,
:read_note :read_note
] if project.readers.include?(user) ] if project.readers.include?(user)
   
Loading
@@ -24,6 +25,7 @@ class Ability
Loading
@@ -24,6 +25,7 @@ class Ability
:write_project, :write_project,
:write_issue, :write_issue,
:write_snippet, :write_snippet,
:write_merge_request,
:write_note :write_note
] if project.writers.include?(user) ] if project.writers.include?(user)
   
Loading
@@ -32,6 +34,7 @@ class Ability
Loading
@@ -32,6 +34,7 @@ class Ability
:admin_issue, :admin_issue,
:admin_snippet, :admin_snippet,
:admin_team_member, :admin_team_member,
:admin_merge_request,
:admin_note :admin_note
] if project.admins.include?(user) ] if project.admins.include?(user)
   
Loading
@@ -39,7 +42,7 @@ class Ability
Loading
@@ -39,7 +42,7 @@ class Ability
end end
   
class << self class << self
[:issue, :note, :snippet].each do |name| [:issue, :note, :snippet, :merge_request].each do |name|
define_method "#{name}_abilities" do |user, subject| define_method "#{name}_abilities" do |user, subject|
if subject.author == user if subject.author == user
[ [
Loading
Loading
class MergeRequest < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User"
has_many :notes, :as => :noteable
attr_protected :author, :author_id, :project, :project_id
validates_presence_of :project_id
validates_presence_of :assignee_id
validates_presence_of :author_id
validates_presence_of :source_branch
validates_presence_of :target_branch
delegate :name,
:email,
:to => :author,
:prefix => true
delegate :name,
:email,
:to => :assignee,
:prefix => true
validates :title,
:presence => true,
:length => { :within => 0..255 }
scope :opened, where(:closed => false)
scope :closed, where(:closed => true)
scope :assigned, lambda { |u| where(:assignee_id => u.id)}
def new?
today? && created_at == updated_at
end
end
Loading
@@ -3,6 +3,7 @@ require "grit"
Loading
@@ -3,6 +3,7 @@ require "grit"
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
belongs_to :owner, :class_name => "User" belongs_to :owner, :class_name => "User"
   
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position" has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy has_many :users_projects, :dependent => :destroy
has_many :users, :through => :users_projects has_many :users, :through => :users_projects
Loading
Loading
Loading
@@ -39,6 +39,10 @@
Loading
@@ -39,6 +39,10 @@
Wall Wall
- if @project.common_notes.today.count > 0 - if @project.common_notes.today.count > 0
%span{ :class => "number" }= @project.common_notes.today.count %span{ :class => "number" }= @project.common_notes.today.count
= link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do
Merge Requests
- if @project.merge_requests.opened.count > 0
%span{ :class => "number" }= @project.merge_requests.opened.count
= link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do = link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do
Snippets Snippets
- if @project.snippets.non_expired.count > 0 - if @project.snippets.non_expired.count > 0
Loading
Loading
%div.merge-request-form-holder
.ui-box.width-100p
%h3
= @merge_request.new_record? ? "New Merge Request" : "Edit Merge Request ##{@merge_request.id}"
= form_for [@project, @merge_request] do |f|
.data
%table.no-borders
-if @merge_request.errors.any?
%tr
%td Errors
%td
#error_explanation
- @merge_request.errors.full_messages.each do |msg|
%span= msg
%br
%tr
%td= f.label :title
%td= f.text_field :title
%tr
%td= f.label :target_branch, "From"
%td= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" })
%tr
%td= f.label :source_branch, "To"
%td= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" })
%tr
%td= f.label :assignee_id, "Assign to"
%td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" })
.buttons
= f.submit 'Save', :class => "grey-button"
.right= link_to 'Back', project_merge_requests_path(@project), :class => "grey-button"
:javascript
$(function(){
$('select#merge_request_assignee_id').chosen();
$('select#merge_request_source_branch').chosen();
$('select#merge_request_target_branch').chosen();
});
= render 'form'
%table
%thead
%th Target branch
%th Source branch
%th Author
%th Assignee
%th Title
%th
%th
%th
- @merge_requests.each do |merge_request|
%tr
%td= merge_request.target_branch
%td= merge_request.source_branch
%td= merge_request.author_id
%td= merge_request.assignee_id
%td= merge_request.title
%td= link_to 'Show', [@project, merge_request]
%td= link_to 'Edit', edit_project_merge_request_path(@project, merge_request)
%td= link_to 'Destroy', [@project, merge_request], :confirm => 'Are you sure?', :method => :delete
%br
= link_to 'New Merge request', new_project_merge_request_path(@project)
= render 'form'
.merge-request-show-holder.ui-box.width-100p
%h3
= "Merge Request ##{@merge_request.id}:"
&nbsp;
= "'#{@merge_request.source_branch}'"
&rarr;
= "'#{@merge_request.target_branch}'"
.right
- if @merge_request.closed
%span.tag.high Resolved
- else
%span.tag.today Open
.data
%p= @merge_request.title
- if @merge_request.author == @merge_request.assignee
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.assignee_name
- else
= image_tag gravatar_icon(@merge_request.author_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.author_name
&rarr;
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.assignee_name
.right
%cite.cgray= @merge_request.created_at.stamp("21 Aug 2011, 11:15pm")
.clear
.buttons
- if can? current_user, :write_project, @project
- if @merge_request.closed
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "grey-button"
- else
= link_to 'Resolve', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "grey-button"
.right
= link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), :class => "grey-button positive"
.clear
%br
%br
- if @commits.size > 0
.merge-request-commits.ui-box.width-100p
- @commits.each do |commit|
%a{ :class => "commit", :href => project_commit_path(@project, :id => commit.id) }
- if commit.author_email
= image_tag gravatar_icon(commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- else
= image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
%span.update-title
= commit.id.to_s
%span.update-author
%strong= commit.author_name
authored
= time_ago_in_words(commit.created_at)
ago
.clear
Loading
@@ -59,6 +59,7 @@ Gitlab::Application.routes.draw do
Loading
@@ -59,6 +59,7 @@ Gitlab::Application.routes.draw do
end end
end end
   
resources :merge_requests
resources :snippets resources :snippets
resources :commits resources :commits
resources :team_members resources :team_members
Loading
Loading
class CreateMergeRequests < ActiveRecord::Migration
def change
create_table :merge_requests do |t|
t.string :target_branch, :null => false
t.string :source_branch, :null => false
t.integer :project_id, :null => false
t.integer :author_id
t.integer :assignee_id
t.string :title
t.boolean :closed, :default => false, :null => false
t.timestamps
end
end
end
Loading
@@ -11,7 +11,7 @@
Loading
@@ -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 => 20111124115339) do ActiveRecord::Schema.define(:version => 20111127155345) do
   
create_table "features", :force => true do |t| create_table "features", :force => true do |t|
t.string "name" t.string "name"
Loading
@@ -21,6 +21,8 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
Loading
@@ -21,6 +21,8 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
t.integer "project_id" t.integer "project_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "version"
t.integer "status", :default => 0, :null => false
end end
   
create_table "issues", :force => true do |t| create_table "issues", :force => true do |t|
Loading
@@ -45,6 +47,18 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
Loading
@@ -45,6 +47,18 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
t.string "identifier" t.string "identifier"
end end
   
create_table "merge_requests", :force => true do |t|
t.string "target_branch", :null => false
t.string "source_branch", :null => false
t.integer "project_id", :null => false
t.integer "author_id"
t.integer "assignee_id"
t.string "title"
t.boolean "closed", :default => false, :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "notes", :force => true do |t| create_table "notes", :force => true do |t|
t.text "note" t.text "note"
t.string "noteable_id" t.string "noteable_id"
Loading
Loading
require 'spec_helper'
describe ApplicationHelper do
context ".gravatar_icon" do
context "over http" do
it "returns the correct URL to www.gravatar.com" do
expected = "http://www.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
# Pretend we're running over HTTP
helper.stub(:request) do
request = double('request')
request.stub(:ssl?) { false }
request
end
helper.gravatar_icon("admin@local.host").should == expected
end
end
context "over https" do
it "returns the correct URL to secure.gravatar.com" do
expected = "https://secure.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
# Pretend we're running over HTTPS
helper.stub(:request) do
request = double('request')
request.stub(:ssl?) { true }
request
end
helper.gravatar_icon("admin@local.host").should == expected
end
end
end
end
require 'spec_helper'
describe MergeRequest do
pending "add some examples to (or delete) #{__FILE__}"
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment