summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/config/normalizer.rb
blob: 09f9bf5f69f7bc8b41d74e1e242b59994de3f585 (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
60
61
62
63
64
65
66
67
68
# frozen_string_literal: true

module Gitlab
  module Ci
    class Config
      class Normalizer
        include Gitlab::Utils::StrongMemoize

        def initialize(jobs_config)
          @jobs_config = jobs_config
        end

        def normalize_jobs
          return @jobs_config if parallelized_jobs.empty?

          expand_parallelize_jobs do |job_name, config|
            if config[:dependencies]
              config[:dependencies] = expand_names(config[:dependencies])
            end

            if config[:needs]
              config[:needs] = expand_names(config[:needs])
            end

            config
          end
        end

        private

        def expand_names(job_names)
          return unless job_names

          job_names.flat_map do |job_name|
            parallelized_jobs[job_name.to_sym] || job_name
          end
        end

        def parallelized_jobs
          strong_memoize(:parallelized_jobs) do
            @jobs_config.each_with_object({}) do |(job_name, config), hash|
              next unless config[:parallel]

              hash[job_name] = self.class.parallelize_job_names(job_name, config[:parallel])
            end
          end
        end

        def expand_parallelize_jobs
          @jobs_config.each_with_object({}) do |(job_name, config), hash|
            if parallelized_jobs.key?(job_name)
              parallelized_jobs[job_name].each_with_index do |name, index|
                hash[name.to_sym] =
                  yield(name, config.merge(name: name, instance: index + 1))
              end
            else
              hash[job_name] = yield(job_name, config)
            end
          end
        end

        def self.parallelize_job_names(name, total)
          Array.new(total) { |index| "#{name} #{index + 1}/#{total}" }
        end
      end
    end
  end
end