diff --git a/app/assets/javascripts/pull_requests.js.coffee b/app/assets/javascripts/pull_requests.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/pull_requests.js.coffee @@ -0,0 +1,3 @@ +# 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/ diff --git a/app/assets/stylesheets/pull_requests.css.scss b/app/assets/stylesheets/pull_requests.css.scss new file mode 100644 index 000000000..f69ac413b --- /dev/null +++ b/app/assets/stylesheets/pull_requests.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the pull_requests controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb new file mode 100644 index 000000000..7db6e592e --- /dev/null +++ b/app/controllers/pull_requests_controller.rb @@ -0,0 +1,135 @@ + +class PullRequestsController < ApplicationController + before_filter :find_project_and_repository + before_filter :connect_gitlab, :only => [:index, :show, :create, :accept_pull_request, :pull_request_commits, :pull_request_changes, :new] + layout "base_projects" + include PullRequestsHelper + include ApplicationHelper + + # 返回json格式 + def index + type = params[:type] + case type + when nil, "1" + @requests = @g.merge_requests(@project.gpid).select{|request| request.state == "opened" || request.state == "reopened"} + when "2" + @requests = @g.merge_requests(@project.gpid).select{|request| request.state == "merged"} + end + @requests_opened_count = @requests.count + @requests_merged_count = params[:type] ? @requests.count : @g.merge_requests(@project.gpid).select{|request| request.state == "merged"}.count + respond_to do |format| + format.html + format.js + end + end + + # 主要取源项目和目标项目分支及标识(用户名/版本库名) + def new + identifier = get_rep_identifier_by_project @project + @source_project_name = "#{get_user_name(@project.user_id)}/#{identifier}" + @source_rev = @g.branches(@project.gpid).map{|b| b.name} + + # 获取forked源项目信息 + if @project.forked_from_project_id + @forked_project = Project.find(@project.forked_from_project_id) + identifier = get_rep_identifier_by_project @forked_project + @forked_project_name = "#{get_user_name(@forked_project.user_id)}/#{identifier}" + @forked_rev = @g.branches(@forked_project.gpid).map{|b| b.name} + end + end + + # Creates a merge request. + # If the operation is successful, 200 and the newly created merge request is returned. If an error occurs, an error number and a message explaining the reason is returned. + # + # @example + # Gitlab.create_merge_request(5, 'New merge request', + # :source_branch => 'source_branch', :target_branch => 'target_branch') + # Gitlab.create_merge_request(5, 'New merge request', + # :source_branch => 'source_branch', :target_branch => 'target_branch', :assignee_id => 42) + # + # @param [Integer] project The ID of a project. + # @param [String] title The title of a merge request. + # @param [Hash] options A customizable set of options. + # @option options [String] :source_branch (required) The source branch name. + # @option options [String] :target_branch (required) The target branch name. + # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request. + # @return [Gitlab::ObjectifiedHash] Information about created merge request. + def create + title = params[:title] + description = params[:description] + source_branch = params[:source_branch] + target_branch = params[:target_branch] + begin + # 如果传送了目标项目ID,则PR请求发至目标项目 + if params[:forked_project_id] && params[:source_project] == "forked_project_name" + target_project_id = params[:forked_project_id].to_i + request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch, :target_project_id => target_project_id) + @fork_project_name = Project.find(@project.forked_from_project_id).try(:name) + @fork_pr_message = true if @fork_project_name + else + request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch) + respond_to do |format| + format.js{redirect_to project_pull_request_path(request.id, :project_id => @project.id)} + end + end + rescue Exception => e + @message = e.message + end + end + + def show + @type = params[:type] + @request = @g.merge_request(@project.gpid, params[:id]) + @commits = @g.merge_request_commits(@project.gpid, params[:id].to_i) + @commits_count = @commits.count + @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes) + @changes_count = @changes.count + end + + # Accept a merge request. + # If merge success you get 200 OK. + # Accept a merge request. + # + # @example + # Gitlab.accept_pull_rquest(5, 1) + # + # @param [Integer] project The ID of a project. + # @param [Integer] id The ID of a merge request. + # @return [Gitlab::ObjectifiedHash] + def accept_pull_request + begin + status = @g.accept_merge_rquest(@project.gpid, params[:id]) + respond_to do |format| + format.js{redirect_to project_pull_request_path(status.id, :project_id => @project.id)} + end + rescue Exception => e + @message = e.message + end + end + + # 获取某次请求的提交次数 + def pull_request_commits + @type = parms[:type] + @commits = @g.merge_request_commits(@project.gpid, params[:id].to_i) + end + + # 获取某次请求的改动 + def pull_request_changes + @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes) + @changes_count = @changes.count + end + + private + def connect_gitlab + @g = Gitlab.client + end + + def find_project_and_repository + @project = Project.find(params[:project_id]) + render_404 if @project.gpid.blank? + @repository = Repository.where(:project_id => @project.id, :type => "Repository::Gitlab") + rescue ActiveRecord::RecordNotFound + render_404 + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d64d95223..69da2657b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -43,6 +43,12 @@ module ApplicationHelper user.nil? ? User.find(2) : user end + # 通过系统外部用户名查找用户,如果用户不存在则用邮箱替换 + def get_user_by_login_and login + user = User.find_by_login(login) + user.nil? ? User.find(2) : user + end + # 历史数据(老版本库数据)处理完则可以修改该放放 def get_rep_identifier_by_project project identifier = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier) @@ -814,6 +820,18 @@ module ApplicationHelper return @result end + # 必须是项目成,项目必须提交过代码 + def allow_pull_request project + return false if project.gpid.nil? + g = Gitlab.client + count = g.user_static(project.gpid, :rev => "master").count + if User.current.member_of?(project) && count > 0 + true + else + false + end + end + # 判断版本库是否初始为gitlab def rep_is_gitlab?(project) rep = project.repositories.where("type =?", "Repository::Gitlab") diff --git a/app/helpers/pull_requests_helper.rb b/app/helpers/pull_requests_helper.rb new file mode 100644 index 000000000..82d4edc0f --- /dev/null +++ b/app/helpers/pull_requests_helper.rb @@ -0,0 +1,17 @@ +module PullRequestsHelper + + # 获取diff内容行号 + def diff_line_num content + content.scan(/@@ -(\d+),\d+ \+\d+,\d+ @@/).first.nil? ? "" : content.scan(/@@ -(\d+),\d+ \+\d+,\d+ @@/).first.join("").to_i + end + + # 处理内容 + def diff_content content + content.gsub!(/.*@@ -\d+,\d+ \+\d+,\d+ @@\n/m,'') + end + + def get_user_name user_id + User.find(user_id).try(:login) + end + +end diff --git a/app/models/project.rb b/app/models/project.rb index 86f670f33..0751c902f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1236,8 +1236,7 @@ class Project < ActiveRecord::Base # 创建项目后在项目下同步创建一个讨论区 def create_board_sync @board = self.boards.build - self.name=" #{l(:label_borad_project) }" - @board.name = self.name + @board.name = " #{l(:label_borad_project) }" @board.description = self.name.to_s if @board.save logger.debug "[Project Model] ===> #{@board.to_json}" diff --git a/app/views/projects/_development_group.html.erb b/app/views/projects/_development_group.html.erb index 2c7d36fb5..273fcf56a 100644 --- a/app/views/projects/_development_group.html.erb +++ b/app/views/projects/_development_group.html.erb @@ -39,6 +39,14 @@ <% end %> <% end %> + +<% if allow_pull_request(@project) %> + +<% end %> + <%# --版本库被设置成私有、module中设置不显示、没有创建版本库 三种情况不显示-- %> <% if visible_repository?(@project) %> <% end %> + +