travis-conditions 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +65 -0
- data/Gemfile.lock +1 -1
- data/NOTES.md +107 -0
- data/README.md +261 -13
- data/bin/travis-conditions +34 -0
- data/lib/travis/conditions.rb +10 -16
- data/lib/travis/conditions/v0.rb +30 -0
- data/lib/travis/conditions/v0/data.rb +57 -0
- data/lib/travis/conditions/v0/eval.rb +70 -0
- data/lib/travis/conditions/v0/parser.rb +204 -0
- data/lib/travis/conditions/v1.rb +19 -0
- data/lib/travis/conditions/v1/boolean.rb +71 -0
- data/lib/travis/conditions/v1/data.rb +75 -0
- data/lib/travis/conditions/v1/eval.rb +114 -0
- data/lib/travis/conditions/v1/helper.rb +30 -0
- data/lib/travis/conditions/v1/parser.rb +214 -0
- data/lib/travis/conditions/version.rb +1 -1
- data/spec/conditions_spec.rb +15 -0
- data/spec/v0/conditions_spec.rb +15 -0
- data/spec/{data_spec.rb → v0/data_spec.rb} +6 -1
- data/spec/{eval_spec.rb → v0/eval_spec.rb} +1 -1
- data/spec/v0/fixtures/failures.txt +342 -0
- data/spec/v0/fixtures/passes.txt +1685 -0
- data/spec/{parser_spec.rb → v0/parser_spec.rb} +1 -1
- data/spec/v1/conditions_spec.rb +44 -0
- data/spec/v1/data_spec.rb +30 -0
- data/spec/v1/eval_spec.rb +349 -0
- data/spec/v1/fixtures/failures.txt +336 -0
- data/spec/v1/fixtures/passes.txt +1634 -0
- data/spec/v1/parser/boolean_spec.rb +215 -0
- data/spec/v1/parser/call_spec.rb +68 -0
- data/spec/v1/parser/comma_spec.rb +28 -0
- data/spec/v1/parser/cont_spec.rb +41 -0
- data/spec/v1/parser/eq_spec.rb +16 -0
- data/spec/v1/parser/in_list_spec.rb +60 -0
- data/spec/v1/parser/is_pred_spec.rb +24 -0
- data/spec/v1/parser/list_spec.rb +36 -0
- data/spec/v1/parser/operand_spec.rb +16 -0
- data/spec/v1/parser/parens_spec.rb +28 -0
- data/spec/v1/parser/quoted_spec.rb +24 -0
- data/spec/v1/parser/re_spec.rb +16 -0
- data/spec/v1/parser/regex_spec.rb +12 -0
- data/spec/v1/parser/space_spec.rb +40 -0
- data/spec/v1/parser/term_spec.rb +84 -0
- data/spec/v1/parser/val_spec.rb +24 -0
- data/spec/v1/parser/var_spec.rb +16 -0
- data/spec/v1/parser_spec.rb +486 -0
- data/spec/v1/user_spec.rb +223 -0
- metadata +48 -9
- data/lib/travis/conditions/data.rb +0 -45
- data/lib/travis/conditions/eval.rb +0 -68
- data/lib/travis/conditions/parser.rb +0 -202
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 511bf5af9e9ff4684b09b23bdfb45c19cf16974b
|
4
|
+
data.tar.gz: 18653ac8eb0886b3c797c25fe7af4eba1f13c6b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab283b0406a10b95be7d9ab0ef7c7fd052cd6db37944bd592493e4990983534370354e7de29091465c97f59d244e3dd6703fb133e8dae30ed07167a5c4438188
|
7
|
+
data.tar.gz: f98a63783c44fc3ddb29772d2e10290c9367fcb1b0bf63c71d31171c16f6156c3df92a92aacaee8ed1639b1d57bf1a5b6d96521683d6c21a76780f0ab5498763
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [Unreleased]
|
4
|
+
|
5
|
+
## v1.0.0-dev.1
|
6
|
+
|
7
|
+
Major parser rewrite, removing Parslet
|
8
|
+
|
9
|
+
### Added
|
10
|
+
- Variables `os`, `dist`, `group`, `sudo`, `language`, `commit_message`
|
11
|
+
- Boolean aliases `&&` (alias to `AND`), `||` (alias to `OR`), `!` (alias to `NOT`)
|
12
|
+
- Operator aliases `==` (alias to `=`), `~=` (alias to `=~`)
|
13
|
+
- Predicates `true`, `false`
|
14
|
+
- Line continuation using `\`
|
15
|
+
- Negated `IN` and `IS` operators:
|
16
|
+
```
|
17
|
+
NOT branch IN (master, dev) # this worked, and continues to work
|
18
|
+
branch NOT IN (master, dev) # this did not work, and now does
|
19
|
+
|
20
|
+
NOT env(foo) IS present # this worked, and continues to work
|
21
|
+
env(foo) IS NOT present # this did not work, and now does
|
22
|
+
env(foo) IS blank # btw this is the same
|
23
|
+
```
|
24
|
+
- Better boolean language parsing of:
|
25
|
+
```
|
26
|
+
# evaluate individual terms (no operator)
|
27
|
+
true
|
28
|
+
false
|
29
|
+
env(FOO)
|
30
|
+
|
31
|
+
# compare values
|
32
|
+
1 = 1
|
33
|
+
|
34
|
+
# compare function calls
|
35
|
+
env(FOO) = env(BAR)
|
36
|
+
|
37
|
+
# compare function calls to variables
|
38
|
+
env(FOO) = type
|
39
|
+
|
40
|
+
# nested function calls
|
41
|
+
env(env(FOO))
|
42
|
+
|
43
|
+
# function calls in lists
|
44
|
+
repo IN (env(ONE), env(OTHER))
|
45
|
+
|
46
|
+
# parenthesis
|
47
|
+
(tag =~ ^v) AND (branch = master)
|
48
|
+
```
|
49
|
+
|
50
|
+
### Changed
|
51
|
+
- All values continue to be treated as strings, except `true` and `false`
|
52
|
+
which are now treated like Ruby's types.
|
53
|
+
- Individual terms such as `true` or `env(FOO)` will now evaluate according
|
54
|
+
to Ruby's concept of truthiness: everything is true except for `false`
|
55
|
+
and absent values.
|
56
|
+
- Var names and unquoted strings starting with a dollar char `$` now raise
|
57
|
+
a parse error. Bash code is not available. Quoted strings still can start
|
58
|
+
with a dollar char.
|
59
|
+
|
60
|
+
## v0.2.0
|
61
|
+
### Changed
|
62
|
+
- Reraise Parselet::ParseFailed as Travis::Conditions::ParseError
|
63
|
+
|
64
|
+
## v0.1.0
|
65
|
+
Initial release
|
data/Gemfile.lock
CHANGED
data/NOTES.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
### New variables:
|
2
|
+
|
3
|
+
* `os`
|
4
|
+
* `dist`
|
5
|
+
* `group`
|
6
|
+
* `sudo`
|
7
|
+
* `language`
|
8
|
+
* `commit_message`
|
9
|
+
|
10
|
+
### New predicates:
|
11
|
+
|
12
|
+
* `true`
|
13
|
+
* `false`
|
14
|
+
|
15
|
+
It is now possible to use `fork IS true` instead of `fork = true`. These mean
|
16
|
+
the same, and there's no reason to not use `=`, but we have seen a lot of
|
17
|
+
people expect these to work.
|
18
|
+
|
19
|
+
### New operator aliases:
|
20
|
+
|
21
|
+
For the same reason we've added the following operator aliases:
|
22
|
+
|
23
|
+
* `==` (alias to `=`)
|
24
|
+
* `~=` (alias to `=~`)
|
25
|
+
* `&&` (alias to `AND`)
|
26
|
+
* `||` (alias to `OR`)
|
27
|
+
* `!` (alias to `NOT`)
|
28
|
+
|
29
|
+
### Negated `IN` and `IS` operators:
|
30
|
+
|
31
|
+
The operators `IN` and `IS` could not be negated the way users expected.
|
32
|
+
We allowed the following:
|
33
|
+
|
34
|
+
```
|
35
|
+
NOT branch IN (master, dev) # worked, and continues to work
|
36
|
+
branch NOT IN (master, dev) # did not work, and now does
|
37
|
+
|
38
|
+
NOT env(foo) IS present # worked, and continues to work
|
39
|
+
env(foo) IS NOT present # did not work, and now does
|
40
|
+
env(foo) IS blank # (btw this is the same)
|
41
|
+
```
|
42
|
+
|
43
|
+
### Line continuation (multiline conditions):
|
44
|
+
|
45
|
+
We were surprised to see users to expect line continuation using `\` to work,
|
46
|
+
as it does, for example, in Ruby or Python. We liked the idea, so we allowed
|
47
|
+
this:
|
48
|
+
|
49
|
+
```
|
50
|
+
if: env(PRIOR_VERSION) IS present AND \
|
51
|
+
env(PRIOR_VERSION) != env(RELEASE_VERSION) AND \
|
52
|
+
branch = master AND \
|
53
|
+
type = push
|
54
|
+
```
|
55
|
+
|
56
|
+
Using YAML multiline strings:
|
57
|
+
|
58
|
+
```
|
59
|
+
if: |
|
60
|
+
env(PRIOR_VERSION) IS present AND \
|
61
|
+
env(PRIOR_VERSION) != env(RELEASE_VERSION) AND \
|
62
|
+
branch = master AND \
|
63
|
+
type = push
|
64
|
+
```
|
65
|
+
|
66
|
+
### Proper boolean language parsing:
|
67
|
+
|
68
|
+
Previously it was not possible to:
|
69
|
+
|
70
|
+
* evaluate individual terms (such as `true`)
|
71
|
+
* compare, say, a value (string) to another, one environment variable (function call) to another, or compare function calls to variables (such as `type` or `branch`).
|
72
|
+
* nest function calls, or include things other than strings in lists.
|
73
|
+
* enclose statements in parenthesis the way one would expect in some places (even though not documented).
|
74
|
+
|
75
|
+
The following statements now parse and evaluate as expected:
|
76
|
+
|
77
|
+
```
|
78
|
+
# individual terms
|
79
|
+
true
|
80
|
+
false
|
81
|
+
|
82
|
+
# compare values
|
83
|
+
1 = 1
|
84
|
+
true != false
|
85
|
+
|
86
|
+
# compare function calls
|
87
|
+
env(FOO) = env(BAR)
|
88
|
+
|
89
|
+
# compare function calls to variables
|
90
|
+
env(FOO) = type
|
91
|
+
|
92
|
+
# nested function calls
|
93
|
+
env(env(FOO))
|
94
|
+
|
95
|
+
# function calls in lists
|
96
|
+
repo IN (env(ONE), env(OTHER))
|
97
|
+
|
98
|
+
# parenthesis
|
99
|
+
(tag =~ ^v) AND (branch = master)
|
100
|
+
```
|
101
|
+
|
102
|
+
### No bash code, please
|
103
|
+
|
104
|
+
Variable names and unquoted strings starting with a dollar char `$` now raise a
|
105
|
+
parse error. Bash code is not available, and these expressions will never evaluate
|
106
|
+
as the user expects, so it is better to raise an error instead. Quoted strings
|
107
|
+
still can start with a dollar char.
|
data/README.md
CHANGED
@@ -1,33 +1,233 @@
|
|
1
|
-
# Boolean language for conditional builds, stages, jobs
|
1
|
+
# Boolean language for conditional builds, stages, jobs
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
str = 'branch IN (foo, bar) AND env(baz) =~ ^baz- OR tag IS present'
|
7
|
+
data = { branch: 'foo', env: { baz: 'baz-1' }, tag: 'v.1.0.0' }
|
8
|
+
Travis::Conditions.parse(str, data)
|
9
|
+
# => true
|
10
|
+
```
|
11
|
+
|
12
|
+
## EBNF
|
13
|
+
|
14
|
+
See [this file](https://github.com/travis-ci/travis-conditions/blob/master/lib/travis/conditions/v1/parser.rb#L6-L47) for the EBNF.
|
15
|
+
|
16
|
+
## CLI
|
17
|
+
|
18
|
+
With the gem installed you can use the command `travis-conditions` in order to
|
19
|
+
test your conditions locally. For example:
|
20
|
+
|
21
|
+
```
|
22
|
+
$ travis-conditions "branch = foo" --data '{"branch": "foo"}'
|
23
|
+
true
|
24
|
+
|
25
|
+
$ echo '{"branch": "foo"}' | travis-conditions "branch = foo"
|
26
|
+
true
|
27
|
+
```
|
28
|
+
|
29
|
+
The given `data` hash can include known attributes (such as branch, tag, repo)
|
30
|
+
and an `env` key that can either hold a hash, or an array of strings:
|
31
|
+
|
32
|
+
```
|
33
|
+
$ travis-conditions "env(foo) = bar" --data '{"env": {"foo": "bar"}}'
|
34
|
+
true
|
35
|
+
$ travis-conditions "env(foo) = bar" --data '{"env": ["foo=bar"]}'
|
36
|
+
true
|
37
|
+
```
|
38
|
+
|
39
|
+
## Conditions
|
40
|
+
|
41
|
+
Conditions can be used to filter out, and reject builds, stages, and jobs by
|
42
|
+
specifying conditions in your build configuration (your `.travis.yml` file).
|
43
|
+
See [Conditional Builds, Stages, and Jobs](/user/conditional-builds-stages-jobs)
|
44
|
+
for details.
|
45
|
+
|
46
|
+
### Examples
|
47
|
+
|
48
|
+
```
|
49
|
+
# require the branch name to be master (note for PRs this is the base branch name)
|
50
|
+
branch = master
|
51
|
+
|
52
|
+
# require the tag name to match a regular expression (enclose in slashes for
|
53
|
+
# more complicated expressions)
|
54
|
+
tag =~ ^v1
|
55
|
+
tag =~ /^(v1|v2)/
|
56
|
+
|
57
|
+
# require the event type to be either `push` or `pull_request`
|
58
|
+
type IN (push, pull_request)
|
59
|
+
|
60
|
+
# require the branch name to not be one of several names
|
61
|
+
branch NOT IN (master, dev)
|
62
|
+
|
63
|
+
# require the sender login name to match a given name (use quotes for strings
|
64
|
+
# that contain spaces or special characters)
|
65
|
+
sender == my_account
|
66
|
+
sender != "deploy bot"
|
67
|
+
|
68
|
+
# exclude forks
|
69
|
+
fork == false
|
70
|
+
|
71
|
+
# match the commit message
|
72
|
+
commit_message !~ /no-deploy/
|
73
|
+
|
74
|
+
# match the os
|
75
|
+
os == linux
|
76
|
+
```
|
77
|
+
|
78
|
+
### Integration
|
79
|
+
|
80
|
+
Conditions are being parsed using [this library](https://github.com/travis-ci/travis-conditions)
|
81
|
+
by the component that accepts your build request, and generates your build,
|
82
|
+
stages, and jobs.
|
83
|
+
|
84
|
+
The following known attributes are available:
|
85
|
+
|
86
|
+
* `type` (the current event type, known event types are: `push`, `pull_request`, `api`, `cron`)
|
87
|
+
* `repo` (the current repository slug `owner_name/name`)
|
88
|
+
* `branch` (the current branch name; for pull requests: the base branch name)
|
89
|
+
* `tag` (the current tag name)
|
90
|
+
* `commit_message` (the current commit message)
|
91
|
+
* `sender` (the event sender's login name)
|
92
|
+
* `fork` (`true` or `false` depending if the repository is a fork)
|
93
|
+
* `head_repo` (for pull requests: the head repository slug `owner_name/name`)
|
94
|
+
* `head_branch` (for pull requests: the head repository branch name)
|
95
|
+
* `os` (the operating system)
|
96
|
+
* `language` (the build language)
|
97
|
+
* `sudo` (sudo access)
|
98
|
+
* `dist` (the distribution)
|
99
|
+
* `group` (the image group)
|
100
|
+
|
101
|
+
Also, environment variables from your build configuration (`.travis.yml`) and
|
102
|
+
repository settings are available, and can be matched using `env(FOO)`, see
|
103
|
+
below.
|
104
|
+
|
105
|
+
Note that this means conditions do not have access to the build environment,
|
106
|
+
and they are *not* evaluted in Bash. Bash variables or subprocesses can *not*
|
107
|
+
be evaluated.
|
108
|
+
|
109
|
+
Variable names and unquoted strings starting with a dollar char `$` raise a
|
110
|
+
parse error, causing the build request to be rejected. Quoted strings still can
|
111
|
+
start with a dollar char, so if you definitely need a string to start with a
|
112
|
+
dollar char you can enclose it in quotes.
|
113
|
+
|
114
|
+
### Specification
|
115
|
+
|
116
|
+
The following expressions are parsed and evaluated as expected:
|
117
|
+
|
118
|
+
```
|
119
|
+
# individual terms
|
120
|
+
true
|
121
|
+
false
|
122
|
+
|
123
|
+
# compare values
|
124
|
+
1 = 1
|
125
|
+
true != false
|
126
|
+
|
127
|
+
# compare function calls
|
128
|
+
env(FOO) = env(BAR)
|
129
|
+
|
130
|
+
# compare function calls to attributes
|
131
|
+
env(FOO) = type
|
132
|
+
|
133
|
+
# nested function calls
|
134
|
+
env(env(FOO))
|
135
|
+
|
136
|
+
# function calls in lists
|
137
|
+
repo IN (env(ONE), env(OTHER))
|
138
|
+
|
139
|
+
# parenthesis
|
140
|
+
(tag =~ ^v) AND (branch = master)
|
141
|
+
```
|
142
|
+
|
143
|
+
All keywords (such as `AND`, `OR`, `NOT`, `IN`, `IS`, attribute and functions names) are case-insensitive.
|
144
|
+
|
145
|
+
The only functions currently is:
|
146
|
+
|
147
|
+
```
|
148
|
+
# (the value of the environment variable `FOO`)
|
149
|
+
env(FOO)
|
150
|
+
```
|
151
|
+
|
152
|
+
The function `env` currently supports environment variables that are given in
|
153
|
+
your build configuration (e.g. on `env` or `env.global`), and environment
|
154
|
+
variables specified in your repository settings. Note that there is no
|
155
|
+
function `env.global` or similar. Instead all environment variables are
|
156
|
+
available through `env`.
|
157
|
+
|
158
|
+
#### Values
|
159
|
+
|
160
|
+
Values are strings that are given without quotes, not containing any whitespace or special characters, or single or double quoted strings:
|
2
161
|
|
3
162
|
```
|
4
|
-
|
163
|
+
"a word"
|
164
|
+
'a word'
|
165
|
+
a_word
|
5
166
|
```
|
6
167
|
|
7
|
-
|
168
|
+
#### Equality and inequality
|
8
169
|
|
9
|
-
|
170
|
+
This matches a string literally:
|
10
171
|
|
11
172
|
```
|
12
173
|
branch = master
|
174
|
+
sender != "my bot"
|
13
175
|
env(foo) = bar
|
176
|
+
"bar" = env("foo")
|
14
177
|
```
|
15
178
|
|
16
|
-
####
|
179
|
+
#### Regular expressions
|
180
|
+
|
181
|
+
This matches a string using a regular expression:
|
17
182
|
|
18
183
|
```
|
184
|
+
# for simple expressions, not ending in a closing parenthesis:
|
19
185
|
branch =~ ^master$
|
20
186
|
env(foo) =~ ^bar$
|
187
|
+
|
188
|
+
# if an expression needs to include whitespace, or end in a parenthesis wrap it with slashes:
|
189
|
+
branch =~ /(master|foo)/
|
21
190
|
```
|
22
191
|
|
23
|
-
|
192
|
+
Usually parenthesis are not required (e.g. the above list of alternatives could also be written as just `master|foo`). If you do need to end a regular expression with a parenthesis, or if it contains whitespace, then the whole expression needs to be wrapped in `/` slashes.
|
193
|
+
|
194
|
+
#### Lists
|
195
|
+
|
196
|
+
This matches against a list (array) of values:
|
24
197
|
|
25
198
|
```
|
26
199
|
branch IN (master, dev)
|
27
200
|
env(foo) IN (bar, baz)
|
28
201
|
```
|
29
202
|
|
30
|
-
|
203
|
+
Note that commas are required to separate values.
|
204
|
+
|
205
|
+
Values that include whitespace or special characters should be quoted:
|
206
|
+
|
207
|
+
```
|
208
|
+
env(foo) IN ("bar baz", "buz bum")
|
209
|
+
```
|
210
|
+
|
211
|
+
The operator `IN` can be negated as follows:
|
212
|
+
|
213
|
+
```
|
214
|
+
# these are the same
|
215
|
+
NOT branch IN (master, dev)
|
216
|
+
branch NOT IN (master, dev)
|
217
|
+
```
|
218
|
+
|
219
|
+
#### Predicates
|
220
|
+
|
221
|
+
Known predicates are:
|
222
|
+
|
223
|
+
```
|
224
|
+
present
|
225
|
+
blank
|
226
|
+
true
|
227
|
+
false
|
228
|
+
```
|
229
|
+
|
230
|
+
This requires a value to be present or missing:
|
31
231
|
|
32
232
|
```
|
33
233
|
branch IS present
|
@@ -36,11 +236,59 @@ env(foo) IS present
|
|
36
236
|
env(foo) IS blank
|
37
237
|
```
|
38
238
|
|
39
|
-
|
239
|
+
The operator `IS` can be negated as follows:
|
40
240
|
|
41
|
-
```
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
241
|
+
```
|
242
|
+
# these are all the same
|
243
|
+
env(foo) IS NOT present
|
244
|
+
NOT env(foo) IS present
|
245
|
+
env(foo) IS blank
|
246
|
+
```
|
247
|
+
|
248
|
+
Note that the operator `IS` is intended to work with the well known predicates `present` and `blank`. It is not the same as `=`, and expressions like the following do *not* work:
|
249
|
+
|
250
|
+
```
|
251
|
+
# this does not work
|
252
|
+
branch IS "master"
|
253
|
+
|
254
|
+
# instead use =
|
255
|
+
branch = "master"
|
256
|
+
```
|
257
|
+
|
258
|
+
However, `IS` can also be used to match against the boolean values `true` and `false` (this has been included after we found many users to expect this to work):
|
259
|
+
|
260
|
+
```
|
261
|
+
branch IS true
|
262
|
+
branch = true # this is the same
|
263
|
+
```
|
264
|
+
|
265
|
+
#### Aliases
|
266
|
+
|
267
|
+
The following aliases are in place:
|
268
|
+
|
269
|
+
* `!` is an alias to `NOT`
|
270
|
+
* `&&` is an alias to `AND`
|
271
|
+
* `||` is an alias to `OR`
|
272
|
+
* `==` is an alias to `=`
|
273
|
+
* `~=` is an alias to `=~`
|
274
|
+
|
275
|
+
#### Line continuation (multiline conditions):
|
276
|
+
|
277
|
+
We were surprised to see users to expect line continuation using `\` to work, as it does, for example, in Ruby or Python. We liked the idea, so we allowed the following:
|
278
|
+
|
279
|
+
```
|
280
|
+
if: env(PRIOR_VERSION) IS present AND \
|
281
|
+
env(PRIOR_VERSION) != env(RELEASE_VERSION) AND \
|
282
|
+
branch = master AND \
|
283
|
+
type = push
|
284
|
+
```
|
285
|
+
|
286
|
+
Using YAML multiline strings:
|
287
|
+
|
288
|
+
```
|
289
|
+
if: |
|
290
|
+
env(PRIOR_VERSION) IS present AND \
|
291
|
+
env(PRIOR_VERSION) != env(RELEASE_VERSION) AND \
|
292
|
+
branch = master AND \
|
293
|
+
type = push
|
46
294
|
```
|