BigW Consortium Gitlab

creates_commit.rb 3.56 KB
Newer Older
1 2 3 4 5 6 7
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(
8
      start_project: @mr_target_project,
9
      start_branch: @mr_target_branch,
10
      target_branch: @mr_source_branch
11 12
    )

13
    result = service.new(
14
      @mr_source_project, current_user, commit_params).execute
15 16

    if result[:status] == :success
17
      update_flash_notice(success_notice)
18

19 20
      success_path = final_success_path(success_path)

21
      respond_to do |format|
22 23
        format.html { redirect_to success_path }
        format.json { render json: { message: "success", filePath: success_path } }
24 25 26
      end
    else
      flash[:alert] = result[:message]
27 28
      failure_path = failure_path.call if failure_path.respond_to?(:call)

29 30 31 32 33 34 35 36 37 38 39 40 41 42
      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!
43
    return if can_collaborate_with_project?
44 45 46 47 48 49

    access_denied!
  end

  private

50 51 52 53 54 55 56 57 58 59 60 61 62 63
  def update_flash_notice(success_notice)
    flash[:notice] = success_notice || "Your changes have been successfully committed."

    if create_merge_request?
      if merge_request_exists?
        flash[:notice] = nil
      else
        target = different_project? ? "project" : "branch"
        flash[:notice] << " You can now submit a merge request to get this change into the original #{target}."
      end
    end
  end

  def final_success_path(success_path)
64 65 66 67
    if create_merge_request?
      merge_request_exists? ? existing_merge_request_path : new_merge_request_path
    else
      success_path = success_path.call if success_path.respond_to?(:call)
68

69 70
      success_path
    end
71 72
  end

73 74 75 76 77 78 79 80 81 82 83 84 85
  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

86
  def existing_merge_request_path
87 88 89 90
    namespace_project_merge_request_path(@mr_target_project.namespace, @mr_target_project, @merge_request)
  end

  def merge_request_exists?
91 92
    return @merge_request if defined?(@merge_request)

93 94
    @merge_request = MergeRequestsFinder.new(current_user, project_id: @mr_target_project.id).execute.opened.
      find_by(source_branch: @mr_source_branch, target_branch: @mr_target_branch, source_project_id: @mr_source_project)
95 96
  end

97 98 99 100 101
  def different_project?
    @mr_source_project != @mr_target_project
  end

  def create_merge_request?
102
    # Even if the field is set, if we're checking the same branch
103 104 105
    # as the target branch in the same project,
    # we don't want to create a merge request.
    params[:create_merge_request].present? &&
106
      (different_project? || @mr_target_branch != @mr_source_branch)
107 108 109
  end

  def set_commit_variables
110 111 112 113 114 115 116
    if can?(current_user, :push_code, @project)
      @mr_source_project = @project
      @target_branch ||= @ref
    else
      @mr_source_project = current_user.fork_of(@project)
      @target_branch ||= @mr_source_project.repository.next_branch('patch')
    end
117

118 119
    # Merge request to this project
    @mr_target_project = @project
120
    @mr_target_branch ||= @ref || @target_branch
121

122
    @mr_source_branch = @target_branch
123
  end
124
end