Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /lib/gitlab/issuable
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'lib/gitlab/issuable')
-rw-r--r--lib/gitlab/issuable/clone/attributes_rewriter.rb66
-rw-r--r--lib/gitlab/issuable/clone/copy_resource_events_service.rb116
2 files changed, 182 insertions, 0 deletions
diff --git a/lib/gitlab/issuable/clone/attributes_rewriter.rb b/lib/gitlab/issuable/clone/attributes_rewriter.rb
new file mode 100644
index 00000000000..fd9b2f086fc
--- /dev/null
+++ b/lib/gitlab/issuable/clone/attributes_rewriter.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Issuable
+ module Clone
+ class AttributesRewriter
+ attr_reader :current_user, :original_entity, :target_parent
+
+ def initialize(current_user, original_entity, target_parent)
+ raise ArgumentError, 'target_parent cannot be nil' if target_parent.nil?
+
+ @current_user = current_user
+ @original_entity = original_entity
+ @target_parent = target_parent
+ end
+
+ def execute(include_milestone: true)
+ attributes = { label_ids: cloneable_labels.pluck_primary_key }
+
+ if include_milestone
+ milestone = matching_milestone(original_entity.milestone&.title)
+ attributes[:milestone_id] = milestone.id if milestone.present?
+ end
+
+ attributes
+ end
+
+ private
+
+ def cloneable_labels
+ params = {
+ project_id: project&.id,
+ group_id: group&.id,
+ title: original_entity.labels.select(:title),
+ include_ancestor_groups: true
+ }
+
+ params[:only_group_labels] = true if target_parent.is_a?(Group)
+
+ LabelsFinder.new(current_user, params).execute
+ end
+
+ def matching_milestone(title)
+ return if title.blank?
+
+ params = { title: title, project_ids: project&.id, group_ids: group&.id }
+
+ milestones = MilestonesFinder.new(params).execute
+ milestones.first
+ end
+
+ def project
+ target_parent if target_parent.is_a?(Project)
+ end
+
+ def group
+ if target_parent.is_a?(Group)
+ target_parent
+ elsif target_parent&.group && current_user.can?(:read_group, target_parent.group)
+ target_parent.group
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/issuable/clone/copy_resource_events_service.rb b/lib/gitlab/issuable/clone/copy_resource_events_service.rb
new file mode 100644
index 00000000000..563805fcb01
--- /dev/null
+++ b/lib/gitlab/issuable/clone/copy_resource_events_service.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Issuable
+ module Clone
+ class CopyResourceEventsService
+ attr_reader :current_user, :original_entity, :new_entity
+
+ def initialize(current_user, original_entity, new_entity)
+ @current_user = current_user
+ @original_entity = original_entity
+ @new_entity = new_entity
+ end
+
+ def execute
+ copy_resource_label_events
+ copy_resource_milestone_events
+ copy_resource_state_events
+ end
+
+ private
+
+ def copy_resource_label_events
+ copy_events(ResourceLabelEvent.table_name, original_entity.resource_label_events) do |event|
+ event.attributes
+ .except('id', 'reference', 'reference_html')
+ .merge(entity_key => new_entity.id, 'action' => ResourceLabelEvent.actions[event.action])
+ end
+ end
+
+ def copy_resource_milestone_events
+ return unless milestone_events_supported?
+
+ copy_events(ResourceMilestoneEvent.table_name, original_entity.resource_milestone_events) do |event|
+ if event.remove?
+ event_attributes_with_milestone(event, nil)
+ else
+ destination_milestone = matching_milestone(event.milestone_title)
+
+ event_attributes_with_milestone(event, destination_milestone) if destination_milestone.present?
+ end
+ end
+ end
+
+ def copy_resource_state_events
+ return unless state_events_supported?
+
+ copy_events(ResourceStateEvent.table_name, original_entity.resource_state_events) do |event|
+ event.attributes
+ .except(*blocked_state_event_attributes)
+ .merge(entity_key => new_entity.id,
+ 'state' => ResourceStateEvent.states[event.state])
+ end
+ end
+
+ # Overriden on EE::Gitlab::Issuable::Clone::CopyResourceEventsService
+ def blocked_state_event_attributes
+ ['id']
+ end
+
+ def event_attributes_with_milestone(event, milestone)
+ event.attributes
+ .except('id')
+ .merge(entity_key => new_entity.id,
+ 'milestone_id' => milestone&.id,
+ 'action' => ResourceMilestoneEvent.actions[event.action],
+ 'state' => ResourceMilestoneEvent.states[event.state])
+ end
+
+ def copy_events(table_name, events_to_copy)
+ events_to_copy.find_in_batches do |batch|
+ events = batch.map do |event|
+ yield(event)
+ end.compact
+
+ ApplicationRecord.legacy_bulk_insert(table_name, events) # rubocop:disable Gitlab/BulkInsert
+ end
+ end
+
+ def entity_key
+ new_entity.class.name.underscore.foreign_key
+ end
+
+ def milestone_events_supported?
+ both_respond_to?(:resource_milestone_events)
+ end
+
+ def state_events_supported?
+ both_respond_to?(:resource_state_events)
+ end
+
+ def both_respond_to?(method)
+ original_entity.respond_to?(method) &&
+ new_entity.respond_to?(method)
+ end
+
+ def matching_milestone(title)
+ return if title.blank? || !new_entity.supports_milestone?
+
+ params = { title: title, project_ids: new_entity.project&.id, group_ids: group&.id }
+
+ milestones = MilestonesFinder.new(params).execute
+ milestones.first
+ end
+
+ def group
+ if new_entity.project&.group && current_user.can?(:read_group, new_entity.project.group)
+ new_entity.project.group
+ end
+ end
+ end
+ end
+ end
+end
+
+Gitlab::Issuable::Clone::CopyResourceEventsService.prepend_mod