Detect circular dependenies in CI/CD extends:
entry
This commit is contained in:
parent
ef26622d62
commit
2c41fbb148
3 changed files with 42 additions and 6 deletions
|
@ -6,6 +6,7 @@ module Gitlab
|
|||
include Enumerable
|
||||
|
||||
ExtensionError = Class.new(StandardError)
|
||||
CircularDependencyError = Class.new(ExtensionError)
|
||||
|
||||
def initialize(hash)
|
||||
@hash = hash
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue