Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2018-05-18 15:08:12 +0300
committerKamil Trzciński <ayufan@ayufan.eu>2018-05-18 15:08:12 +0300
commit46d5ab68b700509e38efc48b8bbe2be128c4f390 (patch)
tree34570f017d82e8ce420b90a73c9af1783fc1671b /lib/gitlab/ci/pipeline
parente330b709469747c65c3f7d6c13fac0ac8dca0615 (diff)
parentafa245142117a7e90ff6046133a2402fb8c09cb1 (diff)
Merge branch 'feature/gb/add-regexp-variables-expression' into 'master'
Add support for variables expression regexp syntax Closes #43601 See merge request gitlab-org/gitlab-ce!18902
Diffstat (limited to 'lib/gitlab/ci/pipeline')
-rw-r--r--lib/gitlab/ci/pipeline/expression.rb10
-rw-r--r--lib/gitlab/ci/pipeline/expression/lexeme/matches.rb29
-rw-r--r--lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb33
-rw-r--r--lib/gitlab/ci/pipeline/expression/lexer.rb8
-rw-r--r--lib/gitlab/ci/pipeline/expression/statement.rb9
5 files changed, 83 insertions, 6 deletions
diff --git a/lib/gitlab/ci/pipeline/expression.rb b/lib/gitlab/ci/pipeline/expression.rb
new file mode 100644
index 00000000000..f57df7c5637
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/expression.rb
@@ -0,0 +1,10 @@
+module Gitlab
+ module Ci
+ module Pipeline
+ module Expression
+ ExpressionError = Class.new(StandardError)
+ RuntimeError = Class.new(ExpressionError)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb b/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb
new file mode 100644
index 00000000000..10957598f76
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/expression/lexeme/matches.rb
@@ -0,0 +1,29 @@
+module Gitlab
+ module Ci
+ module Pipeline
+ module Expression
+ module Lexeme
+ class Matches < Lexeme::Operator
+ PATTERN = /=~/.freeze
+
+ def initialize(left, right)
+ @left = left
+ @right = right
+ end
+
+ def evaluate(variables = {})
+ text = @left.evaluate(variables)
+ regexp = @right.evaluate(variables)
+
+ regexp.scan(text.to_s).any?
+ end
+
+ def self.build(_value, behind, ahead)
+ new(behind, ahead)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb b/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb
new file mode 100644
index 00000000000..9b239c29ea4
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb
@@ -0,0 +1,33 @@
+module Gitlab
+ module Ci
+ module Pipeline
+ module Expression
+ module Lexeme
+ require_dependency 're2'
+
+ class Pattern < Lexeme::Value
+ PATTERN = %r{^/.+/[ismU]*$}.freeze
+
+ def initialize(regexp)
+ @value = regexp
+
+ unless Gitlab::UntrustedRegexp.valid?(@value)
+ raise Lexer::SyntaxError, 'Invalid regular expression!'
+ end
+ end
+
+ def evaluate(variables = {})
+ Gitlab::UntrustedRegexp.fabricate(@value)
+ rescue RegexpError
+ raise Expression::RuntimeError, 'Invalid regular expression!'
+ end
+
+ def self.build(string)
+ new(string)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/expression/lexer.rb b/lib/gitlab/ci/pipeline/expression/lexer.rb
index e1c68b7c3c2..4cacb1e62c9 100644
--- a/lib/gitlab/ci/pipeline/expression/lexer.rb
+++ b/lib/gitlab/ci/pipeline/expression/lexer.rb
@@ -5,15 +5,17 @@ module Gitlab
class Lexer
include ::Gitlab::Utils::StrongMemoize
+ SyntaxError = Class.new(Expression::ExpressionError)
+
LEXEMES = [
Expression::Lexeme::Variable,
Expression::Lexeme::String,
+ Expression::Lexeme::Pattern,
Expression::Lexeme::Null,
- Expression::Lexeme::Equals
+ Expression::Lexeme::Equals,
+ Expression::Lexeme::Matches
].freeze
- SyntaxError = Class.new(Statement::StatementError)
-
MAX_TOKENS = 100
def initialize(statement, max_tokens: MAX_TOKENS)
diff --git a/lib/gitlab/ci/pipeline/expression/statement.rb b/lib/gitlab/ci/pipeline/expression/statement.rb
index 09a7c98464b..b36f1e0f865 100644
--- a/lib/gitlab/ci/pipeline/expression/statement.rb
+++ b/lib/gitlab/ci/pipeline/expression/statement.rb
@@ -3,15 +3,16 @@ module Gitlab
module Pipeline
module Expression
class Statement
- StatementError = Class.new(StandardError)
+ 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]
].freeze
def initialize(statement, variables = {})
@@ -35,11 +36,13 @@ module Gitlab
def truthful?
evaluate.present?
+ rescue Expression::ExpressionError
+ false
end
def valid?
parse_tree.is_a?(Lexeme::Base)
- rescue StatementError
+ rescue Expression::ExpressionError
false
end
end