BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
2c4aa504
Commit
2c4aa504
authored
Feb 21, 2018
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement pipeline expressions parser
parent
91a42a1a
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
94 additions
and
5 deletions
+94
-5
lexeme.rb
lib/gitlab/ci/pipeline/expression/lexeme.rb
+4
-0
lexer.rb
lib/gitlab/ci/pipeline/expression/lexer.rb
+2
-1
statement.rb
lib/gitlab/ci/pipeline/expression/statement.rb
+31
-2
string.rb
lib/gitlab/ci/pipeline/expression/string.rb
+1
-0
token.rb
lib/gitlab/ci/pipeline/expression/token.rb
+5
-0
variable.rb
lib/gitlab/ci/pipeline/expression/variable.rb
+6
-2
lexer_spec.rb
spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb
+9
-0
statement_spec.rb
spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
+36
-0
No files found.
lib/gitlab/ci/pipeline/expression/lexeme.rb
View file @
2c4aa504
...
...
@@ -7,6 +7,10 @@ module Gitlab
raise
NotImplementedError
end
def
self
.
build
(
token
)
raise
NotImplementedError
end
def
self
.
scan
(
scanner
)
if
scanner
.
scan
(
self
::
PATTERN
)
Expression
::
Token
.
new
(
scanner
.
matched
,
self
)
...
...
lib/gitlab/ci/pipeline/expression/lexer.rb
View file @
2c4aa504
...
...
@@ -5,7 +5,8 @@ module Gitlab
class
Lexer
LEXEMES
=
[
Expression
::
Variable
,
Expression
::
String
Expression
::
String
,
Expression
::
Equals
]
MAX_CYCLES
=
5
...
...
lib/gitlab/ci/pipeline/expression/statement.rb
View file @
2c4aa504
...
...
@@ -3,6 +3,8 @@ module Gitlab
module
Pipeline
module
Expression
class
Statement
ParserError
=
Class
.
new
(
StandardError
)
GRAMMAR
=
[
%w[variable equals string]
,
%w[variable equals variable]
,
...
...
@@ -12,14 +14,41 @@ module Gitlab
%w[variable]
]
def
initialize
(
pipeline
,
statement
)
def
initialize
(
statement
,
pipeline
)
@pipeline
=
pipeline
@
statement
=
statement
@
lexer
=
Expression
::
Lexer
.
new
(
statement
)
end
def
variables
end
def
tokens
@lexer
.
tokenize
end
def
lexemes
@lexemes
||=
tokens
.
map
(
&
:to_lexeme
)
end
##
# Our syntax is very simple, so we don't need yet to implement a
# recurisive parser, we can use the most simple approach to create
# a reverse descent parse tree "by hand".
#
def
parse_tree
raise
ParserError
if
lexemes
.
empty?
unless
GRAMMAR
.
find
{
|
syntax
|
syntax
==
lexemes
}
raise
ParserError
,
'Unknown pipeline expression!'
end
if
lexemes
.
many?
Expression
::
Equals
.
new
(
tokens
.
first
.
build
,
tokens
.
last
.
build
)
else
tokens
.
first
.
build
end
end
def
evaluate
end
end
...
...
lib/gitlab/ci/pipeline/expression/string.rb
View file @
2c4aa504
...
...
@@ -14,6 +14,7 @@ module Gitlab
end
def
self
.
build
(
string
)
new
(
string
.
match
(
PATTERN
)[
:string
])
end
end
end
...
...
lib/gitlab/ci/pipeline/expression/token.rb
View file @
2c4aa504
...
...
@@ -10,7 +10,12 @@ module Gitlab
@type
=
type
end
def
build
@type
.
build
(
@value
)
end
def
to_lexeme
type
.
name
.
demodulize
.
downcase
end
end
end
...
...
lib/gitlab/ci/pipeline/expression/variable.rb
View file @
2c4aa504
...
...
@@ -5,12 +5,16 @@ module Gitlab
class
Variable
<
Expression
::
Lexeme
PATTERN
=
/\$(?<name>\w+)/
.
freeze
def
initialize
(
valu
e
)
@
value
=
valu
e
def
initialize
(
nam
e
)
@
name
=
nam
e
end
def
evaluate
(
**
variables
)
end
def
self
.
build
(
string
)
new
(
string
.
match
(
PATTERN
)[
:name
])
end
end
end
end
...
...
spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb
View file @
2c4aa504
...
...
@@ -36,6 +36,15 @@ describe Gitlab::Ci::Pipeline::Expression::Lexer do
expect
(
tokens
.
third
.
value
).
to
eq
'"value"'
end
it
'tokenizes tokens and operators'
do
tokens
=
described_class
.
new
(
'$VARIABLE == "text"'
).
tokenize
expect
(
tokens
.
size
).
to
eq
3
expect
(
tokens
.
first
.
value
).
to
eq
'$VARIABLE'
expect
(
tokens
.
second
.
value
).
to
eq
'=='
expect
(
tokens
.
third
.
value
).
to
eq
'"text"'
end
it
'limits statement to 5 tokens'
do
lexer
=
described_class
.
new
(
"$V1 $V2 $V3 $V4 $V5 $V6"
)
...
...
spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
View file @
2c4aa504
require
'spec_helper'
describe
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Statement
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
)
}
let
(
:text
)
{
'$VAR "text"'
}
subject
do
described_class
.
new
(
text
,
pipeline
)
end
describe
'#tokens'
do
it
'returns raw tokens'
do
expect
(
subject
.
tokens
.
size
).
to
eq
2
end
end
describe
'#lexemes'
do
it
'returns an array of syntax lexemes'
do
expect
(
subject
.
lexemes
).
to
eq
%w[variable string]
end
end
describe
'#parse_tree'
do
context
'when expression grammar is incorrect'
do
it
'raises an error'
do
expect
{
subject
.
parse_tree
}
.
to
raise_error
described_class
::
ParserError
end
end
context
'when expression grammar is correct'
do
let
(
:text
)
{
'$VAR == "value"'
}
it
'returns a reverse descent parse tree when using operator'
do
expect
(
subject
.
parse_tree
)
.
to
be_a
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Equals
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment