Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
6fe4d2c6
Commit
6fe4d2c6
authored
Feb 22, 2018
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Build a recursive parser for pipeline expressions
parent
867a4f68
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
61 additions
and
18 deletions
+61
-18
lib/gitlab/ci/pipeline/expression/equals.rb
lib/gitlab/ci/pipeline/expression/equals.rb
+5
-0
lib/gitlab/ci/pipeline/expression/lexeme.rb
lib/gitlab/ci/pipeline/expression/lexeme.rb
+4
-0
lib/gitlab/ci/pipeline/expression/null.rb
lib/gitlab/ci/pipeline/expression/null.rb
+1
-0
lib/gitlab/ci/pipeline/expression/parser.rb
lib/gitlab/ci/pipeline/expression/parser.rb
+21
-10
lib/gitlab/ci/pipeline/expression/statement.rb
lib/gitlab/ci/pipeline/expression/statement.rb
+1
-2
lib/gitlab/ci/pipeline/expression/string.rb
lib/gitlab/ci/pipeline/expression/string.rb
+1
-0
lib/gitlab/ci/pipeline/expression/token.rb
lib/gitlab/ci/pipeline/expression/token.rb
+10
-6
lib/gitlab/ci/pipeline/expression/variable.rb
lib/gitlab/ci/pipeline/expression/variable.rb
+1
-0
spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
+17
-0
No files found.
lib/gitlab/ci/pipeline/expression/equals.rb
View file @
6fe4d2c6
...
...
@@ -4,6 +4,7 @@ module Gitlab
module
Expression
class
Equals
<
Expression
::
Lexeme
PATTERN
=
/==/
.
freeze
TYPE
=
:operator
def
initialize
(
left
,
right
)
@left
=
left
...
...
@@ -13,6 +14,10 @@ module Gitlab
def
evaluate
(
**
variables
)
@left
.
evaluate
(
variables
)
==
@right
.
evaluate
(
variables
)
end
def
self
.
build
(
value
,
behind
,
ahead
)
new
(
behind
,
ahead
)
end
end
end
end
...
...
lib/gitlab/ci/pipeline/expression/lexeme.rb
View file @
6fe4d2c6
...
...
@@ -11,6 +11,10 @@ module Gitlab
raise
NotImplementedError
end
def
self
.
type
self
::
TYPE
end
def
self
.
scan
(
scanner
)
if
scanner
.
scan
(
self
::
PATTERN
)
Expression
::
Token
.
new
(
scanner
.
matched
,
self
)
...
...
lib/gitlab/ci/pipeline/expression/null.rb
View file @
6fe4d2c6
...
...
@@ -4,6 +4,7 @@ module Gitlab
module
Expression
class
Null
<
Expression
::
Lexeme
PATTERN
=
/null/
.
freeze
TYPE
=
:value
def
initialize
(
value
)
@value
=
value
...
...
lib/gitlab/ci/pipeline/expression/parser.rb
View file @
6fe4d2c6
...
...
@@ -3,20 +3,31 @@ module Gitlab
module
Pipeline
module
Expression
class
Parser
def
initialize
(
syntax
)
if
syntax
.
is_a?
(
Expression
::
Lexer
)
@tokens
=
syntax
.
tokens
else
@tokens
=
syntax
.
to_a
end
def
initialize
(
tokens
)
# raise ArgumentError unless tokens.enumerator?
@tokens
=
tokens
@nodes
=
[]
end
def
tree
if
@tokens
.
many?
Expression
::
Equals
.
new
(
@tokens
.
first
.
build
,
@tokens
.
last
.
build
)
else
@tokens
.
first
.
build
while
token
=
@tokens
.
next
case
token
.
type
when
:operator
lookbehind
=
@nodes
.
last
lookahead
=
Parser
.
new
(
@tokens
).
tree
token
.
build
(
lookbehind
,
lookahead
).
tap
do
|
node
|
@nodes
.
push
(
node
)
end
when
:value
token
.
build
.
tap
do
|
leaf
|
@nodes
.
push
(
leaf
)
end
end
end
rescue
StopIteration
@nodes
.
last
end
end
end
...
...
lib/gitlab/ci/pipeline/expression/statement.rb
View file @
6fe4d2c6
...
...
@@ -15,7 +15,6 @@ module Gitlab
].
freeze
def
initialize
(
statement
,
pipeline
)
@pipeline
=
pipeline
@lexer
=
Expression
::
Lexer
.
new
(
statement
)
@variables
=
pipeline
.
variables
.
map
do
|
variable
|
...
...
@@ -30,7 +29,7 @@ module Gitlab
raise
StatementError
,
'Unknown pipeline expression!'
end
Expression
::
Parser
.
new
(
@lexer
).
tree
Expression
::
Parser
.
new
(
@lexer
.
tokens
.
to_enum
).
tree
end
def
evaluate
...
...
lib/gitlab/ci/pipeline/expression/string.rb
View file @
6fe4d2c6
...
...
@@ -4,6 +4,7 @@ module Gitlab
module
Expression
class
String
<
Expression
::
Lexeme
PATTERN
=
/"(?<string>.+?)"/
.
freeze
TYPE
=
:value
def
initialize
(
value
)
@value
=
value
...
...
lib/gitlab/ci/pipeline/expression/token.rb
View file @
6fe4d2c6
...
...
@@ -3,19 +3,23 @@ module Gitlab
module
Pipeline
module
Expression
class
Token
attr_reader
:value
,
:
typ
e
attr_reader
:value
,
:
lexem
e
def
initialize
(
value
,
typ
e
)
def
initialize
(
value
,
lexem
e
)
@value
=
value
@
type
=
typ
e
@
lexeme
=
lexem
e
end
def
build
@type
.
build
(
@value
)
def
build
(
*
args
)
@lexeme
.
build
(
@value
,
*
args
)
end
def
type
@lexeme
.
type
end
def
to_lexeme
typ
e
.
name
.
demodulize
.
downcase
@lexem
e
.
name
.
demodulize
.
downcase
end
end
end
...
...
lib/gitlab/ci/pipeline/expression/variable.rb
View file @
6fe4d2c6
...
...
@@ -4,6 +4,7 @@ module Gitlab
module
Expression
class
Variable
<
Expression
::
Lexeme
PATTERN
=
/\$(?<name>\w+)/
.
freeze
TYPE
=
:value
def
initialize
(
name
)
@name
=
name
...
...
spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
View file @
6fe4d2c6
...
...
@@ -2,5 +2,22 @@ require 'spec_helper'
describe
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Parser
do
describe
'#tree'
do
context
'when using an operator'
do
it
'returns a reverse descent parse tree'
do
expect
(
described_class
.
new
(
tokens
(
'$VAR == "123"'
)).
tree
)
.
to
be_a
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Equals
end
end
context
'when using a single token'
do
it
'returns a single token instance'
do
expect
(
described_class
.
new
(
tokens
(
'$VAR'
)).
tree
)
.
to
be_a
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Variable
end
end
end
def
tokens
(
statement
)
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Lexer
.
new
(
statement
).
tokens
.
to_enum
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