creates_commit.rb 3.34 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
module CreatesCommit
  extend ActiveSupport::Concern

  def create_commit(service, success_path:, failure_path:, failure_view: nil, success_notice: nil)
    set_commit_variables

    commit_params = @commit_params.merge(
      source_project: @project,
      source_branch: @ref,
      target_branch: @target_branch
    )

    result = service.new(@tree_edit_project, current_user, commit_params).execute

    if result[:status] == :success
      flash[:notice] = success_notice || "Your changes have been successfully committed."

      if create_merge_request?
19
        success_path = merge_request_exists? ? existent_merge_request_path : new_merge_request_path
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
        target = different_project? ? "project" : "branch"
        flash[:notice] << " You can now submit a merge request to get this change into the original #{target}."
      end

      respond_to do |format|
        format.html { redirect_to success_path }
        format.json { render json: { message: "success", filePath: success_path } }
      end
    else
      flash[:alert] = result[:message]
      respond_to do |format|
        format.html do
          if failure_view
            render failure_view
          else
            redirect_to failure_path
          end
        end
        format.json { render json: { message: "failed", filePath: failure_path } }
      end
    end
  end

  def authorize_edit_tree!
    return if can?(current_user, :push_code, project)
    return if current_user && current_user.already_forked?(project)

    access_denied!
  end

  private

  def new_merge_request_path
    new_namespace_project_merge_request_path(
      @mr_source_project.namespace,
      @mr_source_project,
      merge_request: {
        source_project_id: @mr_source_project.id,
        target_project_id: @mr_target_project.id,
        source_branch: @mr_source_branch,
        target_branch: @mr_target_branch
      }
    )
  end

65 66 67 68 69 70 71 72 73 74 75
  def existent_merge_request_path
    namespace_project_merge_request_path(@mr_target_project.namespace, @mr_target_project, @merge_request)
  end

  def merge_request_exists?
    @merge_request = @mr_target_project.merge_requests.opened.where(
                       source_branch: @mr_source_branch,
                       target_branch: @mr_target_branch
                     ).first
  end

76 77 78 79 80 81 82 83 84 85 86 87 88
  def different_project?
    @mr_source_project != @mr_target_project
  end

  def different_branch?
    @mr_source_branch != @mr_target_branch || different_project?
  end

  def create_merge_request?
    params[:create_merge_request].present? && different_branch?
  end

  def set_commit_variables
89
    @mr_source_branch ||= @target_branch
90 91 92 93 94 95 96 97 98 99 100 101 102

    if can?(current_user, :push_code, @project)
      # Edit file in this project
      @tree_edit_project = @project
      @mr_source_project = @project

      if @project.forked?
        # Merge request from this project to fork origin
        @mr_target_project = @project.forked_from_project
        @mr_target_branch = @mr_target_project.repository.root_ref
      else
        # Merge request to this project
        @mr_target_project = @project
103
        @mr_target_branch ||= @ref
104 105 106 107 108 109 110
      end
    else
      # Edit file in fork
      @tree_edit_project = current_user.fork_of(@project)
      # Merge request from fork to this project
      @mr_source_project = @tree_edit_project
      @mr_target_project = @project
111
      @mr_target_branch  ||= @ref
112 113 114
    end
  end
end