travis-conditions 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
```
|