frise 0.3.0.pre → 0.3.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 +17 -2
- data/README.md +12 -19
- data/frise.gemspec +2 -2
- data/lib/frise/defaults_loader.rb +56 -48
- data/lib/frise/loader.rb +82 -24
- data/lib/frise/parser.rb +8 -3
- data/lib/frise/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5923c848338d6a2f7dfc35211200ab51a789ad9e9967742e4eb57430346785e9
|
4
|
+
data.tar.gz: e08f1fdf3a14fe288ad67a0baa6a9e557294de9ac5ea814426e9b92792b1be95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a578f2042b86832986bed1cecbe435330e509e2f6f166ff7302c3eeca37e445bc7acbbcbd4fe16d3cf9c23be68603cd9d4e13f17c508edaeff5e96169b41eaa9
|
7
|
+
data.tar.gz: 1c4378dcec5e8738f25248d6a45fcc96b4392f7144995e08d57407abd3bf1ad5bfe506fe6e1117aa4caef7900dcedfba9dc8b4267b1c4cd6d273c5395313cd2f
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,26 @@
|
|
1
|
+
### 0.3.0 (April 16, 2018)
|
2
|
+
|
3
|
+
- Breaking changes
|
4
|
+
- Defaults and schemas are now defined using a directive in the YAML configs instead of
|
5
|
+
implicitly by looking at load paths. See ([#7](https://github.com/velocidi/frise/pull/7)) for
|
6
|
+
more information on migration;
|
7
|
+
- New features
|
8
|
+
- `$include` and `$schema` directives are now available in config files, allowing users to
|
9
|
+
validate and include defaults at any part of the config
|
10
|
+
([#7](https://github.com/velocidi/frise/pull/7));
|
11
|
+
- A new `$content_include` directive allows users to include the content of a file as a YAML
|
12
|
+
string ([#8](https://github.com/velocidi/frise/pull/8));
|
13
|
+
- The `_file_dir` Liquid variable is now available in all included files, containing always the
|
14
|
+
absolute path to the file being loaded ([#7](https://github.com/velocidi/frise/pull/7)).
|
15
|
+
|
1
16
|
### 0.2.0 (August 17, 2017)
|
2
17
|
|
3
18
|
- New features
|
4
19
|
- New schema types `$enum` and `$one_of` for specifying enumerations and values with multiple
|
5
|
-
possible schemas ([#5](https://github.com/
|
20
|
+
possible schemas ([#5](https://github.com/velocidi/frise/pull/5)).
|
6
21
|
- Bug fixes
|
7
22
|
- Deal correctly with non-existing schema files in the load path
|
8
|
-
([#4](https://github.com/
|
23
|
+
([#4](https://github.com/velocidi/frise/pull/4)).
|
9
24
|
|
10
25
|
### 0.1.0 (August 10, 2017)
|
11
26
|
|
data/README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# Frise
|
2
|
-
[![Build Status](https://travis-ci.org/
|
3
|
-
[![Coverage Status](https://coveralls.io/repos/github/
|
2
|
+
[![Build Status](https://travis-ci.org/velocidi/frise.svg?branch=master)](https://travis-ci.org/velocidi/frise)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/github/velocidi/frise/badge.svg?branch=master)](https://coveralls.io/github/velocidi/frise?branch=master)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/frise.svg)](https://badge.fury.io/rb/frise)
|
5
5
|
|
6
6
|
Frise is a library for loading configuration files as native Ruby structures. Besides reading and
|
7
7
|
parsing the files themselves, it also:
|
8
8
|
|
9
|
-
-
|
9
|
+
- Allows defining other files to be merged anywhere in the config, which can be used to provide default values specified
|
10
|
+
in another file or set of files;
|
10
11
|
- Interprets [Liquid](https://shopify.github.io/liquid) templates in configs and defaults;
|
11
12
|
- Validates the loaded config according to a schema file or set of files.
|
12
13
|
|
@@ -24,7 +25,6 @@ The simplest example would be to load [a simple configuration](example/config.ym
|
|
24
25
|
|
25
26
|
```ruby
|
26
27
|
require 'frise'
|
27
|
-
require 'pp'
|
28
28
|
|
29
29
|
loader = Frise::Loader.new
|
30
30
|
loader.load('example/config.yml')
|
@@ -44,12 +44,11 @@ Currently Frise only supports YAML files, but it may support JSON and other form
|
|
44
44
|
|
45
45
|
### Default values
|
46
46
|
|
47
|
-
By
|
48
|
-
[example/_defaults](example/_defaults)), Frise can handle its application internally on load time:
|
47
|
+
By using the `$include` directive pointing to the files where default values can be found (in this example,
|
48
|
+
[example/_defaults/config.yml](example/_defaults/config.yml)), Frise can handle its application internally on load time:
|
49
49
|
|
50
50
|
```ruby
|
51
|
-
loader
|
52
|
-
loader.load('example/config.yml')
|
51
|
+
loader.load('example/config_with_defaults.yml')
|
53
52
|
# => {"movies"=>
|
54
53
|
# [{"title"=>"The Shawshank Redemption",
|
55
54
|
# "year"=>1994,
|
@@ -75,15 +74,11 @@ config.
|
|
75
74
|
### Schemas
|
76
75
|
|
77
76
|
Additionally, configuration files can also be validated against a schema. By specifying
|
78
|
-
`
|
79
|
-
[example/_schemas/config.yml](example/_schemas/config.yml)
|
77
|
+
`$schema` in the config, users can provide schema files such as
|
78
|
+
[example/_schemas/config.yml](example/_schemas/config.yml):
|
80
79
|
|
81
80
|
```ruby
|
82
|
-
loader
|
83
|
-
schema_load_paths: ['example/_schemas'],
|
84
|
-
defaults_load_paths: ['example/_defaults'])
|
85
|
-
|
86
|
-
loader.load('example/config.yml')
|
81
|
+
loader.load('example/config_with_defaults_and_schema.yml')
|
87
82
|
# {"movies"=>
|
88
83
|
# [{"title"=>"The Shawshank Redemption",
|
89
84
|
# "year"=>1994,
|
@@ -106,16 +101,14 @@ missing and Frise by default prints a summary of the errors and terminates the p
|
|
106
101
|
|
107
102
|
|
108
103
|
```ruby
|
109
|
-
loader
|
110
|
-
|
111
|
-
loader.load('example/config.yml')
|
104
|
+
loader.load('example/config_with_schema.yml')
|
112
105
|
# 2 config error(s) found:
|
113
106
|
# - At movies.0.director: missing required value
|
114
107
|
# - At ui: missing required value
|
115
108
|
```
|
116
109
|
|
117
110
|
Once more, the structure of the schema mimics the structure of the config itself, making it easy to
|
118
|
-
write schemas and
|
111
|
+
write schemas first and create a config scaffold from its schema later.
|
119
112
|
|
120
113
|
Users can check a whole range of properties in config values besides their type: optional values,
|
121
114
|
hashes with validated keys, hashes with unknown keys and even custom validations are also supported.
|
data/frise.gemspec
CHANGED
@@ -20,12 +20,12 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
spec.required_ruby_version = '>= 2.3.0'
|
22
22
|
|
23
|
-
spec.add_dependency 'liquid', '~>
|
23
|
+
spec.add_dependency 'liquid', '~> 4.0'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '~> 1.14'
|
26
26
|
spec.add_development_dependency 'coveralls', '~> 0.8.21'
|
27
27
|
spec.add_development_dependency 'rake', '~> 12.3'
|
28
28
|
spec.add_development_dependency 'rspec', '~> 3.4'
|
29
|
-
spec.add_development_dependency 'rubocop', '
|
29
|
+
spec.add_development_dependency 'rubocop', '0.55.0'
|
30
30
|
spec.add_development_dependency 'simplecov', '~> 0.14.1'
|
31
31
|
end
|
@@ -7,67 +7,75 @@ module Frise
|
|
7
7
|
#
|
8
8
|
# The merge_defaults and merge_defaults_at entrypoint methods provide ways to read files with
|
9
9
|
# defaults and apply them to configuration objects.
|
10
|
-
|
11
|
-
|
12
|
-
SYMBOLS = %w[$all $optional].freeze
|
10
|
+
class DefaultsLoader
|
11
|
+
SYMBOLS = %w[$all $optional].freeze
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
13
|
+
def initialize(include_sym: '$include', content_include_sym: '$content_include', schema_sym: '$schema')
|
14
|
+
@include_sym = include_sym
|
15
|
+
@content_include_sym = content_include_sym
|
16
|
+
@schema_sym = schema_sym
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def widened_class(obj)
|
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
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
else merge_defaults_obj({}, defaults)
|
29
|
-
end
|
27
|
+
def merge_defaults_obj(config, defaults)
|
28
|
+
config_class = widened_class(config)
|
29
|
+
defaults_class = widened_class(defaults)
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
if defaults.nil?
|
32
|
+
config
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
elsif config.nil?
|
35
|
+
if defaults_class != 'Hash' then defaults
|
36
|
+
elsif defaults['$optional'] then nil
|
37
|
+
else merge_defaults_obj({}, defaults)
|
38
|
+
end
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
(config.keys + defaults.keys).uniq.each do |key|
|
40
|
-
next if SYMBOLS.include?(key)
|
41
|
-
new_config[key] = config[key]
|
42
|
-
new_config[key] = merge_defaults_obj(new_config[key], defaults[key]) if defaults.key?(key)
|
43
|
-
new_config[key] = merge_defaults_obj(new_config[key], defaults['$all']) unless new_config[key].nil?
|
44
|
-
new_config.delete(key) if new_config[key].nil?
|
45
|
-
end
|
46
|
-
new_config
|
40
|
+
elsif defaults_class == 'Array' && config_class == 'Array'
|
41
|
+
defaults + config
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
"with default #{defaults.inspect} (#{widened_class(defaults)})"
|
43
|
+
elsif defaults_class == 'Hash' && defaults['$all'] && config_class == 'Array'
|
44
|
+
config.map { |elem| merge_defaults_obj(elem, defaults['$all']) }
|
51
45
|
|
52
|
-
|
53
|
-
|
46
|
+
elsif defaults_class == 'Hash' && config_class == 'Hash'
|
47
|
+
new_config = {}
|
48
|
+
(config.keys + defaults.keys).uniq.each do |key|
|
49
|
+
next if SYMBOLS.include?(key)
|
50
|
+
new_config[key] = config[key]
|
51
|
+
new_config[key] = merge_defaults_obj(new_config[key], defaults[key]) if defaults.key?(key)
|
52
|
+
new_config[key] = merge_defaults_obj(new_config[key], defaults['$all']) unless new_config[key].nil?
|
53
|
+
new_config.delete(key) if new_config[key].nil?
|
54
54
|
end
|
55
|
-
|
55
|
+
new_config
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
57
|
+
elsif defaults_class != config_class
|
58
|
+
raise "Cannot merge config #{config.inspect} (#{widened_class(config)}) " \
|
59
|
+
"with default #{defaults.inspect} (#{widened_class(defaults)})"
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
merge_defaults_obj(config, defaults)
|
61
|
+
else
|
62
|
+
config
|
65
63
|
end
|
64
|
+
end
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
def merge_defaults_obj_at(config, at_path, defaults)
|
67
|
+
at_path.reverse.each { |key| defaults = { key => defaults } }
|
68
|
+
merge_defaults_obj(config, defaults)
|
69
|
+
end
|
70
|
+
|
71
|
+
def merge_defaults(config, defaults_file, symbol_table = config)
|
72
|
+
defaults = Parser.parse(defaults_file, symbol_table) || {}
|
73
|
+
merge_defaults_obj(config, defaults)
|
74
|
+
end
|
75
|
+
|
76
|
+
def merge_defaults_at(config, at_path, defaults_file, symbol_table = config)
|
77
|
+
defaults = Parser.parse(defaults_file, symbol_table) || {}
|
78
|
+
merge_defaults_obj_at(config, at_path, defaults)
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
data/lib/frise/loader.rb
CHANGED
@@ -10,12 +10,25 @@ module Frise
|
|
10
10
|
#
|
11
11
|
# The load method loads a configuration file, merges the applicable includes and validates its schema.
|
12
12
|
class Loader
|
13
|
-
def initialize(include_sym: '$include',
|
13
|
+
def initialize(include_sym: '$include',
|
14
|
+
content_include_sym: '$content_include',
|
15
|
+
schema_sym: '$schema',
|
16
|
+
pre_loaders: [],
|
17
|
+
validators: nil,
|
18
|
+
exit_on_fail: true)
|
19
|
+
|
14
20
|
@include_sym = include_sym
|
21
|
+
@content_include_sym = content_include_sym
|
15
22
|
@schema_sym = schema_sym
|
16
23
|
@pre_loaders = pre_loaders
|
17
24
|
@validators = validators
|
18
25
|
@exit_on_fail = exit_on_fail
|
26
|
+
|
27
|
+
@defaults_loader = DefaultsLoader.new(
|
28
|
+
include_sym: include_sym,
|
29
|
+
content_include_sym: content_include_sym,
|
30
|
+
schema_sym: schema_sym
|
31
|
+
)
|
19
32
|
end
|
20
33
|
|
21
34
|
def load(config_file, global_vars = {})
|
@@ -36,35 +49,49 @@ module Frise
|
|
36
49
|
def process_includes(config, at_path, root_config, global_vars)
|
37
50
|
return config unless config.class == Hash
|
38
51
|
|
39
|
-
|
40
|
-
|
52
|
+
# process $content_include directives
|
53
|
+
config, content_include_confs = extract_content_include(config, at_path)
|
54
|
+
unless content_include_confs.empty?
|
55
|
+
raise "At #{build_path(at_path)}: a #{@content_include_sym} must not have any sibling key" unless config.empty?
|
56
|
+
|
57
|
+
content = ''
|
58
|
+
content_include_confs.each do |include_conf|
|
59
|
+
symbol_table = build_symbol_table(root_config, at_path, nil, global_vars, include_conf)
|
60
|
+
content += Parser.parse_as_text(include_conf['file'], symbol_table) || ''
|
61
|
+
end
|
62
|
+
return content
|
63
|
+
end
|
64
|
+
|
65
|
+
# process $include directives
|
66
|
+
config, include_confs = extract_include(config, at_path)
|
67
|
+
if include_confs.empty?
|
41
68
|
config.map { |k, v| [k, process_includes(v, at_path + [k], root_config, global_vars)] }.to_h
|
42
69
|
else
|
43
70
|
Lazy.new do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
symbol_table = merge_at(root_config, at_path, config)
|
48
|
-
.merge(global_vars).merge(extra_vars).merge(extra_consts).merge('_this' => config)
|
71
|
+
include_confs.each do |include_conf|
|
72
|
+
symbol_table = build_symbol_table(root_config, at_path, config, global_vars, include_conf)
|
73
|
+
included_config = Parser.parse(include_conf['file'], symbol_table)
|
49
74
|
|
50
|
-
config =
|
75
|
+
config = @defaults_loader.merge_defaults_obj(config, included_config)
|
76
|
+
config = process_includes(config, at_path, merge_at(root_config, at_path, config), global_vars)
|
51
77
|
end
|
52
|
-
|
78
|
+
updated_root_config = merge_at(root_config, at_path, config)
|
79
|
+
config.map { |k, v| [k, process_includes(v, at_path + [k], updated_root_config, global_vars)] }.to_h
|
53
80
|
end
|
54
81
|
end
|
55
82
|
end
|
56
83
|
|
57
|
-
def process_schema_includes(schema, global_vars)
|
84
|
+
def process_schema_includes(schema, at_path, global_vars)
|
58
85
|
return schema unless schema.class == Hash
|
59
86
|
|
60
|
-
schema, included_schemas = extract_include(schema)
|
87
|
+
schema, included_schemas = extract_include(schema, at_path)
|
61
88
|
if included_schemas.empty?
|
62
|
-
schema.map { |k, v| [k, process_schema_includes(v, global_vars)] }.to_h
|
89
|
+
schema.map { |k, v| [k, process_schema_includes(v, at_path + [k], global_vars)] }.to_h
|
63
90
|
else
|
64
91
|
included_schemas.each do |defaults_conf|
|
65
92
|
schema = Parser.parse(defaults_conf['file'], global_vars).merge(schema)
|
66
93
|
end
|
67
|
-
process_schema_includes(schema, global_vars)
|
94
|
+
process_schema_includes(schema, at_path, global_vars)
|
68
95
|
end
|
69
96
|
end
|
70
97
|
|
@@ -77,10 +104,10 @@ module Frise
|
|
77
104
|
[k, new_v]
|
78
105
|
end.to_h
|
79
106
|
|
80
|
-
config, schema_files = extract_schema(config)
|
107
|
+
config, schema_files = extract_schema(config, at_path)
|
81
108
|
schema_files.each do |schema_file|
|
82
109
|
schema = Parser.parse(schema_file, global_vars)
|
83
|
-
schema = process_schema_includes(schema, global_vars)
|
110
|
+
schema = process_schema_includes(schema, at_path, global_vars)
|
84
111
|
|
85
112
|
errors = Validator.validate_obj(config,
|
86
113
|
schema,
|
@@ -93,37 +120,68 @@ module Frise
|
|
93
120
|
config
|
94
121
|
end
|
95
122
|
|
96
|
-
def extract_schema(config)
|
97
|
-
extract_special(config, @schema_sym) do |value|
|
123
|
+
def extract_schema(config, at_path)
|
124
|
+
extract_special(config, @schema_sym, at_path) do |value|
|
98
125
|
case value
|
99
126
|
when String then value
|
100
|
-
else raise "
|
127
|
+
else raise "At #{build_path(at_path)}: illegal value for a #{@schema_sym} element: #{value.inspect}"
|
101
128
|
end
|
102
129
|
end
|
103
130
|
end
|
104
131
|
|
105
|
-
def extract_include(config)
|
106
|
-
|
132
|
+
def extract_include(config, at_path)
|
133
|
+
extract_include_base(config, @include_sym, at_path)
|
134
|
+
end
|
135
|
+
|
136
|
+
def extract_content_include(config, at_path)
|
137
|
+
extract_include_base(config, @content_include_sym, at_path)
|
138
|
+
end
|
139
|
+
|
140
|
+
def extract_include_base(config, sym, at_path)
|
141
|
+
extract_special(config, sym, at_path) do |value|
|
107
142
|
case value
|
108
143
|
when Hash then value
|
109
144
|
when String then { 'file' => value }
|
110
|
-
else raise "
|
145
|
+
else raise "At #{build_path(at_path)}: illegal value for a #{sym} element: #{value.inspect}"
|
111
146
|
end
|
112
147
|
end
|
113
148
|
end
|
114
149
|
|
115
|
-
def extract_special(config, key)
|
150
|
+
def extract_special(config, key, at_path)
|
116
151
|
case config[key]
|
117
152
|
when nil then [config, []]
|
118
153
|
when Array then [config.reject { |k| k == key }, config[key].map { |e| yield e }]
|
119
|
-
else raise "
|
154
|
+
else raise "At #{build_path(at_path)}: illegal value for #{key}: #{config[key].inspect}"
|
120
155
|
end
|
121
156
|
end
|
122
157
|
|
158
|
+
# merges the `to_merge` value on `config` at path `at_path`
|
123
159
|
def merge_at(config, at_path, to_merge)
|
124
160
|
return config.merge(to_merge) if at_path.empty?
|
125
161
|
head, *tail = at_path
|
126
162
|
config.merge(head => merge_at(config[head], tail, to_merge))
|
127
163
|
end
|
164
|
+
|
165
|
+
# builds the symbol table for the Liquid renderization of a file, based on:
|
166
|
+
# - `root_config`: the root of the whole config
|
167
|
+
# - `at_path`: the current path
|
168
|
+
# - `config`: the config subtree being built
|
169
|
+
# - `global_vars`: the global variables
|
170
|
+
# - `include_conf`: the $include or $content_include configuration
|
171
|
+
def build_symbol_table(root_config, at_path, config, global_vars, include_conf)
|
172
|
+
extra_vars = (include_conf['vars'] || {}).map { |k, v| [k, root_config.dig(*v.split('.'))] }.to_h
|
173
|
+
extra_consts = include_conf['constants'] || {}
|
174
|
+
|
175
|
+
(config ? merge_at(root_config, at_path, config) : root_config)
|
176
|
+
.merge(global_vars)
|
177
|
+
.merge(extra_vars)
|
178
|
+
.merge(extra_consts)
|
179
|
+
.merge('_this' => config)
|
180
|
+
end
|
181
|
+
|
182
|
+
# builds a user-friendly string indicating a path
|
183
|
+
def build_path(at_path)
|
184
|
+
at_path.empty? ? '<root>' : at_path.join('.')
|
185
|
+
end
|
128
186
|
end
|
129
187
|
end
|
data/lib/frise/parser.rb
CHANGED
@@ -10,15 +10,20 @@ module Frise
|
|
10
10
|
class << self
|
11
11
|
def parse(file, symbol_table = nil)
|
12
12
|
return nil unless File.file? file
|
13
|
-
|
13
|
+
YAML.safe_load(parse_as_text(file, symbol_table), [], [], true) || {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_as_text(file, symbol_table = nil)
|
17
|
+
return nil unless File.file? file
|
18
|
+
content = File.read(file)
|
14
19
|
content = Liquid::Template.parse(content).render with_internal_vars(file, symbol_table) if symbol_table
|
15
|
-
|
20
|
+
content
|
16
21
|
end
|
17
22
|
|
18
23
|
private
|
19
24
|
|
20
25
|
def with_internal_vars(file, symbol_table)
|
21
|
-
symbol_table.merge('_file_dir' => File.dirname(file))
|
26
|
+
symbol_table.merge('_file_dir' => File.expand_path(File.dirname(file)))
|
22
27
|
end
|
23
28
|
end
|
24
29
|
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.3.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ShiftForward
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liquid
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '='
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.55.0
|
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.55.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,9 +147,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
147
|
version: 2.3.0
|
148
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: '0'
|
153
153
|
requirements: []
|
154
154
|
rubyforge_project:
|
155
155
|
rubygems_version: 2.7.6
|