Commit 8a2bc9b4 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Integration variables collections with expressions

parent 96d6193c
...@@ -8,9 +8,13 @@ module Gitlab ...@@ -8,9 +8,13 @@ module Gitlab
end end
def satisfied_by?(pipeline, build) def satisfied_by?(pipeline, build)
variables = Gitlab::Ci::Variables::Collection
.new(build.simple_variables)
.to_hash
statements = @expressions.map do |statement| statements = @expressions.map do |statement|
::Gitlab::Ci::Pipeline::Expression::Statement ::Gitlab::Ci::Pipeline::Expression::Statement
.new(statement, pipeline) .new(statement, variables)
end end
statements.any?(&:truthful?) statements.any?(&:truthful?)
......
...@@ -11,7 +11,7 @@ module Gitlab ...@@ -11,7 +11,7 @@ module Gitlab
end end
def evaluate(variables = {}) def evaluate(variables = {})
HashWithIndifferentAccess.new(variables).fetch(@name, nil) variables.with_indifferent_access.fetch(@name, nil)
end end
def self.build(string) def self.build(string)
......
...@@ -14,24 +14,9 @@ module Gitlab ...@@ -14,24 +14,9 @@ module Gitlab
%w[variable] %w[variable]
].freeze ].freeze
def initialize(statement, pipeline = nil) def initialize(statement, variables = {})
@lexer = Expression::Lexer.new(statement) @lexer = Expression::Lexer.new(statement)
@variables = variables.with_indifferent_access
return if pipeline.nil?
# REFACTORING, temporary refactoring stubs
#
@variables = pipeline.project.predefined_variables.map do |variable|
[variable[:key], variable[:value]]
end
@variables += pipeline.variables.map do |variable|
[variable.key, variable.value]
end
@variables += pipeline.predefined_variables.map do |variable|
[variable[:key], variable[:value]]
end
end end
def parse_tree def parse_tree
......
...@@ -30,7 +30,13 @@ module Gitlab ...@@ -30,7 +30,13 @@ module Gitlab
end end
def to_runner_variables def to_runner_variables
self.map(&:to_hash) self.map(&:to_runner_variable)
end
def to_hash
self.to_runner_variables
.map { |env| [env.fetch(:key), env.fetch(:value)] }
.to_h.with_indifferent_access
end end
end end
end end
......
...@@ -17,7 +17,7 @@ module Gitlab ...@@ -17,7 +17,7 @@ module Gitlab
end end
def ==(other) def ==(other)
to_hash == self.class.fabricate(other).to_hash to_runner_variable == self.class.fabricate(other).to_runner_variable
end end
## ##
...@@ -25,7 +25,7 @@ module Gitlab ...@@ -25,7 +25,7 @@ module Gitlab
# don't expose `file` attribute at all (stems from what the runner # don't expose `file` attribute at all (stems from what the runner
# expects). # expects).
# #
def to_hash def to_runner_variable
@variable.reject do |hash_key, hash_value| @variable.reject do |hash_key, hash_value|
hash_key == :file && hash_value == false hash_key == :file && hash_value == false
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::Build::Policy::Variables do describe Gitlab::Ci::Build::Policy::Variables do
let(:pipeline) { build_stubbed(:ci_empty_pipeline, ref: 'master') } set(:project) { create(:project) }
let(:build) { build_stubbed(:ci_build, pipeline: pipeline, ref: 'master') }
let(:ci_pipeline) do
build(:ci_empty_pipeline, project: project, ref: 'master')
end
let(:ci_build) do
build(:ci_build, pipeline: ci_pipeline, project: project, ref: 'master')
end
before do before do
pipeline.variables.build(key: 'CI_PROJECT_NAME', value: '') ci_pipeline.variables.build(key: 'CI_PROJECT_NAME', value: '')
end end
describe '#satisfied_by?' do describe '#satisfied_by?' do
it 'is satisfied by a defined and existing variable' do it 'is satisfied by a defined and existing variable' do
policy = described_class.new(['$CI_PROJECT_ID', '$UNDEFINED']) policy = described_class.new(['$CI_PROJECT_ID', '$UNDEFINED'])
expect(policy).to be_satisfied_by(pipeline, build) expect(policy).to be_satisfied_by(ci_pipeline, ci_build)
end end
it 'is not satisfied by an overriden empty variable' do it 'is not satisfied by an overriden empty variable' do
policy = described_class.new(['$CI_PROJECT_NAME']) policy = described_class.new(['$CI_PROJECT_NAME'])
expect(policy).not_to be_satisfied_by(pipeline, build) expect(policy).not_to be_satisfied_by(ci_pipeline, ci_build)
end end
it 'is satisfied by a truthy pipeline expression' do it 'is satisfied by a truthy pipeline expression' do
policy = described_class.new([%($CI_PIPELINE_SOURCE == "#{pipeline.source}")]) policy = described_class.new([%($CI_PIPELINE_SOURCE == "#{ci_pipeline.source}")])
expect(policy).to be_satisfied_by(pipeline, build) expect(policy).to be_satisfied_by(ci_pipeline, ci_build)
end end
it 'is not satisfied by a falsy pipeline expression' do it 'is not satisfied by a falsy pipeline expression' do
policy = described_class.new([%($CI_PIPELINE_SOURCE == "invalid source")]) policy = described_class.new([%($CI_PIPELINE_SOURCE == "invalid source")])
expect(policy).not_to be_satisfied_by(pipeline, build) expect(policy).not_to be_satisfied_by(ci_pipeline, ci_build)
end end
it 'is satisfied by a truthy expression using undefined variable' do it 'is satisfied by a truthy expression using undefined variable' do
policy = described_class.new(['$UNDEFINED', '$UNDEFINED == null']) policy = described_class.new(['$UNDEFINED', '$UNDEFINED == null'])
expect(policy).to be_satisfied_by(pipeline, build) expect(policy).to be_satisfied_by(ci_pipeline, ci_build)
end end
it 'does not persist neither pipeline nor build' do
described_class.new('$VAR').satisfied_by?(ci_pipeline, ci_build)
expect(ci_pipeline).not_to be_persisted
expect(ci_build).not_to be_persisted
end
pending 'test for secret variables'
end end
end end
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Statement do describe Gitlab::Ci::Pipeline::Expression::Statement do
let(:pipeline) { build(:ci_pipeline) }
subject do subject do
described_class.new(text, pipeline) described_class.new(text, variables)
end end
before do let(:variables) do
variables = [{ key: 'PRESENT_VARIABLE', value: 'my variable' }, { 'PRESENT_VARIABLE' => 'my variable',
{ key: 'EMPTY_VARIABLE', value: '' }] EMPTY_VARIABLE: '' }
pipeline.variables.build(variables)
end end
describe '.new' do describe '.new' do
context 'when pipeline is not provided' do context 'when variables are not provided' do
it 'allows to properly initialize the statement' do it 'allows to properly initializes the statement' do
statement = described_class.new('$PRESENT_VARIABLE') statement = described_class.new('$PRESENT_VARIABLE')
expect(statement.evaluate).to be_nil expect(statement.evaluate).to be_nil
......
...@@ -46,9 +46,13 @@ describe Gitlab::Ci::Variables::Collection::Item do ...@@ -46,9 +46,13 @@ describe Gitlab::Ci::Variables::Collection::Item do
end end
end end
describe '#to_hash' do describe '#to_runner_variable' do
it 'returns a hash representation of a collection item' do it 'returns a runner-compatible hash representation' do
expect(described_class.new(**variable).to_hash).to eq variable runner_variable = described_class
.new(**variable)
.to_runner_variable
expect(runner_variable).to eq variable
end end
end end
end end
...@@ -7,7 +7,7 @@ describe Gitlab::Ci::Variables::Collection do ...@@ -7,7 +7,7 @@ describe Gitlab::Ci::Variables::Collection do
collection = described_class.new([variable]) collection = described_class.new([variable])
expect(collection.first.to_hash).to eq variable expect(collection.first.to_runner_variable).to eq variable
end end
it 'can be initialized without an argument' do it 'can be initialized without an argument' do
...@@ -96,4 +96,19 @@ describe Gitlab::Ci::Variables::Collection do ...@@ -96,4 +96,19 @@ describe Gitlab::Ci::Variables::Collection do
.to eq [{ key: 'TEST', value: 1, public: true }] .to eq [{ key: 'TEST', value: 1, public: true }]
end end
end end
describe '#to_hash' do
it 'returns regular hash in valid order without duplicates' do
collection = described_class.new
.append(key: 'TEST1', value: 'test-1')
.append(key: 'TEST2', value: 'test-2')
.append(key: 'TEST1', value: 'test-3')
expect(collection.to_hash).to eq('TEST1' => 'test-3',
'TEST2' => 'test-2')
expect(collection.to_hash).to include(TEST1: 'test-3')
expect(collection.to_hash).not_to include(TEST1: 'test-1')
end
end
end end
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