yaml_bot 0.2.0 → 0.3.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/.gitignore +1 -0
- data/.rubocop.yml +14 -0
- data/.ruby-version +1 -1
- data/.travis.yml +1 -2
- data/CHANGELOG.md +6 -0
- data/README.md +12 -9
- data/RULES_DEFINITION.md +259 -0
- data/bin/yamlbot +4 -0
- data/lib/yaml_bot/cli_bot.rb +35 -62
- data/lib/yaml_bot/key_bot.rb +117 -0
- data/lib/yaml_bot/logging_bot.rb +4 -3
- data/lib/yaml_bot/parse_bot.rb +22 -0
- data/lib/yaml_bot/resources/valid_rules_keys.yml +8 -0
- data/lib/yaml_bot/resources/valid_types.yml +6 -0
- data/lib/yaml_bot/rules_bot.rb +42 -87
- data/lib/yaml_bot/validation_bot.rb +11 -99
- data/lib/yaml_bot/version.rb +1 -1
- data/new_spec.yml +36 -0
- data/yaml_bot.gemspec +1 -3
- metadata +10 -20
- data/lib/yaml_bot/resources/valid_accepted_types.yml +0 -8
- data/lib/yaml_bot/resources/valid_key_values.yml +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8169550325022501a33fe951c691a0814d753666
|
|
4
|
+
data.tar.gz: b28c4b536c226f143f5b8d50abca65e76b0cd1aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8bf5698a4b75356806147d63b08535b38bd70a1d2753157a5030b7351c75fff3fd0321cede33d222013091d7fd81e5e94271b03fae53811aed99556724f98ed4
|
|
7
|
+
data.tar.gz: fbabbe2ba0d1c910e61ca5f735027b013be3e7ef2fe5bf7b12572e8742ccdbbea6b84e24cf01dad1b4f73143e70956322f13a54f5794bc26918807e27d727345
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -4,7 +4,21 @@ Documentation:
|
|
|
4
4
|
# Metrics/MethodLength:
|
|
5
5
|
# Max: 15
|
|
6
6
|
|
|
7
|
+
Metrics/LineLength:
|
|
8
|
+
# This will disable the rule completely, regardless what other options you put
|
|
9
|
+
Enabled: false
|
|
10
|
+
|
|
11
|
+
Style/FrozenStringLiteralComment:
|
|
12
|
+
# Strings in Ruby 2.3 >= are frozen by default
|
|
13
|
+
Enabled: false
|
|
14
|
+
|
|
7
15
|
Metrics/ClassLength:
|
|
8
16
|
Enabled: false
|
|
9
17
|
CountComments: false # count full line comments?
|
|
10
18
|
Max: 100
|
|
19
|
+
|
|
20
|
+
Metrics/AbcSize:
|
|
21
|
+
Max: 25
|
|
22
|
+
|
|
23
|
+
Metrics/CyclomaticComplexity:
|
|
24
|
+
Max: 7
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.4.1
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
# v0.3.0 - 2017-06-06
|
|
8
|
+
### Changed
|
|
9
|
+
- Redefined the YamlBot rules specification according to [issue 22](https://github.com/skippyPeanutButter/yaml_bot/issues/22).
|
|
10
|
+
- Reimplemented the YamlBot API to handle new rules specification.
|
|
11
|
+
- Changed required ruby version to be >= 2.4.
|
|
12
|
+
|
|
7
13
|
# v0.2.0 - 2017-01-14
|
|
8
14
|
### Added
|
|
9
15
|
- `values` key has been added to the [Yamlbot Specification][values].
|
data/README.md
CHANGED
|
@@ -11,13 +11,18 @@ YamlBot is not a Yaml linter, it is a Yaml format validator.
|
|
|
11
11
|
|
|
12
12
|
Mistakes can often be made when working with yaml-based configuration. Systems
|
|
13
13
|
such as travis-ci, rubocop, and other tools that utilize yaml files to govern
|
|
14
|
-
how they work often present users with a multitude of keys that can
|
|
15
|
-
many possible values. `yamlbot` allows
|
|
16
|
-
yaml-based system follows and then validate any yaml file against those
|
|
14
|
+
how they work often present users with a multitude of keys and options that can
|
|
15
|
+
take on many possible values. `yamlbot` allows users to feed it a set of rules
|
|
16
|
+
that a yaml-based system follows and then validate any yaml file against those
|
|
17
|
+
rules.
|
|
17
18
|
|
|
18
|
-
If
|
|
19
|
-
|
|
20
|
-
them use `yamlbot` to validate their
|
|
19
|
+
If a tool works off of a yaml-based configuration then a rules file can be
|
|
20
|
+
crafted for validating the configuration is correct. Create a rules file, share
|
|
21
|
+
it with others, and have them use `yamlbot` to validate their configuration
|
|
22
|
+
against the specified rules.
|
|
23
|
+
|
|
24
|
+
See the [RULES FILE](RULES_DEFINITION.md) specification for details on creating
|
|
25
|
+
a `.yamlbot.yml` rules file.
|
|
21
26
|
|
|
22
27
|
### Installation
|
|
23
28
|
|
|
@@ -38,7 +43,7 @@ Or install it yourself as:
|
|
|
38
43
|
### Usage
|
|
39
44
|
|
|
40
45
|
Create a `.yamlbot.yml` file with a set of rules that you want to validate yaml
|
|
41
|
-
files against [yamlbot file specification]
|
|
46
|
+
files against [yamlbot file specification](RULES_DEFINITION.md).
|
|
42
47
|
|
|
43
48
|
Usage assuming the existence `.yamlbot.yml` in the current directory:
|
|
44
49
|
|
|
@@ -84,5 +89,3 @@ to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
|
84
89
|
|
|
85
90
|
The gem is available as open source under the terms of the [MIT
|
|
86
91
|
License](http://opensource.org/licenses/MIT).
|
|
87
|
-
|
|
88
|
-
[yamlbot-spec]: https://github.com/skippyPeanutButter/yaml_bot/wiki/Rules-file-specification
|
data/RULES_DEFINITION.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# YAMLBOT RULES DEFINITION
|
|
2
|
+
|
|
3
|
+
This document details YamlBot rules specification. Using the details discussed
|
|
4
|
+
below, users can craft their own `.yamlbot.yml` rules for validating yaml-based
|
|
5
|
+
files according to a specification. Examples of yaml-based tools that can be
|
|
6
|
+
validated include [travis-ci](https://travis-ci.org/),
|
|
7
|
+
[rubocop](https://github.com/bbatsov/rubocop), and
|
|
8
|
+
[jervis](https://github.com/samrocketman/jervis).
|
|
9
|
+
|
|
10
|
+
The general layout of a `.yamlbot.yml` file is as follows:
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
defaults:
|
|
14
|
+
'default values for rules'
|
|
15
|
+
rules:
|
|
16
|
+
- key: 'yaml.address'
|
|
17
|
+
required_key: true|false
|
|
18
|
+
and_requires: ['list of yaml addresses']
|
|
19
|
+
or_requires: ['list of yaml addresses']
|
|
20
|
+
value_whitelist: ['list of values']
|
|
21
|
+
value_blacklist: ['list of values']
|
|
22
|
+
types: ['list of types']
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Key definitions
|
|
26
|
+
|
|
27
|
+
- `defaults` - This section of the rules file is where default values can be
|
|
28
|
+
specified for the keys `required_key`, `and_requires`,
|
|
29
|
+
`or_requires`, `value_whitelist`, `value_blacklist`, and 'types'.
|
|
30
|
+
This key is optional if a user does not wish to specify defaults.
|
|
31
|
+
|
|
32
|
+
Note: Specific values defined under individual keys will override
|
|
33
|
+
any default values.
|
|
34
|
+
|
|
35
|
+
- `rules` - This section is where the rules for yaml file validation are
|
|
36
|
+
specified. This key is required for `YamlBot` to successfully parse
|
|
37
|
+
the rules file.
|
|
38
|
+
|
|
39
|
+
- `key` - This key is *required*. A rules file must be made up of a
|
|
40
|
+
list of keys that need to be validated. `key` requires a string value,
|
|
41
|
+
which denotes the name of the key being validated. If a user desires
|
|
42
|
+
to validate a nested key, then `.` delimiter must be used to denote
|
|
43
|
+
the parent-child relationship of nested keys.
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
Sample .yamlbot.yml
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
rules:
|
|
50
|
+
- key: person.age
|
|
51
|
+
required_key: true
|
|
52
|
+
types: [number]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Sample yaml file being validated
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
person:
|
|
59
|
+
age: 43
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Nested keys can be specified up to `nth` level of nesting using the
|
|
63
|
+
`.` delimiter.
|
|
64
|
+
|
|
65
|
+
- `required_key` - This key is *required* only if it is not defined in
|
|
66
|
+
the `defaults` section. Every key in the list of key being
|
|
67
|
+
validated must be specified as required or not.
|
|
68
|
+
|
|
69
|
+
- `and_requires` - This key is optional. It determines additional keys that
|
|
70
|
+
*must* be part of the yaml file being validated if a
|
|
71
|
+
particular key is defined.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
```yaml
|
|
75
|
+
rules:
|
|
76
|
+
- key: keya
|
|
77
|
+
required_key: false
|
|
78
|
+
and_requires: [keyb]
|
|
79
|
+
```
|
|
80
|
+
The above rules specifies that if `keya` is defined in the
|
|
81
|
+
yaml file being validated, then `keyb` must also be defined
|
|
82
|
+
for the yaml file to be successfully validated.
|
|
83
|
+
|
|
84
|
+
- `or_requires` - This key is optional, if a particular key is a required_key
|
|
85
|
+
and is missing, then a yaml file may still be valid if any of
|
|
86
|
+
the keys in the `or_requires` list exists and is properly
|
|
87
|
+
defined.
|
|
88
|
+
|
|
89
|
+
Example:
|
|
90
|
+
```yaml
|
|
91
|
+
rules:
|
|
92
|
+
- key: keya
|
|
93
|
+
required_key: true
|
|
94
|
+
and_requires: [keyb]
|
|
95
|
+
```
|
|
96
|
+
The above rules specifies that if `keya` is required in the
|
|
97
|
+
yaml file being validated and is missing, then the yaml file
|
|
98
|
+
will still be marked as valid if `keyb` exists in the yaml
|
|
99
|
+
file with a valid value.
|
|
100
|
+
|
|
101
|
+
- `value_whitelist` - This key is optional. It defines a list of possible values
|
|
102
|
+
that a key may take on. If this list is defined and a key
|
|
103
|
+
does not have a value specified within this list then that
|
|
104
|
+
key will fail validation.
|
|
105
|
+
|
|
106
|
+
- `value_blacklist` - This key is optional. It defines a list of values that a
|
|
107
|
+
key may *not* take on. If this list is defined and a key
|
|
108
|
+
has a value defined in this list, then that key will fail
|
|
109
|
+
validation.
|
|
110
|
+
|
|
111
|
+
- `types` - This key is optional. It defines a list of the possible data types
|
|
112
|
+
that a key's value may be.
|
|
113
|
+
Possible types include 'list', 'object', 'string', 'boolean',
|
|
114
|
+
'number'.
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
```yaml
|
|
118
|
+
- key: age
|
|
119
|
+
required_key: true
|
|
120
|
+
types: [number]
|
|
121
|
+
- key: ethnicity
|
|
122
|
+
required_key: false
|
|
123
|
+
types: [string, list]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Types are denoted in yaml as follows.
|
|
127
|
+
|
|
128
|
+
*List*
|
|
129
|
+
key `groceries` takes an array of items as its value
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
groceries:
|
|
133
|
+
- apples
|
|
134
|
+
- bananas
|
|
135
|
+
- carrots
|
|
136
|
+
or
|
|
137
|
+
|
|
138
|
+
groceries: [apples, bananas, carrots]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
*Object*
|
|
142
|
+
key `car` takes a map/hash of keys with their own values
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
car:
|
|
146
|
+
wheels: 4
|
|
147
|
+
transmission: automatic
|
|
148
|
+
color: blue
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
*String*
|
|
152
|
+
key 'name' takes a string literal as its value
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
name: Louis
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
*Boolean*
|
|
159
|
+
key `can_fly` takes a boolean as its value
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
can_fly: false
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
*Number*
|
|
166
|
+
key `age` takes an integer number as its value
|
|
167
|
+
key `price` takes a floating point number as its value
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
age: 2
|
|
171
|
+
price: 3.99
|
|
172
|
+
```
|
|
173
|
+
### Examples
|
|
174
|
+
|
|
175
|
+
The examples that follow specify several sample yaml files and their accompanying
|
|
176
|
+
`.yamlbot.yml` files used to validate them.
|
|
177
|
+
|
|
178
|
+
```yaml
|
|
179
|
+
defaults:
|
|
180
|
+
required_key: true
|
|
181
|
+
rules:
|
|
182
|
+
- key: person
|
|
183
|
+
types: [object]
|
|
184
|
+
- key: person.name
|
|
185
|
+
types: [string]
|
|
186
|
+
- key: person.age
|
|
187
|
+
types: [number]
|
|
188
|
+
- key: person.haircolor
|
|
189
|
+
required_key: false
|
|
190
|
+
types: [string]
|
|
191
|
+
- key: person.race
|
|
192
|
+
types: [string]
|
|
193
|
+
value_whitelist: [dwarf, highelf, human, orc, hobbit]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
person:
|
|
198
|
+
name: Frodo
|
|
199
|
+
age: 20
|
|
200
|
+
race: hobbit
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The above yaml file would pass validation due to defining all of the required
|
|
204
|
+
keys with valid values.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
defaults:
|
|
210
|
+
required_key: false
|
|
211
|
+
types: [string, list]
|
|
212
|
+
rules:
|
|
213
|
+
- key: language
|
|
214
|
+
types: [string]
|
|
215
|
+
value_whitelist: [c, go, java, objective-c, python, ruby, swift]
|
|
216
|
+
- key: before_install
|
|
217
|
+
- key: install
|
|
218
|
+
- key: before_script
|
|
219
|
+
- key: script
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
language: java
|
|
224
|
+
install:
|
|
225
|
+
- export JAVA_HOME='/usr/bin/java1.8/'
|
|
226
|
+
- mvn install
|
|
227
|
+
script: mvn test
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The above yaml file would pass validation due to defining all of the keys with
|
|
231
|
+
valid values. Although, an empty yaml file would've passed validation due to
|
|
232
|
+
no keys being marked as *required* in the `defaults` section.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
rules:
|
|
238
|
+
- key: bookshelf_items
|
|
239
|
+
required_key: true
|
|
240
|
+
types: [string, list]
|
|
241
|
+
- key: toybox_items
|
|
242
|
+
required_key: false
|
|
243
|
+
types: [string, list]
|
|
244
|
+
value_blacklist: [legos, barbies, hotwheels]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
toybox:
|
|
249
|
+
- 'barbies'
|
|
250
|
+
- 'batman'
|
|
251
|
+
- 'beanie baby'
|
|
252
|
+
bookshelf_items:
|
|
253
|
+
- 'Brittanica Encyclopedia'
|
|
254
|
+
- 'How to adult for dummies'
|
|
255
|
+
- 'YAML for beginners'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The above yaml file would fail validation due to defining the `toybox_items`
|
|
259
|
+
key with a blacked listed value.
|
data/bin/yamlbot
CHANGED
data/lib/yaml_bot/cli_bot.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
|
-
require 'yaml_bot/logging_bot'
|
|
3
2
|
require 'yaml_bot/rules_bot'
|
|
4
3
|
require 'yaml_bot/validation_bot'
|
|
5
|
-
require 'active_support/core_ext/hash/keys'
|
|
6
4
|
|
|
7
5
|
module YamlBot
|
|
8
6
|
class CLIBot
|
|
@@ -10,91 +8,65 @@ module YamlBot
|
|
|
10
8
|
|
|
11
9
|
def initialize(opts = {})
|
|
12
10
|
@options = opts
|
|
13
|
-
log_file = File.new('yaml_bot.log', 'w')
|
|
14
|
-
@logger_bot = LoggingBot.new(log_file)
|
|
15
11
|
@rules_bot = RulesBot.new
|
|
16
12
|
@validation_bot = ValidationBot.new
|
|
17
13
|
end
|
|
18
14
|
|
|
19
15
|
def run
|
|
20
16
|
check_cli_options
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
scan_yaml_file
|
|
17
|
+
load_rules
|
|
18
|
+
load_yaml
|
|
19
|
+
validate_rules
|
|
20
|
+
scan_yaml
|
|
26
21
|
print_results
|
|
27
22
|
@validation_bot.violations.zero? ? 0 : 1
|
|
28
|
-
ensure
|
|
29
|
-
@logger_bot.close_log
|
|
30
23
|
end
|
|
31
24
|
|
|
32
25
|
private
|
|
33
26
|
|
|
34
|
-
def
|
|
35
|
-
if @
|
|
36
|
-
|
|
27
|
+
def print_results
|
|
28
|
+
if @validation_bot.violations.positive?
|
|
29
|
+
puts pluralize(@validation_bot.violations,
|
|
30
|
+
'violation',
|
|
31
|
+
'violations')
|
|
37
32
|
else
|
|
38
|
-
|
|
33
|
+
puts "#{@validation_bot.violations} violations"
|
|
39
34
|
end
|
|
40
35
|
end
|
|
41
36
|
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
def load_rules
|
|
38
|
+
rules_file = @options[:rules] || '.yamlbot.yml'
|
|
39
|
+
raise IOError unless File.exist?(rules_file)
|
|
40
|
+
rules = YAML.load_file(rules_file)
|
|
41
|
+
@rules_bot.rules = rules
|
|
42
|
+
@validation_bot.rules = rules
|
|
43
|
+
rescue IOError
|
|
44
|
+
$stderr.puts "Unable to locate file: #{rules_file}"
|
|
45
|
+
$stderr.puts 'Create a .yamlbot.yml file in the current directory'
|
|
46
|
+
$stderr.puts 'or specify a rules file with the -r option'
|
|
49
47
|
exit 1
|
|
50
48
|
end
|
|
51
49
|
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
def load_yaml
|
|
51
|
+
raise StandardError, 'No YAML file specified' if @options[:file].nil?
|
|
52
|
+
raise IOError unless File.exist?(@options[:file])
|
|
53
|
+
@validation_bot.yaml_file = YAML.load_file(@options[:file])
|
|
54
|
+
rescue IOError
|
|
55
|
+
$stderr.puts "Unable to locate file: #{@options[:file]}"
|
|
56
|
+
$stderr.puts 'Pass a YAML file to validate with the -f option'
|
|
57
|
+
exit 1
|
|
55
58
|
end
|
|
56
59
|
|
|
57
|
-
def
|
|
60
|
+
def validate_rules
|
|
61
|
+
puts 'Validating rules file...'
|
|
58
62
|
@rules_bot.validate_rules
|
|
63
|
+
puts "Rules file validated...\n\n"
|
|
59
64
|
end
|
|
60
65
|
|
|
61
|
-
def
|
|
62
|
-
|
|
66
|
+
def scan_yaml
|
|
67
|
+
puts 'Beginning scan...'
|
|
63
68
|
@validation_bot.scan
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def print_results
|
|
68
|
-
if @validation_bot.violations > 0
|
|
69
|
-
@logger_bot.error pluralize(@validation_bot.violations,
|
|
70
|
-
'violation',
|
|
71
|
-
'violations')
|
|
72
|
-
else
|
|
73
|
-
@logger_bot.info "#{@validation_bot.violations} violations"
|
|
74
|
-
end
|
|
75
|
-
puts "Results logged to #{File.absolute_path(@logger_bot.log_file.path)}"
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def load_default_rules
|
|
79
|
-
rules_file = YAML.load(File.open('.yamlbot.yml')).deep_symbolize_keys
|
|
80
|
-
@rules_bot.rules = rules_file
|
|
81
|
-
@validation_bot.rules = rules_file
|
|
82
|
-
rescue StandardError
|
|
83
|
-
$stderr.puts 'Unable to locate .yamlbot.yml file...'
|
|
84
|
-
$stderr.puts 'Create a .yamlbot.yml file in the current directory'
|
|
85
|
-
$stderr.puts 'or specify a rules file with the -r option.'
|
|
86
|
-
exit 1
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def load_custom_rules
|
|
90
|
-
rules_file = YAML.load(File.open(@options[:rules])).deep_symbolize_keys
|
|
91
|
-
@rules_bot.rules = rules_file
|
|
92
|
-
@validation_bot.rules = rules_file
|
|
93
|
-
rescue StandardError => e
|
|
94
|
-
$stderr.puts "Unable to locate rules file #{options[:rules]}..."
|
|
95
|
-
$stderr.puts e.message
|
|
96
|
-
$stderr.puts e.backtrace
|
|
97
|
-
exit 1
|
|
69
|
+
puts "Finished scan...\n\n"
|
|
98
70
|
end
|
|
99
71
|
|
|
100
72
|
def pluralize(n, singular, plural = nil)
|
|
@@ -119,6 +91,7 @@ module YamlBot
|
|
|
119
91
|
"\t-r, --rule-file rules\t\tThe rules you will be evaluating your "\
|
|
120
92
|
'yaml against',
|
|
121
93
|
"\t-f, --file file\t\t\tThe file to validate against",
|
|
94
|
+
# "\t-c, --color\t\t\tEnable colored output",
|
|
122
95
|
"\t-h, --help\t\t\thelp"
|
|
123
96
|
].join("\n")
|
|
124
97
|
puts msg
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'yaml_bot/parse_bot'
|
|
2
|
+
|
|
3
|
+
module YamlBot
|
|
4
|
+
class KeyBot
|
|
5
|
+
attr_accessor :defaults, :invalid, :key, :yaml_file
|
|
6
|
+
|
|
7
|
+
TYPE_MAP = {
|
|
8
|
+
object: Hash,
|
|
9
|
+
list: Array,
|
|
10
|
+
string: String,
|
|
11
|
+
number: [Integer, Float],
|
|
12
|
+
boolean: [TrueClass, FalseClass]
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
VALIDATION_CHECKS = [
|
|
16
|
+
:check_if_key_is_required,
|
|
17
|
+
:check_and_requires,
|
|
18
|
+
:check_or_requires,
|
|
19
|
+
:check_val_whitelist,
|
|
20
|
+
:check_val_blacklist,
|
|
21
|
+
:check_types
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
def initialize(key, yaml_file, defaults)
|
|
25
|
+
@defaults = defaults || {}
|
|
26
|
+
@invalid = false
|
|
27
|
+
@key = @defaults.merge(key)
|
|
28
|
+
@yaml_file = yaml_file
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def validate
|
|
32
|
+
VALIDATION_CHECKS.each do |method|
|
|
33
|
+
send(method)
|
|
34
|
+
break if @invalid
|
|
35
|
+
end
|
|
36
|
+
@invalid ? 1 : 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def check_if_key_is_required
|
|
40
|
+
yaml_key = ParseBot.get_object_value(yaml_file, key['key'])
|
|
41
|
+
return unless key['required_key'] && yaml_key.nil?
|
|
42
|
+
return unless key['or_requires'].nil?
|
|
43
|
+
@invalid = true
|
|
44
|
+
puts "VIOLATION: Missing required key: #{key['key']}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def check_and_requires
|
|
48
|
+
yaml_key = ParseBot.get_object_value(yaml_file, key['key'])
|
|
49
|
+
return if yaml_key.nil? || key['and_requires'].nil?
|
|
50
|
+
key['and_requires'].each do |k|
|
|
51
|
+
next unless ParseBot.get_object_value(yaml_file, k).nil?
|
|
52
|
+
@invalid = true
|
|
53
|
+
puts "VIOLATION: Key #{key['key']} requires that the following key(s)"
|
|
54
|
+
puts "also be defined: #{key['and_requires']}"
|
|
55
|
+
break
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# If the key being checked, or any of
|
|
60
|
+
# the keys in the "or_requires" list
|
|
61
|
+
# are in the yaml then check passes
|
|
62
|
+
def check_or_requires
|
|
63
|
+
return if key['or_requires'].nil?
|
|
64
|
+
alt_key = search_for_alternate_key(key)
|
|
65
|
+
value = ParseBot.get_object_value(yaml_file, key['key'])
|
|
66
|
+
@invalid = value.nil? && alt_key.nil?
|
|
67
|
+
return unless @invalid
|
|
68
|
+
puts "VIOLATION: Key #{key['key']} or the following key(s)"
|
|
69
|
+
puts "must be defined: #{key['and_requires']}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def check_val_whitelist
|
|
73
|
+
return if key['value_whitelist'].nil?
|
|
74
|
+
value = ParseBot.get_object_value(yaml_file, key['key'])
|
|
75
|
+
return if key['value_whitelist'].include?(value)
|
|
76
|
+
@invalid = true
|
|
77
|
+
puts "VIOLATION: Invalid value #{value} for whitelist #{key['value_whitelist']}\n"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def check_val_blacklist
|
|
81
|
+
return if key['value_blacklist'].nil?
|
|
82
|
+
value = ParseBot.get_object_value(yaml_file, key['key'])
|
|
83
|
+
return unless key['value_blacklist'].include?(value)
|
|
84
|
+
@invalid = true
|
|
85
|
+
puts "VIOLATION: Blacklisted value specified #{value}\n"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def check_types
|
|
89
|
+
return if key['types'].nil?
|
|
90
|
+
value = ParseBot.get_object_value(yaml_file, key['key'])
|
|
91
|
+
return if value.nil?
|
|
92
|
+
@invalid = !value_is_a_valid_type?(key['types'], value)
|
|
93
|
+
return unless @invalid
|
|
94
|
+
puts "VIOLATION: Invalid value type specified for key: #{key['key']}"
|
|
95
|
+
puts "#{value.class} given, valid types include #{key['types']}\n"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def search_for_alternate_key(key_map)
|
|
101
|
+
alt_key = nil
|
|
102
|
+
key_map['or_requires'].each do |k|
|
|
103
|
+
alt_key = ParseBot.get_object_value(yaml_file, k)
|
|
104
|
+
return alt_key unless alt_key.nil?
|
|
105
|
+
end
|
|
106
|
+
alt_key
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def value_is_a_valid_type?(types, value)
|
|
110
|
+
types.any? do |type|
|
|
111
|
+
type_value = TYPE_MAP[type.downcase.to_sym]
|
|
112
|
+
return type_value.any? { |t| value.instance_of?(t) } if type_value.instance_of?(Array)
|
|
113
|
+
return true if value.instance_of?(type_value)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/yaml_bot/logging_bot.rb
CHANGED
|
@@ -16,9 +16,10 @@ module YamlBot
|
|
|
16
16
|
|
|
17
17
|
attr_accessor :log_file, :log_level
|
|
18
18
|
|
|
19
|
-
def initialize(log_file, level
|
|
19
|
+
def initialize(log_file, level: :info, no_color: false)
|
|
20
20
|
@log_file = log_file
|
|
21
21
|
@log_level = level.to_sym unless valid_log_level(level)
|
|
22
|
+
@no_color = no_color
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def info(message)
|
|
@@ -50,9 +51,9 @@ module YamlBot
|
|
|
50
51
|
def emit(opts = {})
|
|
51
52
|
color = opts[:color]
|
|
52
53
|
message = opts[:message]
|
|
53
|
-
print ESCAPES[color]
|
|
54
|
+
print ESCAPES[color] unless @no_color
|
|
54
55
|
print message
|
|
55
|
-
print ESCAPES[:reset]
|
|
56
|
+
print ESCAPES[:reset] unless @no_color
|
|
56
57
|
print "\n"
|
|
57
58
|
end
|
|
58
59
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module YamlBot
|
|
2
|
+
class ParseBot
|
|
3
|
+
def self.get_object_value(yaml, key_addr)
|
|
4
|
+
if !key_addr.index('.').nil? && key_addr.index('.') >= 0
|
|
5
|
+
key1, key2 = key_addr.split('.', 2)
|
|
6
|
+
return get_object_value(yaml[key1], key2) if !yaml[key1].nil? && yaml[key1].instance_of?(Hash)
|
|
7
|
+
return nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
return to_boolean(yaml[key_addr]) if %w(true false).include?(yaml[key_addr])
|
|
11
|
+
yaml[key_addr]
|
|
12
|
+
rescue StandardError => e
|
|
13
|
+
puts "Caught exception #{e}!"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private_class_method
|
|
17
|
+
|
|
18
|
+
def self.to_boolean(val)
|
|
19
|
+
val == 'true'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/yaml_bot/rules_bot.rb
CHANGED
|
@@ -1,115 +1,70 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
|
-
require 'yaml_bot/logging_bot'
|
|
3
2
|
require 'yaml_bot/validation_error'
|
|
4
3
|
|
|
5
4
|
module YamlBot
|
|
6
5
|
class RulesBot
|
|
7
|
-
attr_accessor :rules
|
|
6
|
+
attr_accessor :rules
|
|
8
7
|
|
|
9
|
-
def initialize
|
|
10
|
-
@rules =
|
|
11
|
-
@missing_required_keys = false
|
|
12
|
-
@missing_optional_keys = false
|
|
8
|
+
def initialize(rules = nil)
|
|
9
|
+
@rules = rules
|
|
13
10
|
end
|
|
14
11
|
|
|
15
12
|
def validate_rules
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def check_top_level_keys
|
|
25
|
-
[:required, :optional].each do |key_type|
|
|
26
|
-
next if determine_key_type(key_type)
|
|
27
|
-
@rules[:root_keys][key_type].each do |key|
|
|
28
|
-
name = key.keys.first
|
|
29
|
-
check_subkeys_and_accepted_types(key[name])
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def check_subkeys_and_accepted_types(key)
|
|
35
|
-
validate_accepted_types(key) unless key[:accepted_types].nil?
|
|
36
|
-
validate_keys(key[:subkeys]) unless key[:subkeys].nil?
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def determine_key_type(key_type)
|
|
40
|
-
if key_type == :required
|
|
41
|
-
@missing_required_keys
|
|
13
|
+
raise ValidationError, '.yamlbot rules file is not set.' if @rules.nil?
|
|
14
|
+
raise ValidationError, 'rules section not defined in .yamlbot file' if @rules['rules'].nil?
|
|
15
|
+
validate_rules_keys(@rules['defaults']) unless @rules['defaults'].nil?
|
|
16
|
+
if @rules['rules'].instance_of?(Array)
|
|
17
|
+
validate_each_key_rule
|
|
42
18
|
else
|
|
43
|
-
|
|
19
|
+
msg = "The rules section of a rules file must define a list of keys.\n"
|
|
20
|
+
raise ValidationError, msg
|
|
44
21
|
end
|
|
45
22
|
end
|
|
46
23
|
|
|
47
|
-
|
|
48
|
-
check_existance_of_root_keys_key
|
|
49
|
-
check_existance_of_required_and_optional_keys
|
|
50
|
-
fail_validation_if_missing_required_and_optional_keys
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def check_existance_of_root_keys_key
|
|
54
|
-
return unless @rules[:root_keys].nil?
|
|
55
|
-
msg = "Missing 'root_keys' key\n"
|
|
56
|
-
msg += "Rules file must specify 'root_keys' as the top level key\n"
|
|
57
|
-
logger.error msg
|
|
58
|
-
raise YamlBot::ValidationError, msg
|
|
59
|
-
end
|
|
24
|
+
private
|
|
60
25
|
|
|
61
|
-
def
|
|
62
|
-
[
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
log_missing_key_type(key_type)
|
|
66
|
-
end
|
|
26
|
+
def validate_each_key_rule
|
|
27
|
+
@rules['rules'].each do |key_map|
|
|
28
|
+
validate_key_map(key_map)
|
|
29
|
+
puts "Key: #{key_map['key']} validated."
|
|
67
30
|
end
|
|
68
31
|
end
|
|
69
32
|
|
|
70
|
-
def
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
else
|
|
75
|
-
@missing_optional_keys = true
|
|
76
|
-
logger.info 'No optional keys specified.'
|
|
77
|
-
end
|
|
33
|
+
def validate_key_map(key_map)
|
|
34
|
+
validate_rules_keys(key_map)
|
|
35
|
+
validate_key_exists_and_is_string(key_map)
|
|
36
|
+
validate_required_key_exists_and_is_bool(key_map)
|
|
78
37
|
end
|
|
79
38
|
|
|
80
|
-
def
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
39
|
+
def validate_rules_keys(key_map)
|
|
40
|
+
valid_keys = YAML.load_file(File.dirname(File.realpath(__FILE__)) +
|
|
41
|
+
'/resources/valid_rules_keys.yml')
|
|
42
|
+
invalid_keys = []
|
|
43
|
+
key_map.keys.each { |k| invalid_keys << k unless valid_keys.include?(k) }
|
|
44
|
+
return if invalid_keys.empty?
|
|
45
|
+
msg = "Invalid key(s) specified in rules file: #{invalid_keys}\n"
|
|
46
|
+
msg += "Valid rules keys include: #{valid_keys}\n"
|
|
47
|
+
raise ValidationError, msg
|
|
85
48
|
end
|
|
86
49
|
|
|
87
|
-
def
|
|
88
|
-
[
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
end
|
|
93
|
-
end
|
|
50
|
+
def validate_key_exists_and_is_string(key_map)
|
|
51
|
+
return unless key_map['key'].nil? || !key_map['key'].instance_of?(String)
|
|
52
|
+
msg = "Missing required key 'key' within rules file.\n"
|
|
53
|
+
msg += "Or a key name has a value that is not a String.\n"
|
|
54
|
+
raise ValidationError, msg
|
|
94
55
|
end
|
|
95
56
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
57
|
+
def validate_required_key_exists_and_is_bool(key_map)
|
|
58
|
+
merged_keys = {}.merge(key_map)
|
|
59
|
+
merged_keys = @rules['defaults'].merge(key_map) unless @rules['defaults'].nil?
|
|
60
|
+
return unless merged_keys['required_key'].nil? || !boolean?(merged_keys['required_key'])
|
|
61
|
+
msg = "Missing required key 'required_key' for key: #{key_map['key']}.\n"
|
|
62
|
+
msg += "Or 'required_key' has a value that is not a Boolean.\n"
|
|
63
|
+
raise ValidationError, msg
|
|
100
64
|
end
|
|
101
65
|
|
|
102
|
-
def
|
|
103
|
-
|
|
104
|
-
'/resources/valid_accepted_types.yml'
|
|
105
|
-
allowed_values = YAML.load(File.open(file_name))
|
|
106
|
-
|
|
107
|
-
key_hash[:accepted_types].each do |type|
|
|
108
|
-
next if allowed_values.include?(type)
|
|
109
|
-
msg = "Invalid value for key: #{type}\n"
|
|
110
|
-
msg += "Valid key values are #{allowed_values}"
|
|
111
|
-
raise YamlBot::ValidationError, msg
|
|
112
|
-
end
|
|
66
|
+
def boolean?(arg)
|
|
67
|
+
arg.instance_of?(TrueClass) || arg.instance_of?(FalseClass)
|
|
113
68
|
end
|
|
114
69
|
end
|
|
115
70
|
end
|
|
@@ -1,111 +1,23 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
|
-
require 'yaml_bot/
|
|
3
|
-
require 'yaml_bot/rules_bot'
|
|
4
|
-
require 'yaml_bot/validation_error'
|
|
2
|
+
require 'yaml_bot/key_bot'
|
|
5
3
|
|
|
6
4
|
module YamlBot
|
|
7
5
|
class ValidationBot
|
|
8
|
-
attr_accessor :rules, :yaml_file, :violations
|
|
6
|
+
attr_accessor :rules, :yaml_file, :violations
|
|
9
7
|
|
|
10
|
-
def initialize
|
|
11
|
-
|
|
8
|
+
def initialize(rules = nil, yaml_file = nil)
|
|
9
|
+
@rules = rules || {}
|
|
10
|
+
@yaml_file = yaml_file || {}
|
|
11
|
+
@violations = 0
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def scan
|
|
15
|
-
|
|
16
|
-
[
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
defaults = rules['defaults']
|
|
16
|
+
rules['rules'].each do |item|
|
|
17
|
+
key_bot = KeyBot.new(item, yaml_file, defaults)
|
|
18
|
+
@violations += key_bot.validate
|
|
19
19
|
end
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def validate_keys(yaml, keys, parent_keys, key_type)
|
|
25
|
-
keys.each_with_index do |key_map, index|
|
|
26
|
-
key = key_map.keys.first
|
|
27
|
-
ancestors = parent_keys.dup << key
|
|
28
|
-
if yaml.keys.include?(key)
|
|
29
|
-
validate_subkeys_or_accepted_types(yaml, key, keys, index, ancestors)
|
|
30
|
-
else
|
|
31
|
-
log_missing_key(key_type, ancestors)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def validate_subkeys_or_accepted_types(yaml, key, keys, index, ancestors)
|
|
37
|
-
if !keys[index][key][:subkeys].nil?
|
|
38
|
-
validate_subkeys(yaml, key, keys, index, ancestors)
|
|
39
|
-
else
|
|
40
|
-
validate_accepted_types_or_key_values(yaml[key],
|
|
41
|
-
keys[index][key],
|
|
42
|
-
ancestors)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def validate_subkeys(yaml, key, keys, index, ancestors)
|
|
47
|
-
[:required, :optional].each do |key_type|
|
|
48
|
-
next if keys[index][key][:subkeys][key_type].nil?
|
|
49
|
-
validate_keys(yaml[key],
|
|
50
|
-
keys[index][key][:subkeys][key_type],
|
|
51
|
-
ancestors,
|
|
52
|
-
key_type)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def validate_accepted_types_or_key_values(value, key_block, ancestors)
|
|
57
|
-
types = key_block[:accepted_types]
|
|
58
|
-
key_values = key_block[:values]
|
|
59
|
-
validate_key_values(value, key_values, ancestors) unless key_values.nil?
|
|
60
|
-
validate_accepted_types(value, types, ancestors) unless types.nil?
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def validate_existance_of_rules_and_yaml_files
|
|
64
|
-
return unless rules.nil? || yaml_file.nil?
|
|
65
|
-
msg = "Rules file, or Yaml file is not set\n"
|
|
66
|
-
raise YamlBot::ValidationError, msg
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def validate_accepted_types(value, types, ancestors)
|
|
70
|
-
if types.include?(value.class.to_s)
|
|
71
|
-
msg = "Key: '#{ancestors.join('.')}' contains a value of a valid type "\
|
|
72
|
-
"#{value.class}"
|
|
73
|
-
log_successful_key_validation(msg)
|
|
74
|
-
else
|
|
75
|
-
msg = "Value: '#{value}' of class #{value.class} is not a valid type "\
|
|
76
|
-
"for key: '#{ancestors.join('.')}'\n"
|
|
77
|
-
msg += "Valid types for key '#{ancestors.join('.')}' include #{types}\n"
|
|
78
|
-
log_failed_key_validation(msg)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def validate_key_values(value, key_values, ancestors)
|
|
83
|
-
if key_values.include?('*') || key_values.include?(value)
|
|
84
|
-
msg = "Key: '#{ancestors.join('.')}' contains valid value #{value}"
|
|
85
|
-
log_successful_key_validation(msg)
|
|
86
|
-
else
|
|
87
|
-
msg = "Key: '#{ancestors.join('.')}' contains invalid value #{value}\n"
|
|
88
|
-
msg += "Valid values include #{key_values}"
|
|
89
|
-
log_failed_key_validation(msg)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def log_missing_key(key_type, ancestors)
|
|
94
|
-
if key_type == :required
|
|
95
|
-
self.violations += 1
|
|
96
|
-
logger.error "Missing required key: '#{ancestors.join('.')}'"
|
|
97
|
-
else
|
|
98
|
-
logger.warn "Optional key: '#{ancestors.join('.')}' not utilized"
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def log_successful_key_validation(msg)
|
|
103
|
-
logger.info msg
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def log_failed_key_validation(msg)
|
|
107
|
-
self.violations += 1
|
|
108
|
-
logger.error msg
|
|
20
|
+
@violations
|
|
109
21
|
end
|
|
110
22
|
end
|
|
111
23
|
end
|
data/lib/yaml_bot/version.rb
CHANGED
data/new_spec.yml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
defaults:
|
|
2
|
+
required_key: false
|
|
3
|
+
types: ['String', 'List']
|
|
4
|
+
rules:
|
|
5
|
+
- key: 'language'
|
|
6
|
+
required_key: true
|
|
7
|
+
types: ['String']
|
|
8
|
+
value_whitelist: ['android', 'go', 'python', 'ruby']
|
|
9
|
+
- key: 'env'
|
|
10
|
+
types: ['String', 'List', 'Object']
|
|
11
|
+
- key: 'env.global'
|
|
12
|
+
- key: 'env.matrix'
|
|
13
|
+
- key: 'before_install'
|
|
14
|
+
- key: 'install'
|
|
15
|
+
- key: 'before_script'
|
|
16
|
+
- key: 'script'
|
|
17
|
+
- key: 'branches.only'
|
|
18
|
+
types: ['List']
|
|
19
|
+
- key: 'branches.except'
|
|
20
|
+
types: ['List']
|
|
21
|
+
- key: 'jenkins.sudo'
|
|
22
|
+
types: ['Boolean', 'String']
|
|
23
|
+
- key: 'jenkins.use_gerrit'
|
|
24
|
+
types: ['Boolean', 'String']
|
|
25
|
+
- key: 'jenkins.collect.artifacts'
|
|
26
|
+
|
|
27
|
+
defaults:
|
|
28
|
+
<default values for rules>
|
|
29
|
+
rules:
|
|
30
|
+
- key: 'yaml address'
|
|
31
|
+
required_key: true|false
|
|
32
|
+
and_requires: ['list of yaml addresses']
|
|
33
|
+
or_requires: ['list of yaml addresses']
|
|
34
|
+
value_whitelist: ['list of values']
|
|
35
|
+
value_blacklist: ['list of values']
|
|
36
|
+
types: ['list of types']
|
data/yaml_bot.gemspec
CHANGED
|
@@ -24,7 +24,5 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
25
25
|
spec.add_development_dependency 'rubocop', '~> 0.46.0'
|
|
26
26
|
|
|
27
|
-
spec.
|
|
28
|
-
|
|
29
|
-
spec.required_ruby_version = '>=2.2'
|
|
27
|
+
spec.required_ruby_version = '>=2.4'
|
|
30
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yaml_bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Luis Ortiz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-06-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -66,20 +66,6 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: 0.46.0
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: activesupport
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '5.0'
|
|
76
|
-
type: :runtime
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '5.0'
|
|
83
69
|
description:
|
|
84
70
|
email:
|
|
85
71
|
- lortiz1145@gmail.com
|
|
@@ -100,19 +86,23 @@ files:
|
|
|
100
86
|
- Gemfile
|
|
101
87
|
- LICENSE.txt
|
|
102
88
|
- README.md
|
|
89
|
+
- RULES_DEFINITION.md
|
|
103
90
|
- Rakefile
|
|
104
91
|
- _config.yml
|
|
105
92
|
- bin/setup
|
|
106
93
|
- bin/yamlbot
|
|
107
94
|
- lib/yaml_bot.rb
|
|
108
95
|
- lib/yaml_bot/cli_bot.rb
|
|
96
|
+
- lib/yaml_bot/key_bot.rb
|
|
109
97
|
- lib/yaml_bot/logging_bot.rb
|
|
110
|
-
- lib/yaml_bot/
|
|
111
|
-
- lib/yaml_bot/resources/
|
|
98
|
+
- lib/yaml_bot/parse_bot.rb
|
|
99
|
+
- lib/yaml_bot/resources/valid_rules_keys.yml
|
|
100
|
+
- lib/yaml_bot/resources/valid_types.yml
|
|
112
101
|
- lib/yaml_bot/rules_bot.rb
|
|
113
102
|
- lib/yaml_bot/validation_bot.rb
|
|
114
103
|
- lib/yaml_bot/validation_error.rb
|
|
115
104
|
- lib/yaml_bot/version.rb
|
|
105
|
+
- new_spec.yml
|
|
116
106
|
- yaml_bot.gemspec
|
|
117
107
|
homepage: https://github.com/skippyPeanutButter/yaml_bot
|
|
118
108
|
licenses:
|
|
@@ -126,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
126
116
|
requirements:
|
|
127
117
|
- - ">="
|
|
128
118
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: '2.
|
|
119
|
+
version: '2.4'
|
|
130
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
121
|
requirements:
|
|
132
122
|
- - ">="
|
|
@@ -134,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
134
124
|
version: '0'
|
|
135
125
|
requirements: []
|
|
136
126
|
rubyforge_project:
|
|
137
|
-
rubygems_version: 2.
|
|
127
|
+
rubygems_version: 2.6.11
|
|
138
128
|
signing_key:
|
|
139
129
|
specification_version: 4
|
|
140
130
|
summary: Validate YAML files according to a set of rules.
|