From 65f4e7b2a1fe8946109c7aa0d59999bfaaeba257 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 15 May 2018 13:04:18 +0200 Subject: Add support for pattern matching in variables expressions --- lib/gitlab/ci/pipeline/expression/lexeme/matches.rb | 2 +- lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb | 2 ++ lib/gitlab/ci/pipeline/expression/lexer.rb | 4 +++- lib/gitlab/ci/pipeline/expression/statement.rb | 4 +++- spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb | 10 ++++++++++ spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb | 1 - spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb | 11 ++++++++--- 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb b/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb index 806f2082227..10957598f76 100644 --- a/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb +++ b/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb @@ -15,7 +15,7 @@ module Gitlab text = @left.evaluate(variables) regexp = @right.evaluate(variables) - regexp.scan(text).any? + regexp.scan(text.to_s).any? end def self.build(_value, behind, ahead) diff --git a/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb b/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb index 59b8e4fad4c..f7b12914249 100644 --- a/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb +++ b/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb @@ -3,6 +3,8 @@ module Gitlab module Pipeline module Expression module Lexeme + require_dependency 're2' + class Pattern < Lexeme::Value PATTERN = %r{/(?.+)/}.freeze diff --git a/lib/gitlab/ci/pipeline/expression/lexer.rb b/lib/gitlab/ci/pipeline/expression/lexer.rb index ebc6565266f..4cacb1e62c9 100644 --- a/lib/gitlab/ci/pipeline/expression/lexer.rb +++ b/lib/gitlab/ci/pipeline/expression/lexer.rb @@ -10,8 +10,10 @@ module Gitlab LEXEMES = [ Expression::Lexeme::Variable, Expression::Lexeme::String, + Expression::Lexeme::Pattern, Expression::Lexeme::Null, - Expression::Lexeme::Equals + Expression::Lexeme::Equals, + Expression::Lexeme::Matches ].freeze MAX_TOKENS = 100 diff --git a/lib/gitlab/ci/pipeline/expression/statement.rb b/lib/gitlab/ci/pipeline/expression/statement.rb index de37c50d2a2..8886cbae516 100644 --- a/lib/gitlab/ci/pipeline/expression/statement.rb +++ b/lib/gitlab/ci/pipeline/expression/statement.rb @@ -6,12 +6,14 @@ module Gitlab StatementError = Class.new(Expression::ExpressionError) GRAMMAR = [ + %w[variable], %w[variable equals string], %w[variable equals variable], %w[variable equals null], %w[string equals variable], %w[null equals variable], - %w[variable] + %w[variable matches pattern], + %w[pattern matches variable] ].freeze def initialize(statement, variables = {}) diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb index 22907b0554a..a8890262402 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb @@ -39,6 +39,16 @@ describe Gitlab::Ci::Pipeline::Expression::Lexeme::Matches do expect(operator.evaluate).to eq true end + it 'supports matching against a nil value' do + allow(left).to receive(:evaluate).and_return(nil) + allow(right).to receive(:evaluate) + .and_return(Gitlab::UntrustedRegexp.new('pattern')) + + operator = described_class.new(left, right) + + expect(operator.evaluate).to eq false + end + it 'supports multiline strings' do allow(left).to receive(:evaluate).and_return <<~TEXT My awesome contents diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb index 47385ce0a5b..a14a28056d8 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb @@ -1,5 +1,4 @@ require 'fast_spec_helper' -require_dependency 're2' describe Gitlab::Ci::Pipeline::Expression::Lexeme::Pattern do describe '.build' do diff --git a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb index 6d58838bf14..a5733c13768 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb @@ -84,7 +84,6 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do describe '#evaluate' do statements = [ ['$PRESENT_VARIABLE == "my variable"', true], - ["$PRESENT_VARIABLE == 'my variable'", true], ['"my variable" == $PRESENT_VARIABLE', true], ['$PRESENT_VARIABLE == null', false], ['$EMPTY_VARIABLE == null', false], @@ -93,7 +92,11 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do ['$UNDEFINED_VARIABLE == null', true], ['null == $UNDEFINED_VARIABLE', true], ['$PRESENT_VARIABLE', 'my variable'], - ['$UNDEFINED_VARIABLE', nil] + ['$UNDEFINED_VARIABLE', nil], + ["$PRESENT_VARIABLE =~ /var.*e$/", true], + ["$PRESENT_VARIABLE =~ /^var.*/", false], + ["$EMPTY_VARIABLE =~ /var.*/", false], + ["$UNDEFINED_VARIABLE =~ /var.*/", false] ] statements.each do |expression, value| @@ -115,7 +118,9 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do ['$PRESENT_VARIABLE', true], ['$UNDEFINED_VARIABLE', false], ['$EMPTY_VARIABLE', false], - ['$INVALID = 1', false] + ['$INVALID = 1', false], + ["$PRESENT_VARIABLE =~ /var.*/", true], + ["$UNDEFINED_VARIABLE =~ /var.*/", false] ] statements.each do |expression, value| -- cgit v1.2.1