2012-04-23 18:06:14 +01:00
|
|
|
# -*- encoding : utf-8 -*-
|
2012-05-04 11:56:11 +01:00
|
|
|
class Projects::PullRequestsController < Projects::BaseController
|
2012-04-23 18:06:14 +01:00
|
|
|
before_filter :authenticate_user!
|
2012-05-30 19:08:07 +01:00
|
|
|
skip_before_filter :authenticate_user!, :only => [:index, :show] if APP_CONFIG['anonymous_access']
|
2012-09-26 18:10:04 +01:00
|
|
|
load_and_authorize_resource :project
|
2012-05-30 19:08:07 +01:00
|
|
|
|
2012-10-03 12:36:04 +01:00
|
|
|
load_resource :issue, :through => :project, :find_by => :serial_id, :parent => false, :except => [:index, :autocomplete_to_project]
|
|
|
|
load_and_authorize_resource :instance_name => :pull, :through => :issue, :singleton => true, :except => [:index, :autocomplete_to_project]
|
2012-04-23 18:06:14 +01:00
|
|
|
|
|
|
|
def new
|
2012-10-03 12:59:18 +01:00
|
|
|
to_project = find_destination_project(false)
|
2012-10-03 12:36:04 +01:00
|
|
|
authorize! :read, to_project
|
2012-07-06 18:30:01 +01:00
|
|
|
|
2012-10-03 12:36:04 +01:00
|
|
|
@pull = to_project.pull_requests.new
|
|
|
|
@pull.issue = to_project.issues.new
|
2012-08-07 17:34:22 +01:00
|
|
|
set_attrs
|
2012-07-06 18:30:01 +01:00
|
|
|
|
2012-10-03 12:59:18 +01:00
|
|
|
if PullRequest.check_ref(@pull, 'to', @pull.to_ref) && PullRequest.check_ref(@pull, 'from', @pull.from_ref) || @pull.uniq_merge
|
2012-09-28 18:45:27 +01:00
|
|
|
flash.now[:warning] = @pull.errors.full_messages.join('. ')
|
2012-05-24 18:10:49 +01:00
|
|
|
else
|
2012-08-07 17:24:47 +01:00
|
|
|
@pull.check(false) # don't make event transaction
|
|
|
|
if @pull.already?
|
|
|
|
@pull.destroy
|
2012-10-03 12:36:04 +01:00
|
|
|
flash.now[:warning] = I18n.t('projects.pull_requests.up_to_date', :to_ref => @pull.to_ref, :from_ref => @pull.from_ref)
|
2012-08-07 17:24:47 +01:00
|
|
|
else
|
|
|
|
load_diff_commits_data
|
|
|
|
end
|
2012-05-23 17:09:11 +01:00
|
|
|
end
|
2012-04-23 18:06:14 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
2012-07-06 18:30:01 +01:00
|
|
|
unless pull_params
|
|
|
|
raise 'expect pull_request params' # for debug
|
|
|
|
redirect :back
|
|
|
|
end
|
2012-10-03 12:59:18 +01:00
|
|
|
to_project = find_destination_project
|
2012-10-03 12:36:04 +01:00
|
|
|
authorize! :read, to_project
|
2012-07-06 18:30:01 +01:00
|
|
|
|
2012-10-03 12:36:04 +01:00
|
|
|
@pull = to_project.pull_requests.new pull_params
|
2013-03-20 20:46:33 +00:00
|
|
|
@pull.issue.assignee_id = (params[:issue] || {})[:assignee_id]
|
2012-10-03 12:36:04 +01:00
|
|
|
@pull.issue.user, @pull.issue.project, @pull.from_project = current_user, to_project, @project
|
2012-11-14 10:51:10 +00:00
|
|
|
@pull.from_project_owner_uname = @pull.from_project.owner.uname
|
|
|
|
@pull.from_project_name = @pull.from_project.name
|
2012-04-28 18:28:57 +01:00
|
|
|
|
2012-08-07 18:59:36 +01:00
|
|
|
if @pull.valid? # FIXME more clean/clever logics
|
2012-10-02 10:14:31 +01:00
|
|
|
@pull.save # set pull id
|
2012-06-28 14:47:29 +01:00
|
|
|
@pull.check(false) # don't make event transaction
|
2012-08-07 17:34:22 +01:00
|
|
|
if @pull.already?
|
2012-05-23 17:09:11 +01:00
|
|
|
@pull.destroy
|
2012-10-03 12:36:04 +01:00
|
|
|
flash.now[:error] = I18n.t('projects.pull_requests.up_to_date', :to_ref => @pull.to_ref, :from_ref => @pull.from_ref)
|
2012-05-23 17:09:11 +01:00
|
|
|
render :new
|
|
|
|
else
|
2012-10-05 20:19:05 +01:00
|
|
|
@pull.send(@pull.status == 'blocked' ? 'block' : @pull.status)
|
2012-10-03 12:36:04 +01:00
|
|
|
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
2012-05-23 17:09:11 +01:00
|
|
|
end
|
2012-04-28 18:28:57 +01:00
|
|
|
else
|
2012-09-28 18:45:27 +01:00
|
|
|
flash.now[:error] = t('flash.pull_request.save_error')
|
|
|
|
flash.now[:warning] = @pull.errors.full_messages.join('. ')
|
2012-07-10 17:10:12 +01:00
|
|
|
|
2012-10-03 12:36:04 +01:00
|
|
|
if @pull.errors.try(:messages) && @pull.errors.messages[:to_ref].nil? && @pull.errors.messages[:from_ref].nil?
|
2012-08-07 17:24:47 +01:00
|
|
|
@pull.check(false) # don't make event transaction
|
|
|
|
load_diff_commits_data
|
|
|
|
end
|
2012-04-28 18:28:57 +01:00
|
|
|
render :new
|
|
|
|
end
|
2012-04-23 18:06:14 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def update
|
2012-07-12 15:15:28 +01:00
|
|
|
if (action = params[:pull_request_action]) && %w(close reopen).include?(params[:pull_request_action])
|
|
|
|
if @pull.send("can_#{action}?")
|
|
|
|
@pull.set_user_and_time current_user
|
|
|
|
@pull.send(action)
|
|
|
|
@pull.check if @pull.open?
|
|
|
|
end
|
|
|
|
end
|
2012-10-03 12:36:04 +01:00
|
|
|
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
2012-04-23 18:06:14 +01:00
|
|
|
end
|
|
|
|
|
2012-05-17 17:47:36 +01:00
|
|
|
def merge
|
2012-05-30 19:08:07 +01:00
|
|
|
@pull.check
|
2012-06-27 11:47:08 +01:00
|
|
|
unless @pull.merge!(current_user)
|
2012-09-28 18:45:27 +01:00
|
|
|
flash.now[:error] = t('flash.pull_request.save_error')
|
|
|
|
flash.now[:warning] = @pull.errors.full_messages.join('. ')
|
2012-06-27 11:47:08 +01:00
|
|
|
end
|
2012-10-03 12:36:04 +01:00
|
|
|
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
2012-05-17 17:47:36 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def show
|
2012-05-31 12:23:30 +01:00
|
|
|
load_diff_commits_data
|
2012-05-17 17:47:36 +01:00
|
|
|
end
|
|
|
|
|
2012-09-25 21:50:40 +01:00
|
|
|
def index(status = 200)
|
2012-09-26 12:46:23 +01:00
|
|
|
@issues_with_pull_request = @project.issues.joins(:pull_request)
|
2013-03-20 15:22:13 +00:00
|
|
|
@issues_with_pull_request = @issues_with_pull_request.where(:assignee_id => current_user.id) if @is_assigned_to_me = params[:filter] == 'to_me'
|
2013-03-19 15:30:50 +00:00
|
|
|
@issues_with_pull_request = @issues_with_pull_request.search(params[:search_pull_request]) if params[:search_pull_request] !~ /#{t('layout.pull_requests.search')}/
|
2012-09-25 21:50:40 +01:00
|
|
|
|
2013-03-19 15:30:50 +00:00
|
|
|
@opened_issues, @closed_issues = @issues_with_pull_request.not_closed_or_merged.count, @issues_with_pull_request.closed_or_merged.count
|
2013-03-19 12:11:02 +00:00
|
|
|
|
|
|
|
@status = params[:status] == 'closed' ? :closed : :open
|
|
|
|
@issues_with_pull_request = @issues_with_pull_request.send( (@status == :closed) ? :closed_or_merged : :not_closed_or_merged )
|
|
|
|
|
|
|
|
@sort = params[:sort] == 'updated' ? :updated : :created
|
|
|
|
@direction = params[:direction] == 'asc' ? :asc : :desc
|
|
|
|
@issues_with_pull_request = @issues_with_pull_request.order("issues.#{@sort}_at #{@direction}")
|
2012-09-25 21:50:40 +01:00
|
|
|
|
2012-09-26 12:46:23 +01:00
|
|
|
@issues_with_pull_request = @issues_with_pull_request.
|
2013-03-19 12:11:02 +00:00
|
|
|
includes(:assignee, :user, :pull_request).uniq.
|
2013-03-19 21:30:35 +00:00
|
|
|
paginate :per_page => 20, :page => params[:page]
|
2012-09-25 21:50:40 +01:00
|
|
|
if status == 200
|
2012-09-26 12:46:23 +01:00
|
|
|
render 'index', :layout => request.xhr? ? 'with_sidebar' : 'application'
|
2012-09-25 21:50:40 +01:00
|
|
|
else
|
|
|
|
render :status => status, :nothing => true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-10-03 12:36:04 +01:00
|
|
|
def autocomplete_to_project
|
2012-10-02 10:20:48 +01:00
|
|
|
items = Project.accessible_by(current_ability, :membered) | @project.ancestors
|
2012-12-25 09:46:07 +00:00
|
|
|
term = Regexp.new(Regexp.escape params[:term].downcase)
|
|
|
|
items.select! {|e| term.match(e.name_with_owner.downcase) && e.repo.branches.count > 0}
|
2012-08-10 17:37:21 +01:00
|
|
|
render :json => json_for_autocomplete_base(items)
|
2012-05-16 17:50:30 +01:00
|
|
|
end
|
|
|
|
|
2012-07-06 18:30:01 +01:00
|
|
|
protected
|
2012-05-16 17:50:30 +01:00
|
|
|
|
2012-07-06 18:30:01 +01:00
|
|
|
def pull_params
|
|
|
|
@pull_params ||= params[:pull_request].presence
|
2012-05-16 17:50:30 +01:00
|
|
|
end
|
|
|
|
|
2012-07-06 18:30:01 +01:00
|
|
|
def json_for_autocomplete_base items
|
|
|
|
items.collect do |project|
|
2012-08-10 17:37:21 +01:00
|
|
|
hash = {"id" => project.id.to_s, "label" => project.name_with_owner, "value" => project.name_with_owner}
|
2012-10-01 17:03:08 +01:00
|
|
|
hash[:get_refs_url] = project_refs_list_path(project)
|
2012-07-06 18:30:01 +01:00
|
|
|
hash
|
2012-05-16 17:50:30 +01:00
|
|
|
end
|
|
|
|
end
|
2012-05-30 19:08:07 +01:00
|
|
|
|
2012-05-31 12:23:30 +01:00
|
|
|
def load_diff_commits_data
|
2012-10-18 13:50:43 +01:00
|
|
|
@commits = @pull.repo.commits_between(@pull.to_commit, @pull.from_commit)
|
2012-09-26 18:00:58 +01:00
|
|
|
@total_commits = @commits.count
|
|
|
|
@commits = @commits.last(100)
|
2012-06-07 18:23:28 +01:00
|
|
|
|
2012-10-26 15:03:46 +01:00
|
|
|
@stats = @pull.diff_stats
|
2012-10-18 13:09:12 +01:00
|
|
|
@comments, @commentable = @issue.comments, @issue
|
2012-05-31 12:23:30 +01:00
|
|
|
end
|
2012-08-07 17:34:22 +01:00
|
|
|
|
2012-10-03 12:59:18 +01:00
|
|
|
def find_destination_project bang=true
|
2012-10-03 12:36:04 +01:00
|
|
|
args = params[:to_project].try(:split, '/') || []
|
2012-10-03 12:59:18 +01:00
|
|
|
project = (args.length == 2) ? Project.find_by_owner_and_name(*args) : nil
|
|
|
|
raise ActiveRecord::RecordNotFound if bang && !project
|
2012-10-10 19:59:25 +01:00
|
|
|
project || @project
|
2012-10-01 18:43:15 +01:00
|
|
|
end
|
|
|
|
|
2012-08-07 17:34:22 +01:00
|
|
|
def set_attrs
|
|
|
|
if pull_params && pull_params[:issue_attributes]
|
|
|
|
@pull.issue.title = pull_params[:issue_attributes][:title].presence
|
|
|
|
@pull.issue.body = pull_params[:issue_attributes][:body].presence
|
|
|
|
end
|
2012-10-03 12:36:04 +01:00
|
|
|
@pull.from_project = @project
|
2013-03-07 12:22:48 +00:00
|
|
|
@pull.to_ref = (pull_params[:to_ref].presence if pull_params) || @pull.to_project.default_head
|
2013-01-31 16:26:49 +00:00
|
|
|
@pull.from_ref = params[:treeish].presence || (pull_params[:from_ref].presence if pull_params) || @pull.from_project.default_head(params[:treeish])
|
2012-10-27 19:44:42 +01:00
|
|
|
@pull.from_project_owner_uname = @pull.from_project.owner.uname
|
|
|
|
@pull.from_project_name = @pull.from_project.name
|
2012-08-07 17:34:22 +01:00
|
|
|
end
|
2012-04-23 18:06:14 +01:00
|
|
|
end
|