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
Loading
@@ -58,6 +58,8 @@
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 td,
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
Loading
@@ -155,6 +155,8 @@ input.ssh_project_url {
}
 
/** FORM INPUTS **/
.new_merge_request,
.edit_merge_request,
.user_new,
.new_key,
.new_issue,
Loading
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;}
/* 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.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
Loading
@@ -17,6 +17,7 @@ class Ability
:read_issue,
:read_snippet,
:read_team_member,
:read_merge_request,
:read_note
] if project.readers.include?(user)
 
Loading
Loading
@@ -24,6 +25,7 @@ class Ability
:write_project,
:write_issue,
:write_snippet,
:write_merge_request,
:write_note
] if project.writers.include?(user)
 
Loading
Loading
@@ -32,6 +34,7 @@ class Ability
:admin_issue,
:admin_snippet,
:admin_team_member,
:admin_merge_request,
:admin_note
] if project.admins.include?(user)
 
Loading
Loading
@@ -39,7 +42,7 @@ class Ability
end
 
class << self
[:issue, :note, :snippet].each do |name|
[:issue, :note, :snippet, :merge_request].each do |name|
define_method "#{name}_abilities" do |user, subject|
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
Loading
@@ -3,6 +3,7 @@ require "grit"
class Project < ActiveRecord::Base
belongs_to :owner, :class_name => "User"
 
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy
has_many :users, :through => :users_projects
Loading
Loading
Loading
Loading
@@ -39,6 +39,10 @@
Wall
- if @project.common_notes.today.count > 0
%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
Snippets
- 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
Loading
@@ -59,6 +59,7 @@ Gitlab::Application.routes.draw do
end
end
 
resources :merge_requests
resources :snippets
resources :commits
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
Loading
@@ -11,7 +11,7 @@
#
# 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|
t.string "name"
Loading
Loading
@@ -21,6 +21,8 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "version"
t.integer "status", :default => 0, :null => false
end
 
create_table "issues", :force => true do |t|
Loading
Loading
@@ -45,6 +47,18 @@ ActiveRecord::Schema.define(:version => 20111124115339) do
t.string "identifier"
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|
t.text "note"
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