diff options
author | Ritave <olaf.tomalka@gmail.com> | 2016-11-02 12:58:59 +0100 |
---|---|---|
committer | Ritave <olaf.tomalka@gmail.com> | 2017-01-31 12:50:52 +0100 |
commit | 5d871dccbee115691ef109dfc857123503869a0e (patch) | |
tree | 11a6bab0f1b6b60f6eb789c9503347c6de253569 /app/services/labels | |
parent | b525aff665f139cd12ac5a6df78d722427e759cc (diff) | |
download | gitlab-ce-5d871dccbee115691ef109dfc857123503869a0e.tar.gz |
Abillity to promote project labels to group labels
Fixes #24021
Diffstat (limited to 'app/services/labels')
-rw-r--r-- | app/services/labels/promote_service.rb | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb new file mode 100644 index 00000000000..76d0ba67b07 --- /dev/null +++ b/app/services/labels/promote_service.rb @@ -0,0 +1,71 @@ +module Labels + class PromoteService < BaseService + BATCH_SIZE = 1000 + + def execute(label) + return unless project.group && + label.is_a?(ProjectLabel) + + Label.transaction do + new_label = clone_label_to_group_label(label) + + label_ids_for_merge(new_label).find_in_batches(batch_size: BATCH_SIZE) do |batched_ids| + update_issuables(new_label, batched_ids) + update_issue_board_lists(new_label, batched_ids) + update_priorities(new_label, batched_ids) + # Order is important, project labels need to be last + update_project_labels(batched_ids) + end + + # We skipped validations during creation. Let's run them now, after deleting conflicting labels + raise ActiveRecord::RecordInvalid.new(new_label) unless new_label.valid? + new_label + end + end + + private + + def label_ids_for_merge(new_label) + LabelsFinder. + new(current_user, title: new_label.title, group_id: project.group.id). + execute(skip_authorization: true). + where.not(id: new_label). + select(:id) # Can't use pluck() to avoid object-creation because of the batching + end + + def update_issuables(new_label, label_ids) + LabelLink. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_issue_board_lists(new_label, label_ids) + List. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_priorities(new_label, label_ids) + LabelPriority. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_project_labels(label_ids) + Label.where(id: label_ids).delete_all + end + + def clone_label_to_group_label(label) + params = label.attributes.slice('title', 'description', 'color') + # Since the title of the new label has to be the same as the previous labels + # and we're merging old labels in batches we'll skip validation to omit 2-step + # merge process and do it in one batch + # We'll be forcing validation at the end of the transaction to ensure everything + # was merged correctly + new_label = GroupLabel.new(params.merge(group: project.group)) + new_label.save(validate: false) + + new_label + end + end +end |