summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/config/normalizer/matrix_strategy.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/config/normalizer/matrix_strategy.rb')
-rw-r--r--lib/gitlab/ci/config/normalizer/matrix_strategy.rb68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/gitlab/ci/config/normalizer/matrix_strategy.rb b/lib/gitlab/ci/config/normalizer/matrix_strategy.rb
new file mode 100644
index 00000000000..db21274a9ed
--- /dev/null
+++ b/lib/gitlab/ci/config/normalizer/matrix_strategy.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ class Normalizer
+ class MatrixStrategy
+ class << self
+ def applies_to?(config)
+ config.is_a?(Hash) && config.key?(:matrix)
+ end
+
+ def build_from(job_name, initial_config)
+ config = expand(initial_config[:matrix])
+ total = config.size
+
+ config.map.with_index do |vars, index|
+ new(job_name, index.next, vars, total)
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def expand(config)
+ config.flat_map do |config|
+ values = config.values
+
+ values[0]
+ .product(*values.from(1))
+ .map { |vals| config.keys.zip(vals).to_h }
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+
+ def initialize(job_name, instance, variables, total)
+ @job_name = job_name
+ @instance = instance
+ @variables = variables.to_h
+ @total = total
+ end
+
+ def attributes
+ {
+ name: name,
+ instance: instance,
+ variables: variables,
+ parallel: { total: total }
+ }
+ end
+
+ def name_with_details
+ vars = variables.map { |key, value| "#{key}=#{value}"}.join('; ')
+
+ "#{job_name} (#{vars})"
+ end
+
+ def name
+ "#{job_name} #{instance}/#{total}"
+ end
+
+ private
+
+ attr_reader :job_name, :instance, :variables, :total
+ end
+ end
+ end
+ end
+end