Detect circular dependenies in CI/CD extends: entry

This commit is contained in:
Grzegorz Bizon 2018-08-16 15:30:06 +02:00
parent ef26622d62
commit 2c41fbb148
3 changed files with 42 additions and 6 deletions

View file

@ -6,6 +6,7 @@ module Gitlab
include Enumerable
ExtensionError = Class.new(StandardError)
CircularDependencyError = Class.new(ExtensionError)
def initialize(hash)
@hash = hash

View file

@ -5,9 +5,9 @@ module Gitlab
class Entry
attr_reader :key
def initialize(key, hash, parent = nil)
def initialize(key, context, parent = nil)
@key = key
@hash = hash
@context = context
@parent = parent
end
@ -16,12 +16,12 @@ module Gitlab
end
def value
@value ||= @hash.fetch(@key)
@value ||= @context.fetch(@key)
end
def base
Extendable::Entry
.new(extends, @hash, self)
.new(extends, @context, self)
.extend!
end
@ -33,9 +33,17 @@ module Gitlab
value.fetch(:extends).to_sym
end
def path
Array(@parent&.path).compact.push(key)
end
def extend!
if path.count(key) > 1
raise Extendable::Collection::CircularDependencyError
end
if extensible?
@hash[key] = base.deep_merge(value)
@context[key] = base.deep_merge(value)
else
value
end

View file

@ -117,6 +117,33 @@ describe Gitlab::Ci::Config::Extendable::Collection do
end
pending 'when invalid `extends` is specified'
pending 'when circular dependecy has been detected'
context 'when circular dependecy has been detected' do
let(:hash) do
{
test: {
extends: 'something',
script: 'ls',
only: { refs: %w[master] }
},
something: {
extends: '.first',
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
'.first': {
extends: 'something',
script: 'run',
only: { kubernetes: 'active' }
}
}
end
it 'raises an error' do
expect { subject.extend! }
.to raise_error(described_class::CircularDependencyError)
end
end
end
end