summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/config/normalizer.rb
blob: 7bd0e08e8178e5e922f0ea78c3425860f73ada56 (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
# frozen_string_literal: true

module Gitlab
  module Ci
    class Config
      class Normalizer
        class << self
          def normalize_jobs(jobs_config)
            parallelized_jobs = extract_parallelized_jobs(jobs_config)
            parallelized_config = parallelize_jobs(jobs_config, parallelized_jobs)
            parallelize_dependencies(parallelized_config, parallelized_jobs)
          end

          private

          def extract_parallelized_jobs(jobs_config)
            parallelized_jobs = {}

            jobs_config.each do |job_name, config|
              if config[:parallel]
                parallelized_jobs[job_name] = parallelize_job_names(job_name, config[:parallel])
              end
            end

            parallelized_jobs
          end

          def parallelize_jobs(jobs_config, parallelized_jobs)
            jobs_config.each_with_object({}) do |(job_name, config), hash|
              if parallelized_jobs.keys.include?(job_name)
                parallelized_jobs[job_name].each { |name, index| hash[name.to_sym] = config.merge(name: name, instance: index) }
              else
                hash[job_name] = config
              end

              hash
            end
          end

          def parallelize_dependencies(parallelized_config, parallelized_jobs)
            parallelized_config.each_with_object({}) do |(job_name, config), hash|
              intersection = config[:dependencies] & parallelized_jobs.keys.map(&:to_s)
              if intersection && intersection.any?
                deps = intersection.map { |dep| parallelized_jobs[dep.to_sym].map(&:first) }.flatten
                hash[job_name] = config.merge(dependencies: deps)
              else
                hash[job_name] = config
              end

              hash
            end
          end

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