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

task_list_reference_replacement_service.rb « work_items « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1044a4feb886d3eb51dd615f0a4abb98514e67e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
# frozen_string_literal: true

module WorkItems
  class TaskListReferenceReplacementService
    STALE_OBJECT_MESSAGE = 'Stale work item. Check lock version'

    def initialize(work_item:, work_item_reference:, line_number_start:, line_number_end:, title:, lock_version:)
      @work_item = work_item
      @work_item_reference = work_item_reference
      @line_number_start = line_number_start
      @line_number_end = line_number_end
      @title = title
      @lock_version = lock_version
    end

    def execute
      return ::ServiceResponse.error(message: STALE_OBJECT_MESSAGE) if @work_item.lock_version > @lock_version
      return ::ServiceResponse.error(message: 'line_number_start must be greater than 0') if @line_number_start < 1
      return ::ServiceResponse.error(message: 'line_number_end must be greater or equal to line_number_start') if @line_number_end < @line_number_start
      return ::ServiceResponse.error(message: "Work item description can't be blank") if @work_item.description.blank?

      source_lines = @work_item.description.split("\n")
      markdown_task_first_line = source_lines[@line_number_start - 1]
      task_line = Taskable::ITEM_PATTERN.match(markdown_task_first_line)

      return ::ServiceResponse.error(message: "Unable to detect a task on line #{@line_number_start}") unless task_line

      captures = task_line.captures

      markdown_task_first_line.sub!(Taskable::ITEM_PATTERN, "#{captures[0]} #{captures[1]} #{@work_item_reference}+")

      source_lines[@line_number_start - 1] = markdown_task_first_line
      remove_additional_lines!(source_lines)

      @work_item.update!(description: source_lines.join("\n"))

      ::ServiceResponse.success
    rescue ActiveRecord::StaleObjectError
      ::ServiceResponse.error(message: STALE_OBJECT_MESSAGE)
    end

    private

    def remove_additional_lines!(source_lines)
      return if @line_number_end <= @line_number_start

      source_lines.delete_if.each_with_index do |_line, index|
        index >= @line_number_start && index < @line_number_end
      end
    end
  end
end