Commit 977ea357 authored by Matija Čupić's avatar Matija Čupić

Separate bridge and DAG needs

Separates bridge and DAG needs into two separate entities to avoid any
ambiguity.
parent 2f1f43ae
...@@ -8,17 +8,60 @@ module EE ...@@ -8,17 +8,60 @@ module EE
## ##
# Entry that represents a cross-project needs dependency. # Entry that represents a cross-project needs dependency.
# #
class Needs < ::Gitlab::Config::Entry::Node class Needs < ::Gitlab::Config::Entry::Simplifiable
include ::Gitlab::Config::Entry::Validatable strategy :BridgeNeeds, if: -> (config) { config.is_a?(Hash) }
include ::Gitlab::Config::Entry::Attributable strategy :ComplexNeeds, if: -> (config) { config.is_a?(Array) }
ALLOWED_KEYS = %i[pipeline].freeze class BridgeNeeds < ::Gitlab::Config::Entry::Node
attributes :pipeline include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
validations do ALLOWED_KEYS = %i[pipeline].freeze
validates :config, presence: true attributes :pipeline
validates :config, allowed_keys: ALLOWED_KEYS
validates :pipeline, type: String, presence: true validations do
validates :config, presence: true
validates :config, allowed_keys: ALLOWED_KEYS
validates :pipeline, type: String, presence: true
end
end
class ComplexNeeds < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
validations do
validates :config, presence: true
validates :config, type: Array
validate :one_needs_pipeline
validate :needs_array_elements
end
def one_needs_pipeline
if config.count { |element| element.is_a?(Hash) } > 1
errors.add(:needs, 'needs hash element needs to have a pipeline key')
end
end
def needs_array_elements
config.each do |element|
next if element.is_a?(String)
unless element.is_a?(Hash) && element[:pipeline]
errors.add(:needs, 'needs hash element needs to have a pipeline key')
end
end
end
def value
bridge, pipeline = config.partition { |element| element.is_a?(Hash) }
{ bridge: bridge.first, pipeline: pipeline }
end
end
class UnknownStrategy < ::Gitlab::Config::Entry::Node
def errors
["#{location} has to be either an array of conditions or a hash"]
end
end end
end end
end end
......
...@@ -6,37 +6,22 @@ require_dependency 'active_model' ...@@ -6,37 +6,22 @@ require_dependency 'active_model'
describe EE::Gitlab::Ci::Config::Entry::Needs do describe EE::Gitlab::Ci::Config::Entry::Needs do
subject { described_class.new(config) } subject { described_class.new(config) }
context 'when upstream config is a non-empty string' do context 'when needs is a bridge needs' do
let(:config) { { pipeline: 'some/project' } } context 'when upstream config is a non-empty string' do
let(:config) { { pipeline: 'some/project' } }
describe '#valid?' do describe '#valid?' do
it { is_expected.to be_valid } it { is_expected.to be_valid }
end
describe '#value' do
it 'is returns a upstream configuration hash' do
expect(subject.value).to eq(pipeline: 'some/project')
end end
end
end
context 'when upstream config an empty string' do
let(:config) { '' }
describe '#valid?' do describe '#value' do
it { is_expected.not_to be_valid } it 'is returns a upstream configuration hash' do
end expect(subject.value).to eq(pipeline: 'some/project')
end
describe '#errors' do
it 'is returns an error about an empty config' do
expect(subject.errors.first)
.to eq("needs config can't be blank")
end end
end end
end
context 'when upstream configuration is not valid' do context 'when upstream config is not a string' do
context 'when branch is not provided' do
let(:config) { { pipeline: 123 } } let(:config) { { pipeline: 123 } }
describe '#valid?' do describe '#valid?' do
...@@ -46,9 +31,32 @@ describe EE::Gitlab::Ci::Config::Entry::Needs do ...@@ -46,9 +31,32 @@ describe EE::Gitlab::Ci::Config::Entry::Needs do
describe '#errors' do describe '#errors' do
it 'returns an error message' do it 'returns an error message' do
expect(subject.errors.first) expect(subject.errors.first)
.to eq('needs pipeline should be a string') .to eq('bridge needs pipeline should be a string')
end end
end end
end end
end end
context 'when needs is a complex needs' do
let(:config) { ['test', { pipeline: 'test' }] }
it 'test' do
subject
end
end
context 'when needs is empty' do
let(:config) { '' }
describe '#valid?' do
it { is_expected.not_to be_valid }
end
describe '#errors' do
it 'is returns an error about an empty config' do
expect(subject.errors.first)
.to end_with('has to be either an array of conditions or a hash')
end
end
end
end end
...@@ -40,7 +40,7 @@ module Gitlab ...@@ -40,7 +40,7 @@ module Gitlab
environment: job[:environment_name], environment: job[:environment_name],
coverage_regex: job[:coverage], coverage_regex: job[:coverage],
yaml_variables: yaml_variables(name), yaml_variables: yaml_variables(name),
needs_attributes: job[:needs]&.map { |need| { name: need } }, needs_attributes: job[:needs][:pipeline]&.map { |need| { name: need } },
interruptible: job[:interruptible], interruptible: job[:interruptible],
rules: job[:rules], rules: job[:rules],
options: { options: {
...@@ -59,7 +59,7 @@ module Gitlab ...@@ -59,7 +59,7 @@ module Gitlab
instance: job[:instance], instance: job[:instance],
start_in: job[:start_in], start_in: job[:start_in],
trigger: job[:trigger], trigger: job[:trigger],
bridge_needs: job[:needs] bridge_needs: job[:needs][:bridge]
}.compact }.compact }.compact }.compact
end end
...@@ -159,11 +159,11 @@ module Gitlab ...@@ -159,11 +159,11 @@ module Gitlab
end end
def validate_job_needs!(name, job) def validate_job_needs!(name, job)
return unless job[:needs] return unless job[:needs][:pipeline]
stage_index = @stages.index(job[:stage]) stage_index = @stages.index(job[:stage])
job[:needs].each do |need| job[:needs][:pipeline].each do |need|
raise ValidationError, "#{name} job: undefined need: #{need}" unless @jobs[need.to_sym] raise ValidationError, "#{name} job: undefined need: #{need}" unless @jobs[need.to_sym]
needs_stage_index = @stages.index(@jobs[need.to_sym][:stage]) needs_stage_index = @stages.index(@jobs[need.to_sym][:stage])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment