debian-mirror-gitlab/app/presenters/merge_request_presenter.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

297 lines
8.5 KiB
Ruby
Raw Normal View History

2018-11-18 11:00:15 +05:30
# frozen_string_literal: true
2017-08-17 22:00:37 +05:30
class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
include GitlabRoutingHelper
include MarkupHelper
include TreeHelper
2018-05-09 12:01:36 +05:30
include ChecksCollaboration
2018-03-17 18:26:18 +05:30
include Gitlab::Utils::StrongMemoize
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
delegator_override_with Gitlab::Utils::StrongMemoize # This module inclusion is expected. See https://gitlab.com/gitlab-org/gitlab/-/issues/352884.
2021-11-18 22:05:49 +05:30
2020-07-28 23:09:34 +05:30
APPROVALS_WIDGET_BASE_TYPE = 'base'
2021-11-18 22:05:49 +05:30
presents ::MergeRequest, as: :merge_request
2017-08-17 22:00:37 +05:30
def ci_status
if pipeline
status = pipeline.status
2019-07-31 22:56:46 +05:30
status = "success-with-warnings" if pipeline.success? && pipeline.has_warnings?
2017-08-17 22:00:37 +05:30
status || "preparing"
else
2021-09-30 23:02:18 +05:30
ci_integration = source_project.try(:ci_integration)
ci_integration&.commit_status(diff_head_sha, source_branch)
2017-08-17 22:00:37 +05:30
end
end
2019-09-04 21:01:54 +05:30
def cancel_auto_merge_path
if can_cancel_auto_merge?(current_user)
cancel_auto_merge_project_merge_request_path(project, merge_request)
2017-08-17 22:00:37 +05:30
end
end
def create_issue_to_resolve_discussions_path
if can?(current_user, :create_issue, project) && project.issues_enabled?
2017-09-10 17:25:29 +05:30
new_project_issue_path(project, merge_request_to_resolve_discussions_of: iid)
2017-08-17 22:00:37 +05:30
end
end
def remove_wip_path
2021-01-03 14:25:43 +05:30
if can?(current_user, :update_merge_request, merge_request.project)
2017-09-10 17:25:29 +05:30
remove_wip_project_merge_request_path(project, merge_request)
2017-08-17 22:00:37 +05:30
end
end
def merge_path
if can_be_merged_by?(current_user)
2017-09-10 17:25:29 +05:30
merge_project_merge_request_path(project, merge_request)
2017-08-17 22:00:37 +05:30
end
end
def revert_in_fork_path
2018-03-17 18:26:18 +05:30
if user_can_fork_project? && cached_can_be_reverted?
2017-08-17 22:00:37 +05:30
continue_params = {
to: merge_request_path(merge_request),
2019-07-31 22:56:46 +05:30
notice: _('%{edit_in_new_fork_notice} Try to cherry-pick this commit again.') % { edit_in_new_fork_notice: edit_in_new_fork_notice },
2017-08-17 22:00:37 +05:30
notice_now: edit_in_new_fork_notice_now
}
2017-09-10 17:25:29 +05:30
project_forks_path(merge_request.project,
2017-08-17 22:00:37 +05:30
namespace_key: current_user.namespace.id,
continue: continue_params)
end
end
def cherry_pick_in_fork_path
if user_can_fork_project? && can_be_cherry_picked?
continue_params = {
to: merge_request_path(merge_request),
2019-07-31 22:56:46 +05:30
notice: _('%{edit_in_new_fork_notice} Try to revert this commit again.') % { edit_in_new_fork_notice: edit_in_new_fork_notice },
2017-08-17 22:00:37 +05:30
notice_now: edit_in_new_fork_notice_now
}
2017-09-10 17:25:29 +05:30
project_forks_path(project,
2017-08-17 22:00:37 +05:30
namespace_key: current_user.namespace.id,
continue: continue_params)
end
end
def conflict_resolution_path
if conflicts.can_be_resolved_in_ui? && conflicts.can_be_resolved_by?(current_user)
2017-09-10 17:25:29 +05:30
conflicts_project_merge_request_path(project, merge_request)
end
end
2018-03-17 18:26:18 +05:30
def rebase_path
2018-03-27 19:54:05 +05:30
if !rebase_in_progress? && should_be_rebased? && can_push_to_source_branch?
2018-03-17 18:26:18 +05:30
rebase_project_merge_request_path(project, merge_request)
end
end
2017-09-10 17:25:29 +05:30
def target_branch_tree_path
if target_branch_exists?
project_tree_path(project, target_branch)
2017-08-17 22:00:37 +05:30
end
end
def target_branch_commits_path
if target_branch_exists?
2017-09-10 17:25:29 +05:30
project_commits_path(project, target_branch)
2017-08-17 22:00:37 +05:30
end
end
2019-07-07 11:18:12 +05:30
def target_branch_path
if target_branch_exists?
project_branch_path(project, target_branch)
end
end
def source_branch_commits_path
if source_branch_exists?
project_commits_path(source_project, source_branch)
end
end
2017-08-17 22:00:37 +05:30
def source_branch_path
if source_branch_exists?
2017-09-10 17:25:29 +05:30
project_branch_path(source_project, source_branch)
2017-08-17 22:00:37 +05:30
end
end
def source_branch_with_namespace_link
namespace = source_project_namespace
branch = source_branch
2018-11-18 11:00:15 +05:30
namespace_link = source_branch_exists? ? link_to(namespace, project_path(source_project)) : ERB::Util.html_escape(namespace)
branch_link = source_branch_exists? ? link_to(branch, project_tree_path(source_project, source_branch)) : ERB::Util.html_escape(branch)
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
for_fork? ? "#{namespace_link}:#{branch_link}" : branch_link
2017-08-17 22:00:37 +05:30
end
def closing_issues_links
2017-09-10 17:25:29 +05:30
markdown(
issues_sentence(project, closing_issues),
pipeline: :gfm,
author: author,
project: project,
2022-01-26 12:08:38 +05:30
issuable_reference_expansion_enabled: true
2017-09-10 17:25:29 +05:30
)
2017-08-17 22:00:37 +05:30
end
def mentioned_issues_links
2017-09-10 17:25:29 +05:30
markdown(
issues_sentence(project, mentioned_issues),
pipeline: :gfm,
author: author,
project: project,
2022-01-26 12:08:38 +05:30
issuable_reference_expansion_enabled: true
2017-09-10 17:25:29 +05:30
)
2017-08-17 22:00:37 +05:30
end
2022-05-07 20:08:51 +05:30
def assign_to_closing_issues_path
assign_related_issues_project_merge_request_path(project, merge_request)
end
def assign_to_closing_issues_count
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2021-06-08 01:23:25 +05:30
issues = MergeRequests::AssignIssuesService.new(project: project,
current_user: current_user,
params: {
merge_request: merge_request,
closes_issues: closing_issues
}).assignable_issues
2022-05-07 20:08:51 +05:30
issues.count
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2017-08-17 22:00:37 +05:30
end
def can_revert_on_current_merge_request?
2018-05-09 12:01:36 +05:30
can_collaborate_with_project?(project) && cached_can_be_reverted?
2017-08-17 22:00:37 +05:30
end
def can_cherry_pick_on_current_merge_request?
2018-05-09 12:01:36 +05:30
can_collaborate_with_project?(project) && can_be_cherry_picked?
2017-08-17 22:00:37 +05:30
end
2018-03-17 18:26:18 +05:30
def can_push_to_source_branch?
2018-03-27 19:54:05 +05:30
return false unless source_branch_exists?
!!::Gitlab::UserAccess
2020-10-24 23:57:45 +05:30
.new(current_user, container: source_project)
2018-03-27 19:54:05 +05:30
.can_push_to_branch?(source_branch)
2018-03-17 18:26:18 +05:30
end
2021-11-18 22:05:49 +05:30
delegator_override :can_remove_source_branch?
2018-11-08 19:23:39 +05:30
def can_remove_source_branch?
source_branch_exists? && merge_request.can_remove_source_branch?(current_user)
end
2019-02-02 18:00:53 +05:30
def can_read_pipeline?
pipeline && can?(current_user, :read_pipeline, pipeline)
end
2018-11-08 19:23:39 +05:30
def mergeable_discussions_state
# This avoids calling MergeRequest#mergeable_discussions_state without
# considering the state of the MR first. If a MR isn't mergeable, we can
# safely short-circuit it.
if merge_request.mergeable_state?(skip_ci_check: true, skip_discussions_check: true)
merge_request.mergeable_discussions_state?
else
false
end
end
2021-11-18 22:05:49 +05:30
delegator_override :subscribed?
2018-11-08 19:23:39 +05:30
def subscribed?
merge_request.subscribed?(current_user, merge_request.target_project)
end
2019-07-07 11:18:12 +05:30
def source_branch_link
if source_branch_exists?
link_to(source_branch, source_branch_commits_path, class: 'ref-name')
else
content_tag(:span, source_branch, class: 'ref-name')
end
end
def target_branch_link
if target_branch_exists?
link_to(target_branch, target_branch_commits_path, class: 'ref-name')
else
content_tag(:span, target_branch, class: 'ref-name')
end
end
2020-07-28 23:09:34 +05:30
def api_approvals_path
expose_path(api_v4_projects_merge_requests_approvals_path(id: project.id, merge_request_iid: merge_request.iid))
end
def api_approve_path
expose_path(api_v4_projects_merge_requests_approve_path(id: project.id, merge_request_iid: merge_request.iid))
end
def api_unapprove_path
expose_path(api_v4_projects_merge_requests_unapprove_path(id: project.id, merge_request_iid: merge_request.iid))
end
def approvals_widget_type
APPROVALS_WIDGET_BASE_TYPE
end
2021-10-27 15:23:28 +05:30
def closing_issues
strong_memoize(:closing_issues) do
visible_closing_issues_for(current_user)
end
end
def mentioned_issues
strong_memoize(:mentioned_issues) do
issues_mentioned_but_not_closing(current_user)
end
end
2022-01-26 12:08:38 +05:30
delegator_override :pipeline_coverage_delta
def pipeline_coverage_delta
return unless merge_request.pipeline_coverage_delta.present?
'%.2f' % merge_request.pipeline_coverage_delta
end
2017-08-17 22:00:37 +05:30
private
2018-03-17 18:26:18 +05:30
def cached_can_be_reverted?
strong_memoize(:can_be_reverted) do
can_be_reverted?(current_user)
end
end
2017-08-17 22:00:37 +05:30
def conflicts
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2017-08-17 22:00:37 +05:30
@conflicts ||= MergeRequests::Conflicts::ListService.new(merge_request)
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2017-08-17 22:00:37 +05:30
end
def pipeline
2018-03-17 18:26:18 +05:30
@pipeline ||= actual_head_pipeline
2017-08-17 22:00:37 +05:30
end
def issues_sentence(project, issues)
# Sorting based on the `#123` or `group/project#123` reference will sort
# local issues first.
issues.map do |issue|
issue.to_reference(project)
end.sort.to_sentence
end
def user_can_fork_project?
can?(current_user, :fork_project, project)
end
2022-05-07 20:08:51 +05:30
# Avoid including ActionView::Helpers::UrlHelper
def link_to(*args)
ApplicationController.helpers.link_to(*args)
end
2017-08-17 22:00:37 +05:30
end
2019-12-04 20:38:33 +05:30
2021-06-08 01:23:25 +05:30
MergeRequestPresenter.prepend_mod_with('MergeRequestPresenter')