summaryrefslogtreecommitdiff
path: root/tooling/danger/sidekiq_args.rb
blob: d06bb92ca6d3d6adc6c150c2c1eb22f247430cec (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
53
54
55
56
57
58
59
# frozen_string_literal: true

module Tooling
  module Danger
    module SidekiqArgs
      include ::Danger::Helpers

      WORKER_FILES_REGEX = 'app/workers'
      EE_PREFIX = 'ee/'
      DEF_PERFORM = "def perform"
      DEF_PERFORM_REGEX = /[\s+-]*def perform\((.*)\)/
      BEFORE_DEF_PERFORM_REGEX = /^[\s-]*def perform\b/
      AFTER_DEF_PERFORM_REGEX = /^[\s+]*def perform\b/

      SUGGEST_MR_COMMENT = <<~SUGGEST_COMMENT
        Please follow the [sidekiq development guidelines](https://docs.gitlab.com/ee/development/sidekiq/compatibility_across_updates.html#changing-the-arguments-for-a-worker) when changing sidekiq worker arguments.
      SUGGEST_COMMENT

      def changed_worker_files(ee: :include)
        changed_files = helper.all_changed_files
        folder_prefix =
          case ee
          when :include
            "(#{EE_PREFIX})?"
          when :only
            EE_PREFIX
          when :exclude
            nil
          end

        changed_files.grep(%r{\A#{folder_prefix}#{WORKER_FILES_REGEX}})
      end

      def args_changed?(diff)
        # Find the "before" and "after" versions of the perform method definition
        before_def_perform = diff.find { |line| BEFORE_DEF_PERFORM_REGEX.match?(line) }
        after_def_perform = diff.find { |line| AFTER_DEF_PERFORM_REGEX.match?(line) }

        # args are not changed if there is no before or after def perform method
        return false unless before_def_perform && after_def_perform

        # Extract the perform  method arguments from the "before" and "after" versions
        before_args, after_args = diff.flat_map { |line| line.scan(DEF_PERFORM_REGEX) }

        before_args != after_args
      end

      def add_comment_for_matched_line(filename)
        diff = helper.changed_lines(filename)
        return unless args_changed?(diff)

        file_lines = project_helper.file_lines(filename)

        perform_method_line = file_lines.index { |line| line.include?(DEF_PERFORM) }
        markdown(format(SUGGEST_MR_COMMENT), file: filename, line: perform_method_line.succ)
      end
    end
  end
end