frise 0.3.0 → 0.5.1
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/.github/workflows/CI.yml +40 -0
- data/.rubocop.yml +5 -3
- data/CHANGELOG.md +23 -0
- data/LICENSE.txt +1 -1
- data/frise.gemspec +11 -10
- data/lib/frise/defaults_loader.rb +26 -11
- data/lib/frise/loader/lazy.rb +4 -2
- data/lib/frise/loader.rb +45 -30
- data/lib/frise/parser.rb +1 -1
- data/lib/frise/validator.rb +31 -19
- data/lib/frise/version.rb +1 -1
- metadata +35 -35
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68f89536d127f91e812a1c23258ad32ca3d4331970c9af0632cb3f95fce06e52
|
|
4
|
+
data.tar.gz: 129230d3c50d29a25f4e060bfdf4e839d19aa579607c6bead51acf6237ac9c20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61f5a83ff2ba3e17ae022dbac6639fa3a316c4739685ed3cec8634a9a12789dd280c4373763bdebea85d82821b02856327df0df6fbb423d55affb8010252ec64
|
|
7
|
+
data.tar.gz: bc65274a574e25cdbe6142bd7bc2dbe7d6d9275143c211987845dc916156ebe2f0d3ff5739490ea177b67157545b6c5c4aef0a96bbe6dfbaa6f9061c35fcfd73
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [ push, pull_request ]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
ruby: [ 2.6, 2.7, 3 ]
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v2
|
|
16
|
+
- name: Set up Ruby
|
|
17
|
+
uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: bundle install
|
|
23
|
+
- name: Run tests
|
|
24
|
+
run: bundle exec rake
|
|
25
|
+
- name: Coveralls Parallel
|
|
26
|
+
uses: coverallsapp/github-action@master
|
|
27
|
+
with:
|
|
28
|
+
github-token: ${{ secrets.github_token }}
|
|
29
|
+
flag-name: ${{ matrix.ruby }}
|
|
30
|
+
parallel: true
|
|
31
|
+
|
|
32
|
+
finish:
|
|
33
|
+
needs: test
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- name: Coveralls Finished
|
|
37
|
+
uses: coverallsapp/github-action@master
|
|
38
|
+
with:
|
|
39
|
+
github-token: ${{ secrets.github_token }}
|
|
40
|
+
parallel-finished: true
|
data/.rubocop.yml
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
AllCops:
|
|
2
|
-
|
|
2
|
+
NewCops: enable
|
|
3
|
+
Layout/EmptyLineAfterGuardClause:
|
|
4
|
+
Enabled: false
|
|
3
5
|
Metrics:
|
|
4
6
|
Enabled: false
|
|
5
|
-
Naming/
|
|
7
|
+
Naming/BlockParameterName:
|
|
6
8
|
Enabled: false
|
|
7
|
-
Naming/
|
|
9
|
+
Naming/MethodParameterName:
|
|
8
10
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
### 0.5.1 (March 28, 2022)
|
|
2
|
+
|
|
3
|
+
- Breaking changes
|
|
4
|
+
- Increase minimum required ruby version to 2.6.0 ([#22](https://github.com/velocidi/frise/pull/22)).
|
|
5
|
+
- Bug fixes
|
|
6
|
+
- Fix YAML.safe_load call arguments error in ruby 3.1 ([#26](https://github.com/velocidi/frise/pull/26)).
|
|
7
|
+
|
|
8
|
+
### 0.4.1 (July 7, 2020)
|
|
9
|
+
|
|
10
|
+
- New features
|
|
11
|
+
- `$delete` directive is now available in config files, allowing users to delete parts of the
|
|
12
|
+
config sub-tree ([#20](https://github.com/velocidi/frise/pull/20)).
|
|
13
|
+
|
|
14
|
+
### 0.4.0 (November 29, 2019)
|
|
15
|
+
|
|
16
|
+
- Breaking changes
|
|
17
|
+
- Recursive inclusions now respect the hierarchy of configuration files, avoiding inclusions lower
|
|
18
|
+
in the hiearchy to be resolved before ones higher in the hierarchy
|
|
19
|
+
([#14](https://github.com/velocidi/frise/pull/14)).
|
|
20
|
+
- Bug fixes
|
|
21
|
+
- Fix error messages from validations happening deeper in the config hierarchy, that were wrongly
|
|
22
|
+
missing the first character in their path ([#16](https://github.com/velocidi/frise/pull/16)).
|
|
23
|
+
|
|
1
24
|
### 0.3.0 (April 16, 2018)
|
|
2
25
|
|
|
3
26
|
- Breaking changes
|
data/LICENSE.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright 2017
|
|
1
|
+
Copyright 2017-2019 Velocidi [http://www.velocidi.com/]
|
|
2
2
|
|
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
4
4
|
use this file except in compliance with the License. You may obtain a copy of
|
data/frise.gemspec
CHANGED
|
@@ -7,25 +7,26 @@ require 'frise/version'
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'frise'
|
|
9
9
|
spec.version = Frise::VERSION
|
|
10
|
-
spec.authors = ['
|
|
11
|
-
spec.email = ['
|
|
10
|
+
spec.authors = ['Velocidi']
|
|
11
|
+
spec.email = ['hello@velocidi.com']
|
|
12
12
|
|
|
13
13
|
spec.summary = 'Ruby config library with schema validation, default values and templating'
|
|
14
|
-
spec.homepage = 'https://github.com/
|
|
14
|
+
spec.homepage = 'https://github.com/velocidi/frise'
|
|
15
15
|
spec.license = 'Apache-2.0'
|
|
16
16
|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
18
18
|
f.match(%r{^(test|spec|features|example)/})
|
|
19
19
|
end
|
|
20
20
|
spec.require_paths = ['lib']
|
|
21
|
-
spec.required_ruby_version = '>= 2.
|
|
21
|
+
spec.required_ruby_version = '>= 2.6.0'
|
|
22
22
|
|
|
23
23
|
spec.add_dependency 'liquid', '~> 4.0'
|
|
24
24
|
|
|
25
|
-
spec.add_development_dependency 'bundler', '~>
|
|
26
|
-
spec.add_development_dependency '
|
|
27
|
-
spec.add_development_dependency '
|
|
28
|
-
spec.add_development_dependency '
|
|
29
|
-
spec.add_development_dependency '
|
|
30
|
-
spec.add_development_dependency 'simplecov', '
|
|
25
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
26
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.9'
|
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 1.10'
|
|
29
|
+
spec.add_development_dependency 'simplecov', '~> 0.18'
|
|
30
|
+
spec.add_development_dependency 'simplecov-lcov', '0.8.0'
|
|
31
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
31
32
|
end
|
|
@@ -10,20 +10,20 @@ module Frise
|
|
|
10
10
|
class DefaultsLoader
|
|
11
11
|
SYMBOLS = %w[$all $optional].freeze
|
|
12
12
|
|
|
13
|
-
def initialize(
|
|
13
|
+
def initialize(
|
|
14
|
+
include_sym: '$include',
|
|
15
|
+
content_include_sym: '$content_include',
|
|
16
|
+
schema_sym: '$schema',
|
|
17
|
+
delete_sym: '$delete'
|
|
18
|
+
)
|
|
19
|
+
|
|
14
20
|
@include_sym = include_sym
|
|
15
21
|
@content_include_sym = content_include_sym
|
|
16
22
|
@schema_sym = schema_sym
|
|
23
|
+
@delete_sym = delete_sym
|
|
17
24
|
end
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
class_name = obj.class.to_s
|
|
21
|
-
return 'String' if class_name == 'Hash' && !obj[@content_include_sym].nil?
|
|
22
|
-
return 'Boolean' if %w[TrueClass FalseClass].include? class_name
|
|
23
|
-
return 'Integer' if %w[Fixnum Bignum].include? class_name
|
|
24
|
-
class_name
|
|
25
|
-
end
|
|
26
|
-
|
|
26
|
+
# rubocop:disable Lint/DuplicateBranch
|
|
27
27
|
def merge_defaults_obj(config, defaults)
|
|
28
28
|
config_class = widened_class(config)
|
|
29
29
|
defaults_class = widened_class(defaults)
|
|
@@ -34,9 +34,13 @@ module Frise
|
|
|
34
34
|
elsif config.nil?
|
|
35
35
|
if defaults_class != 'Hash' then defaults
|
|
36
36
|
elsif defaults['$optional'] then nil
|
|
37
|
-
else
|
|
37
|
+
else
|
|
38
|
+
merge_defaults_obj({}, defaults)
|
|
38
39
|
end
|
|
39
40
|
|
|
41
|
+
elsif config == @delete_sym
|
|
42
|
+
config
|
|
43
|
+
|
|
40
44
|
elsif defaults_class == 'Array' && config_class == 'Array'
|
|
41
45
|
defaults + config
|
|
42
46
|
|
|
@@ -56,12 +60,13 @@ module Frise
|
|
|
56
60
|
|
|
57
61
|
elsif defaults_class != config_class
|
|
58
62
|
raise "Cannot merge config #{config.inspect} (#{widened_class(config)}) " \
|
|
59
|
-
|
|
63
|
+
"with default #{defaults.inspect} (#{widened_class(defaults)})"
|
|
60
64
|
|
|
61
65
|
else
|
|
62
66
|
config
|
|
63
67
|
end
|
|
64
68
|
end
|
|
69
|
+
# rubocop:enable Lint/DuplicateBranch
|
|
65
70
|
|
|
66
71
|
def merge_defaults_obj_at(config, at_path, defaults)
|
|
67
72
|
at_path.reverse.each { |key| defaults = { key => defaults } }
|
|
@@ -77,5 +82,15 @@ module Frise
|
|
|
77
82
|
defaults = Parser.parse(defaults_file, symbol_table) || {}
|
|
78
83
|
merge_defaults_obj_at(config, at_path, defaults)
|
|
79
84
|
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def widened_class(obj)
|
|
89
|
+
class_name = obj.class.to_s
|
|
90
|
+
return 'String' if class_name == 'Hash' && !obj[@content_include_sym].nil?
|
|
91
|
+
return 'Boolean' if %w[TrueClass FalseClass].include? class_name
|
|
92
|
+
return 'Integer' if %w[Fixnum Bignum].include? class_name
|
|
93
|
+
class_name
|
|
94
|
+
end
|
|
80
95
|
end
|
|
81
96
|
end
|
data/lib/frise/loader/lazy.rb
CHANGED
|
@@ -12,11 +12,13 @@ module Frise
|
|
|
12
12
|
@__target_object__ ||= @callable.call
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# rubocop:disable Style/MethodMissing
|
|
16
15
|
def method_missing(method_name, *args, &block)
|
|
17
16
|
__target_object__.send(method_name, *args, &block)
|
|
18
17
|
end
|
|
19
|
-
|
|
18
|
+
|
|
19
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
20
|
+
__target_object__.respond_to?(method_name, include_private)
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
data/lib/frise/loader.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Frise
|
|
|
13
13
|
def initialize(include_sym: '$include',
|
|
14
14
|
content_include_sym: '$content_include',
|
|
15
15
|
schema_sym: '$schema',
|
|
16
|
+
delete_sym: '$delete',
|
|
16
17
|
pre_loaders: [],
|
|
17
18
|
validators: nil,
|
|
18
19
|
exit_on_fail: true)
|
|
@@ -20,6 +21,7 @@ module Frise
|
|
|
20
21
|
@include_sym = include_sym
|
|
21
22
|
@content_include_sym = content_include_sym
|
|
22
23
|
@schema_sym = schema_sym
|
|
24
|
+
@delete_sym = delete_sym
|
|
23
25
|
@pre_loaders = pre_loaders
|
|
24
26
|
@validators = validators
|
|
25
27
|
@exit_on_fail = exit_on_fail
|
|
@@ -27,7 +29,8 @@ module Frise
|
|
|
27
29
|
@defaults_loader = DefaultsLoader.new(
|
|
28
30
|
include_sym: include_sym,
|
|
29
31
|
content_include_sym: content_include_sym,
|
|
30
|
-
schema_sym: schema_sym
|
|
32
|
+
schema_sym: schema_sym,
|
|
33
|
+
delete_sym: delete_sym
|
|
31
34
|
)
|
|
32
35
|
end
|
|
33
36
|
|
|
@@ -39,15 +42,15 @@ module Frise
|
|
|
39
42
|
config = pre_loader.call(config)
|
|
40
43
|
end
|
|
41
44
|
|
|
42
|
-
config = process_includes(config, [], config, global_vars)
|
|
43
|
-
config = process_schemas(config, [], global_vars)
|
|
45
|
+
config = process_includes(config, [], config, global_vars) unless @include_sym.nil?
|
|
46
|
+
config = process_schemas(config, [], global_vars) unless @schema_sym.nil?
|
|
44
47
|
config
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
private
|
|
48
51
|
|
|
49
|
-
def process_includes(config, at_path, root_config, global_vars)
|
|
50
|
-
return config unless config.
|
|
52
|
+
def process_includes(config, at_path, root_config, global_vars, include_confs_stack = [])
|
|
53
|
+
return config unless config.instance_of?(Hash)
|
|
51
54
|
|
|
52
55
|
# process $content_include directives
|
|
53
56
|
config, content_include_confs = extract_content_include(config, at_path)
|
|
@@ -63,30 +66,30 @@ module Frise
|
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
# process $include directives
|
|
66
|
-
config,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
config, next_include_confs = extract_include(config, at_path)
|
|
70
|
+
include_confs = next_include_confs + include_confs_stack
|
|
71
|
+
res = if include_confs.empty?
|
|
72
|
+
config.to_h { |k, v| [k, process_includes(v, at_path + [k], root_config, global_vars)] }
|
|
73
|
+
else
|
|
74
|
+
Lazy.new do
|
|
75
|
+
include_conf = include_confs.first
|
|
76
|
+
rest_include_confs = include_confs[1..]
|
|
77
|
+
symbol_table = build_symbol_table(root_config, at_path, config, global_vars, include_conf)
|
|
78
|
+
included_config = Parser.parse(include_conf['file'], symbol_table)
|
|
79
|
+
config = @defaults_loader.merge_defaults_obj(config, included_config)
|
|
80
|
+
process_includes(config, at_path, merge_at(root_config, at_path, config), global_vars,
|
|
81
|
+
rest_include_confs)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
@delete_sym.nil? ? res : omit_deleted(res)
|
|
82
85
|
end
|
|
83
86
|
|
|
84
87
|
def process_schema_includes(schema, at_path, global_vars)
|
|
85
|
-
return schema unless schema.
|
|
88
|
+
return schema unless schema.instance_of?(Hash)
|
|
86
89
|
|
|
87
90
|
schema, included_schemas = extract_include(schema, at_path)
|
|
88
91
|
if included_schemas.empty?
|
|
89
|
-
schema.
|
|
92
|
+
schema.to_h { |k, v| [k, process_schema_includes(v, at_path + [k], global_vars)] }
|
|
90
93
|
else
|
|
91
94
|
included_schemas.each do |defaults_conf|
|
|
92
95
|
schema = Parser.parse(defaults_conf['file'], global_vars).merge(schema)
|
|
@@ -96,13 +99,13 @@ module Frise
|
|
|
96
99
|
end
|
|
97
100
|
|
|
98
101
|
def process_schemas(config, at_path, global_vars)
|
|
99
|
-
return config unless config.
|
|
102
|
+
return config unless config.instance_of?(Hash)
|
|
100
103
|
|
|
101
|
-
config = config.
|
|
104
|
+
config = config.to_h do |k, v|
|
|
102
105
|
new_v = process_schemas(v, at_path + [k], global_vars)
|
|
103
106
|
return nil if !v.nil? && new_v.nil?
|
|
104
107
|
[k, new_v]
|
|
105
|
-
end
|
|
108
|
+
end
|
|
106
109
|
|
|
107
110
|
config, schema_files = extract_schema(config, at_path)
|
|
108
111
|
schema_files.each do |schema_file|
|
|
@@ -147,10 +150,10 @@ module Frise
|
|
|
147
150
|
end
|
|
148
151
|
end
|
|
149
152
|
|
|
150
|
-
def extract_special(config, key, at_path)
|
|
153
|
+
def extract_special(config, key, at_path, &block)
|
|
151
154
|
case config[key]
|
|
152
155
|
when nil then [config, []]
|
|
153
|
-
when Array then [config.reject { |k| k == key }, config[key].map
|
|
156
|
+
when Array then [config.reject { |k| k == key }, config[key].map(&block)]
|
|
154
157
|
else raise "At #{build_path(at_path)}: illegal value for #{key}: #{config[key].inspect}"
|
|
155
158
|
end
|
|
156
159
|
end
|
|
@@ -162,6 +165,18 @@ module Frise
|
|
|
162
165
|
config.merge(head => merge_at(config[head], tail, to_merge))
|
|
163
166
|
end
|
|
164
167
|
|
|
168
|
+
# returns the config without the keys whose values are @delete_sym
|
|
169
|
+
# @delete_sym given as array elements are not handled.
|
|
170
|
+
def omit_deleted(config)
|
|
171
|
+
config.each_with_object({}) do |(k, v), new_hash|
|
|
172
|
+
if v.is_a?(Hash)
|
|
173
|
+
new_hash[k] = omit_deleted(v)
|
|
174
|
+
else
|
|
175
|
+
new_hash[k] = v unless v == @delete_sym
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
165
180
|
# builds the symbol table for the Liquid renderization of a file, based on:
|
|
166
181
|
# - `root_config`: the root of the whole config
|
|
167
182
|
# - `at_path`: the current path
|
|
@@ -169,10 +184,10 @@ module Frise
|
|
|
169
184
|
# - `global_vars`: the global variables
|
|
170
185
|
# - `include_conf`: the $include or $content_include configuration
|
|
171
186
|
def build_symbol_table(root_config, at_path, config, global_vars, include_conf)
|
|
172
|
-
extra_vars = (include_conf['vars'] || {}).
|
|
187
|
+
extra_vars = (include_conf['vars'] || {}).transform_values { |v| root_config.dig(*v.split('.')) }
|
|
173
188
|
extra_consts = include_conf['constants'] || {}
|
|
174
189
|
|
|
175
|
-
(config ? merge_at(root_config, at_path, config) : root_config)
|
|
190
|
+
omit_deleted(config ? merge_at(root_config, at_path, config) : root_config)
|
|
176
191
|
.merge(global_vars)
|
|
177
192
|
.merge(extra_vars)
|
|
178
193
|
.merge(extra_consts)
|
data/lib/frise/parser.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Frise
|
|
|
10
10
|
class << self
|
|
11
11
|
def parse(file, symbol_table = nil)
|
|
12
12
|
return nil unless File.file? file
|
|
13
|
-
YAML.safe_load(parse_as_text(file, symbol_table),
|
|
13
|
+
YAML.safe_load(parse_as_text(file, symbol_table), aliases: true) || {}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def parse_as_text(file, symbol_table = nil)
|
data/lib/frise/validator.rb
CHANGED
|
@@ -14,6 +14,8 @@ module Frise
|
|
|
14
14
|
attr_reader :errors
|
|
15
15
|
|
|
16
16
|
def initialize(root, validators = nil)
|
|
17
|
+
super()
|
|
18
|
+
|
|
17
19
|
@root = root
|
|
18
20
|
@validators = validators
|
|
19
21
|
@errors = []
|
|
@@ -27,23 +29,23 @@ module Frise
|
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def add_validation_error(path, msg)
|
|
30
|
-
logged_path = path.empty? ? '<root>' : path
|
|
32
|
+
logged_path = path.empty? ? '<root>' : path
|
|
31
33
|
@errors << "At #{logged_path}: #{msg}"
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def get_full_schema(schema)
|
|
35
37
|
case schema
|
|
36
|
-
when Hash
|
|
38
|
+
when Hash
|
|
37
39
|
default_type = schema[:enum] || schema[:one_of] ? 'Object' : 'Hash'
|
|
38
40
|
{ type: default_type }.merge(schema)
|
|
39
41
|
when Symbol then { type: 'Object', validate: schema }
|
|
40
|
-
when Array
|
|
42
|
+
when Array
|
|
41
43
|
if schema.size == 1
|
|
42
44
|
{ type: 'Array', all: schema[0] }
|
|
43
45
|
else
|
|
44
46
|
(raise "Invalid schema: #{schema.inspect}")
|
|
45
47
|
end
|
|
46
|
-
when String
|
|
48
|
+
when String
|
|
47
49
|
if schema.end_with?('?')
|
|
48
50
|
{ type: schema[0..-2], optional: true }
|
|
49
51
|
else
|
|
@@ -83,8 +85,8 @@ module Frise
|
|
|
83
85
|
if full_schema[:validate]
|
|
84
86
|
begin
|
|
85
87
|
@validators.method(full_schema[:validate]).call(@root, obj)
|
|
86
|
-
rescue StandardError =>
|
|
87
|
-
add_validation_error(path,
|
|
88
|
+
rescue StandardError => e
|
|
89
|
+
add_validation_error(path, e.message)
|
|
88
90
|
end
|
|
89
91
|
end
|
|
90
92
|
true
|
|
@@ -93,7 +95,7 @@ module Frise
|
|
|
93
95
|
def validate_enum(full_schema, obj, path)
|
|
94
96
|
if full_schema[:enum] && !full_schema[:enum].include?(obj)
|
|
95
97
|
add_validation_error(path, "invalid value #{obj.inspect}. " \
|
|
96
|
-
|
|
98
|
+
"Accepted values are #{full_schema[:enum].map(&:inspect).join(', ')}")
|
|
97
99
|
return false
|
|
98
100
|
end
|
|
99
101
|
true
|
|
@@ -115,7 +117,7 @@ module Frise
|
|
|
115
117
|
def validate_spec_keys(full_schema, obj, path, processed_keys)
|
|
116
118
|
full_schema.each do |spec_key, spec_value|
|
|
117
119
|
next if spec_key.is_a?(Symbol)
|
|
118
|
-
validate_object("#{path}.#{spec_key}", obj[spec_key], spec_value)
|
|
120
|
+
validate_object(path.empty? ? spec_key : "#{path}.#{spec_key}", obj[spec_key], spec_value)
|
|
119
121
|
processed_keys << spec_key
|
|
120
122
|
end
|
|
121
123
|
true
|
|
@@ -124,15 +126,13 @@ module Frise
|
|
|
124
126
|
def validate_remaining_keys(full_schema, obj, path, processed_keys)
|
|
125
127
|
expected_types = get_expected_types(full_schema)
|
|
126
128
|
if expected_types.size == 1 && expected_types[0].ancestors.member?(Enumerable)
|
|
127
|
-
hash = obj.is_a?(Hash) ? obj :
|
|
129
|
+
hash = obj.is_a?(Hash) ? obj : obj.map.with_index { |x, i| [i, x] }.to_h
|
|
128
130
|
hash.each do |key, value|
|
|
129
|
-
if full_schema[:all_keys] && !key.is_a?(Symbol)
|
|
130
|
-
validate_object(path, key, full_schema[:all_keys])
|
|
131
|
-
end
|
|
131
|
+
validate_object(path, key, full_schema[:all_keys]) if full_schema[:all_keys] && !key.is_a?(Symbol)
|
|
132
132
|
|
|
133
133
|
next if processed_keys.member? key
|
|
134
134
|
if full_schema[:all]
|
|
135
|
-
validate_object("#{path}.#{key}", value, full_schema[:all])
|
|
135
|
+
validate_object(path.empty? ? key : "#{path}.#{key}", value, full_schema[:all])
|
|
136
136
|
elsif !full_schema[:allow_unknown_keys]
|
|
137
137
|
add_validation_error(path, "unknown key: #{key}")
|
|
138
138
|
end
|
|
@@ -158,17 +158,27 @@ module Frise
|
|
|
158
158
|
def self.parse_symbols(obj)
|
|
159
159
|
case obj
|
|
160
160
|
when Array then obj.map { |e| parse_symbols(e) }
|
|
161
|
-
when Hash then
|
|
162
|
-
when String then obj.start_with?('$') ? obj[1
|
|
161
|
+
when Hash then obj.to_h { |k, v| [parse_symbols(k), parse_symbols(v)] }
|
|
162
|
+
when String then obj.start_with?('$') ? obj[1..].to_sym : obj
|
|
163
163
|
else obj
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
def self.validate_obj(config, schema, options = {})
|
|
168
|
-
validate_obj_at(config, [], schema, options)
|
|
168
|
+
validate_obj_at(config, [], schema, **options)
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
-
def self.validate_obj_at(
|
|
171
|
+
def self.validate_obj_at(
|
|
172
|
+
config,
|
|
173
|
+
at_path,
|
|
174
|
+
schema,
|
|
175
|
+
path_prefix: nil,
|
|
176
|
+
validators: nil,
|
|
177
|
+
print: nil,
|
|
178
|
+
fatal: nil,
|
|
179
|
+
raise_error: nil
|
|
180
|
+
)
|
|
181
|
+
|
|
172
182
|
schema = parse_symbols(schema)
|
|
173
183
|
at_path.reverse.each { |key| schema = { key => schema, :allow_unknown_keys => true } }
|
|
174
184
|
|
|
@@ -190,11 +200,11 @@ module Frise
|
|
|
190
200
|
end
|
|
191
201
|
|
|
192
202
|
def self.validate(config, schema_file, options = {})
|
|
193
|
-
validate_obj_at(config, [], Parser.parse(schema_file) || { allow_unknown_keys: true }, options)
|
|
203
|
+
validate_obj_at(config, [], Parser.parse(schema_file) || { allow_unknown_keys: true }, **options)
|
|
194
204
|
end
|
|
195
205
|
|
|
196
206
|
def self.validate_at(config, at_path, schema_file, options = {})
|
|
197
|
-
validate_obj_at(config, at_path, Parser.parse(schema_file) || { allow_unknown_keys: true }, options)
|
|
207
|
+
validate_obj_at(config, at_path, Parser.parse(schema_file) || { allow_unknown_keys: true }, **options)
|
|
198
208
|
end
|
|
199
209
|
end
|
|
200
210
|
|
|
@@ -204,6 +214,8 @@ module Frise
|
|
|
204
214
|
attr_reader :errors
|
|
205
215
|
|
|
206
216
|
def initialize(errors)
|
|
217
|
+
super()
|
|
218
|
+
|
|
207
219
|
@errors = errors
|
|
208
220
|
end
|
|
209
221
|
end
|
data/lib/frise/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: frise
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
autorequire:
|
|
7
|
+
- Velocidi
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-03-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|
|
@@ -30,95 +30,95 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '2.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '2.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 0
|
|
47
|
+
version: '13.0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 0
|
|
54
|
+
version: '13.0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
56
|
+
name: rspec
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '3.9'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '3.9'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: rubocop
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
75
|
+
version: '1.10'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
82
|
+
version: '1.10'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: simplecov
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- -
|
|
87
|
+
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.
|
|
89
|
+
version: '0.18'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- -
|
|
94
|
+
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 0.
|
|
96
|
+
version: '0.18'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: simplecov
|
|
98
|
+
name: simplecov-lcov
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- -
|
|
101
|
+
- - '='
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 0.
|
|
103
|
+
version: 0.8.0
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- -
|
|
108
|
+
- - '='
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 0.
|
|
111
|
-
description:
|
|
110
|
+
version: 0.8.0
|
|
111
|
+
description:
|
|
112
112
|
email:
|
|
113
|
-
-
|
|
113
|
+
- hello@velocidi.com
|
|
114
114
|
executables: []
|
|
115
115
|
extensions: []
|
|
116
116
|
extra_rdoc_files: []
|
|
117
117
|
files:
|
|
118
|
+
- ".github/workflows/CI.yml"
|
|
118
119
|
- ".gitignore"
|
|
119
120
|
- ".rspec"
|
|
120
121
|
- ".rubocop.yml"
|
|
121
|
-
- ".travis.yml"
|
|
122
122
|
- CHANGELOG.md
|
|
123
123
|
- Gemfile
|
|
124
124
|
- LICENSE.txt
|
|
@@ -132,11 +132,12 @@ files:
|
|
|
132
132
|
- lib/frise/parser.rb
|
|
133
133
|
- lib/frise/validator.rb
|
|
134
134
|
- lib/frise/version.rb
|
|
135
|
-
homepage: https://github.com/
|
|
135
|
+
homepage: https://github.com/velocidi/frise
|
|
136
136
|
licenses:
|
|
137
137
|
- Apache-2.0
|
|
138
|
-
metadata:
|
|
139
|
-
|
|
138
|
+
metadata:
|
|
139
|
+
rubygems_mfa_required: 'true'
|
|
140
|
+
post_install_message:
|
|
140
141
|
rdoc_options: []
|
|
141
142
|
require_paths:
|
|
142
143
|
- lib
|
|
@@ -144,16 +145,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
144
145
|
requirements:
|
|
145
146
|
- - ">="
|
|
146
147
|
- !ruby/object:Gem::Version
|
|
147
|
-
version: 2.
|
|
148
|
+
version: 2.6.0
|
|
148
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
150
|
requirements:
|
|
150
151
|
- - ">="
|
|
151
152
|
- !ruby/object:Gem::Version
|
|
152
153
|
version: '0'
|
|
153
154
|
requirements: []
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
signing_key:
|
|
155
|
+
rubygems_version: 3.3.7
|
|
156
|
+
signing_key:
|
|
157
157
|
specification_version: 4
|
|
158
158
|
summary: Ruby config library with schema validation, default values and templating
|
|
159
159
|
test_files: []
|