summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-08-17 10:07:38 +0200
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-08-17 10:07:38 +0200
commitb4bc6db804b0f671ae2f83999a9b86f0611c62fd (patch)
treedec7e9688c9b8da36fbc1726792c440ab82f6a12
parent53a053893d4cabcd58e13febf98d4df06a6e3bd7 (diff)
downloadgitlab-ce-b4bc6db804b0f671ae2f83999a9b86f0611c62fd.tar.gz
Improve extendable CI/CD config hash collection
-rw-r--r--lib/gitlab/ci/config/extendable/collection.rb17
-rw-r--r--lib/gitlab/ci/config/extendable/entry.rb26
-rw-r--r--spec/lib/gitlab/ci/config/extendable/collection_spec.rb37
3 files changed, 45 insertions, 35 deletions
diff --git a/lib/gitlab/ci/config/extendable/collection.rb b/lib/gitlab/ci/config/extendable/collection.rb
index e59884439a2..cdc8eb6614d 100644
--- a/lib/gitlab/ci/config/extendable/collection.rb
+++ b/lib/gitlab/ci/config/extendable/collection.rb
@@ -6,26 +6,23 @@ module Gitlab
include Enumerable
ExtensionError = Class.new(StandardError)
+ InvalidExtensionError = Class.new(ExtensionError)
CircularDependencyError = Class.new(ExtensionError)
def initialize(hash)
- @hash = hash
+ @hash = hash.dup
+
+ each { |entry| entry.extend! if entry.extensible? }
end
def each
- @hash.each_pair do |key, value|
- next unless value.key?(:extends)
-
+ @hash.each_key do |key|
yield Extendable::Entry.new(key, @hash)
end
end
- def extend!
- each do |entry|
- raise ExtensionError unless entry.valid?
-
- entry.extend!
- end
+ def to_hash
+ @hash.to_h
end
end
end
diff --git a/lib/gitlab/ci/config/extendable/entry.rb b/lib/gitlab/ci/config/extendable/entry.rb
index 96b0bd1a2ce..d5eef647b3e 100644
--- a/lib/gitlab/ci/config/extendable/entry.rb
+++ b/lib/gitlab/ci/config/extendable/entry.rb
@@ -19,9 +19,9 @@ module Gitlab
@value ||= @context.fetch(@key)
end
- def base
+ def base_hash
Extendable::Entry
- .new(extends, @context, self)
+ .new(extends_key, @context, self)
.extend!
end
@@ -29,8 +29,8 @@ module Gitlab
value.key?(:extends)
end
- def extends
- value.fetch(:extends).to_sym
+ def extends_key
+ value.fetch(:extends).to_s.to_sym
end
def path
@@ -38,16 +38,30 @@ module Gitlab
end
def extend!
- if path.count(key) > 1
+ if circular_dependency?
raise Extendable::Collection::CircularDependencyError
end
+ if invalid_extends_key?
+ raise Extendable::Collection::InvalidExtensionError
+ end
+
if extensible?
- @context[key] = base.deep_merge(value)
+ @context[key] = base_hash.deep_merge(value)
else
value
end
end
+
+ private
+
+ def circular_dependency?
+ path.count(key) > 1
+ end
+
+ def invalid_extends_key?
+ !@context.key?(key)
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/config/extendable/collection_spec.rb b/spec/lib/gitlab/ci/config/extendable/collection_spec.rb
index 08c929ef70d..796683fea63 100644
--- a/spec/lib/gitlab/ci/config/extendable/collection_spec.rb
+++ b/spec/lib/gitlab/ci/config/extendable/collection_spec.rb
@@ -13,23 +13,13 @@ describe Gitlab::Ci::Config::Extendable::Collection do
{ something: { script: 'ls' }, test: test }
end
- it 'yields the test hash' do
- expect { |b| subject.each(&b) }.to yield_control
- end
- end
-
- context 'when not extending using a hash' do
- let(:hash) do
- { something: { extends: [1], script: 'ls' } }
- end
-
- it 'yields invalid extends as well' do
+ it 'yields control' do
expect { |b| subject.each(&b) }.to yield_control
end
end
end
- describe '#extend!' do
+ describe '#to_hash' do
context 'when a hash has a single simple extension' do
let(:hash) do
{
@@ -47,7 +37,7 @@ describe Gitlab::Ci::Config::Extendable::Collection do
end
it 'extends a hash with a deep reverse merge' do
- expect(subject.extend!).to eq(
+ expect(subject.to_hash).to eq(
something: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
@@ -88,7 +78,7 @@ describe Gitlab::Ci::Config::Extendable::Collection do
end
it 'extends a hash with a deep reverse merge' do
- expect(subject.extend!).to eq(
+ expect(subject.to_hash).to eq(
'.first': {
script: 'run',
only: { kubernetes: 'active' }
@@ -139,8 +129,8 @@ describe Gitlab::Ci::Config::Extendable::Collection do
}
end
- it 'raises an error' do
- expect { subject.extend! }
+ it 'raises an error about circular dependency' do
+ expect { subject.to_hash }
.to raise_error(described_class::CircularDependencyError)
end
end
@@ -156,12 +146,21 @@ describe Gitlab::Ci::Config::Extendable::Collection do
}
end
- it 'raises an error' do
- expect { subject.extend! }
+ it 'raises an error about circular dependency' do
+ expect { subject.to_hash }
.to raise_error(described_class::CircularDependencyError)
end
end
- pending 'when invalid `extends` is specified'
+ context 'when invalid extends value is specified' do
+ let(:hash) do
+ { something: { extends: 1, script: 'ls' } }
+ end
+
+ it 'raises an error about invalid extension' do
+ expect { subject.to_hash }
+ .to raise_error(described_class::InvalidExtensionError)
+ end
+ end
end
end