ravioli 0.1.0 → 0.1.2
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/README.md +16 -16
- data/lib/ravioli.rb +23 -15
- data/lib/ravioli/builder.rb +110 -17
- data/lib/ravioli/configuration.rb +10 -7
- data/lib/ravioli/engine.rb +6 -4
- data/lib/ravioli/version.rb +1 -1
- metadata +67 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92bc88993084463bb740d10f3b95d4282c083e492db56deb6326c37718cc6f94
|
4
|
+
data.tar.gz: 077a5e8070664163c4f8508a9c2e1d7850d8241a4c96ad3b58a716ec9f0b98f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba40d1bbfc6a08e842577f746a7ac21b17aaa94824dfe0dcd1b6aa86b23868f99bcad55c05a5bcb8dff1448249bf6ca797e84a54eec1f8004cc47be4c57a5019
|
7
|
+
data.tar.gz: 6cb087130e095129930d2ec12d0b9505adae10e0d8838cd60d06db5b61ca6d3d3b164fcc1a2f8299b65be5083d2479b39693c9ceb9d5540b05a398d6826129c0
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ key = Rails.config.dig!(:thing, :api_key)
|
|
35
35
|
-->
|
36
36
|
1. Add `gem "ravioli"` to your `Gemfile`
|
37
37
|
2. Run `bundle install`
|
38
|
-
3. Add an initializer (totally optional): `rails generate ravioli:install` - Ravioli will do **everything** automatically for you if you skip this step, because I
|
38
|
+
3. Add an initializer (totally optional): `rails generate ravioli:install` - Ravioli will do **everything** automatically for you if you skip this step, because I'm here to put a little meat on your bones.
|
39
39
|
|
40
40
|
## Usage
|
41
41
|
|
@@ -207,7 +207,7 @@ mailjet:
|
|
207
207
|
# ...the contents of mailjet.json
|
208
208
|
```
|
209
209
|
|
210
|
-
**NOTE THAT APP.YML GOT LOADED INTO THE ROOT OF THE CONFIGURATION!** This is because the automatic loading system assumes you want some configuration values that aren't nested. It effectively calls [`
|
210
|
+
**NOTE THAT APP.YML GOT LOADED INTO THE ROOT OF THE CONFIGURATION!** This is because the automatic loading system assumes you want some configuration values that aren't nested. It effectively calls [`load_file(filename, key: File.basename(filename) != "app")`](#load_file), which ensures that, for example, the values in `config/mailjet.json` get loaded under `Rails.config.mailjet` while the valuaes in `config/app.yml` get loaded directly into `Rails.config`.
|
211
211
|
|
212
212
|
### 3. Loads and combines encrypted credentials
|
213
213
|
|
@@ -225,7 +225,7 @@ This allows you to use your secure credentials stores without duplicating inform
|
|
225
225
|
def Rails.config
|
226
226
|
@config ||= Ravioli.build(strict: Rails.env.production?) do |config|
|
227
227
|
config.add_staging_flag!
|
228
|
-
config.
|
228
|
+
config.auto_load_files!
|
229
229
|
config.auto_load_credentials!
|
230
230
|
end
|
231
231
|
end
|
@@ -243,16 +243,16 @@ The best way to build your own configuration is by calling `Ravioli.build`. It w
|
|
243
243
|
|
244
244
|
```ruby
|
245
245
|
configuration = Ravioli.build do |config|
|
246
|
-
config.
|
246
|
+
config.load_file("things.yml")
|
247
247
|
config.whatever = {things: true}
|
248
248
|
end
|
249
249
|
```
|
250
250
|
|
251
|
-
This will
|
251
|
+
This will return a configured instance of `Ravioli::Configuration` with structure
|
252
252
|
|
253
253
|
```yaml
|
254
|
-
|
255
|
-
# ...the contents of
|
254
|
+
things:
|
255
|
+
# ...the contents of things.yml
|
256
256
|
whatever:
|
257
257
|
things: true
|
258
258
|
```
|
@@ -303,7 +303,7 @@ end
|
|
303
303
|
### `add_staging_flag!`
|
304
304
|
|
305
305
|
|
306
|
-
### `
|
306
|
+
### `load_file`
|
307
307
|
|
308
308
|
Let's imagine we have this config file:
|
309
309
|
|
@@ -329,24 +329,24 @@ In an initializer, generate your Ravioli instance and load it up:
|
|
329
329
|
```ruby
|
330
330
|
# config/initializers/_ravioli.rb`
|
331
331
|
Config = Ravioli.build do
|
332
|
-
|
333
|
-
|
334
|
-
|
332
|
+
load_file(:mailjet) # given a symbol, it automatically assumes you meant `config/mailjet.yml`
|
333
|
+
load_file("config/mailjet") # same as above
|
334
|
+
load_file("lib/mailjet/config") # looks for `Rails.root.join("lib", "mailjet", "config.yml")
|
335
335
|
end
|
336
336
|
```
|
337
337
|
|
338
338
|
`config/initializers/_ravioli.rb`
|
339
339
|
|
340
340
|
```ruby
|
341
|
-
Config = Ravioli.build do
|
341
|
+
Config = Ravioli.build do |config|
|
342
342
|
%i[new_relic sentry google].each do |service|
|
343
|
-
|
343
|
+
config.load_file(service)
|
344
344
|
end
|
345
345
|
|
346
|
-
load_credentials # just load the base credentials file
|
347
|
-
load_credentials("credentials/production") if Rails.env.production? # add production overrides when appropriate
|
346
|
+
config.load_credentials # just load the base credentials file
|
347
|
+
config.load_credentials("credentials/production") if Rails.env.production? # add production overrides when appropriate
|
348
348
|
|
349
|
-
|
349
|
+
config.staging = File.exists?("./staging.txt") # technically you could do this ... I don't know why you would, but technically you could
|
350
350
|
end
|
351
351
|
```
|
352
352
|
|
data/lib/ravioli.rb
CHANGED
@@ -7,28 +7,36 @@ require_relative "ravioli/builder"
|
|
7
7
|
require_relative "ravioli/configuration"
|
8
8
|
require_relative "ravioli/version"
|
9
9
|
|
10
|
-
|
11
|
-
#
|
12
|
-
# as the Builder class for help loading configuration files and encrypted credentials
|
10
|
+
# The root namespace for all of Ravioli, and owner of two handly
|
11
|
+
# configuration-related class methods
|
13
12
|
module Ravioli
|
14
|
-
NAME = "Ravioli"
|
15
|
-
|
16
13
|
class << self
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
# Forwards arguments to a {Ravioli::Builder}. See
|
15
|
+
# {Ravioli::Builder#new} for complete documentation.
|
16
|
+
#
|
17
|
+
# @param namespace [String, Module, Class] the name of, or a direct reference to, the module or class your Configuration class should namespace itself within
|
18
|
+
# @param class_name [String] the name of the namespace's Configuration class
|
19
|
+
# @param strict [boolean] whether or not the Builder instance should throw errors when there are errors loading configuration files or encrypted credentials
|
20
|
+
def build(namespace: nil, class_name: "Configuration", strict: false, &block)
|
21
|
+
builder = Builder.new(
|
22
|
+
class_name: class_name,
|
23
|
+
hijack: true,
|
24
|
+
namespace: namespace,
|
25
|
+
strict: strict,
|
26
|
+
)
|
27
|
+
yield builder if block
|
28
|
+
builder.build!
|
27
29
|
end
|
28
30
|
|
31
|
+
# Returns a list of all of the configuration instances
|
29
32
|
def configurations
|
30
33
|
@configurations ||= []
|
31
34
|
end
|
35
|
+
|
36
|
+
# Returns the most-recently configured Ravioli instance that has been built with {Ravioli::build}.
|
37
|
+
def default
|
38
|
+
configurations.last
|
39
|
+
end
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
data/lib/ravioli/builder.rb
CHANGED
@@ -1,18 +1,60 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/all"
|
4
|
+
require "erb"
|
4
5
|
require_relative "configuration"
|
5
6
|
|
6
7
|
module Ravioli
|
7
|
-
# The Builder
|
8
|
+
# The Builder class provides a simple interface for building a Ravioli configuration. It has
|
8
9
|
# methods for loading configuration files and encrypted credentials, and forwards direct
|
9
10
|
# configuration on to the configuration instance. This allows us to keep a clean separation of
|
10
11
|
# concerns (builder: loads configuration details; configuration: provides access to information
|
11
12
|
# in memory).
|
13
|
+
#
|
14
|
+
# == ENV variables and encrypted credentials keys
|
15
|
+
#
|
16
|
+
# <table><thead><tr><th>File</th><th>First it tries...</th><th>Then it tries...</th></tr></thead><tbody><tr><td>
|
17
|
+
#
|
18
|
+
# `config/credentials.yml.enc`
|
19
|
+
#
|
20
|
+
# </td><td>
|
21
|
+
#
|
22
|
+
# `ENV["RAILS_BASE_KEY"]`
|
23
|
+
#
|
24
|
+
# </td><td>
|
25
|
+
#
|
26
|
+
# `ENV["RAILS_MASTER_KEY"]`
|
27
|
+
#
|
28
|
+
# </td></tr><tr><td>
|
29
|
+
#
|
30
|
+
# `config/credentials/production.yml.enc`
|
31
|
+
|
32
|
+
# </td><td>
|
33
|
+
#
|
34
|
+
# `ENV["RAILS_PRODUCTION_KEY"]`
|
35
|
+
#
|
36
|
+
# </td><td>
|
37
|
+
#
|
38
|
+
# `ENV["RAILS_MASTER_KEY"]`
|
39
|
+
#
|
40
|
+
# </td></tr><tr><td>
|
41
|
+
#
|
42
|
+
# `config/credentials/staging.yml.enc` (only if running on staging)
|
43
|
+
#
|
44
|
+
# </td><td>
|
45
|
+
#
|
46
|
+
# `ENV["RAILS_STAGING_KEY"]`
|
47
|
+
#
|
48
|
+
# </td><td>
|
49
|
+
#
|
50
|
+
# `ENV["RAILS_MASTER_KEY"]`
|
51
|
+
#
|
52
|
+
# </td></tr></tbody></table>
|
12
53
|
class Builder
|
13
|
-
def initialize(class_name: "Configuration", namespace: nil, strict: false)
|
54
|
+
def initialize(class_name: "Configuration", hijack: false, namespace: nil, strict: false)
|
14
55
|
configuration_class = if namespace.present?
|
15
56
|
namespace.class_eval <<-EOC, __FILE__, __LINE__ + 1
|
57
|
+
# class Configuration < Ravioli::Configuration; end
|
16
58
|
class #{class_name.to_s.classify} < Ravioli::Configuration; end
|
17
59
|
EOC
|
18
60
|
namespace.const_get(class_name)
|
@@ -21,10 +63,23 @@ module Ravioli
|
|
21
63
|
end
|
22
64
|
@strict = !!strict
|
23
65
|
@configuration = configuration_class.new
|
66
|
+
@reload_credentials = Set.new
|
67
|
+
@reload_paths = Set.new
|
68
|
+
@hijack = !!hijack
|
69
|
+
|
70
|
+
if @hijack
|
71
|
+
# Put this builder on the configurations stack - it will intercept setters on the underyling
|
72
|
+
# configuration object as it loads files, and mark those files as needing a reload once
|
73
|
+
# loading is complete
|
74
|
+
Ravioli.configurations.push(self)
|
75
|
+
end
|
24
76
|
end
|
25
77
|
|
26
|
-
# Automatically infer a `staging
|
78
|
+
# Automatically infer a `staging` status from the current environment
|
79
|
+
#
|
80
|
+
# @param is_staging [boolean, #present?] whether or not the current environment is considered a staging environment
|
27
81
|
def add_staging_flag!(is_staging = Rails.env.production? && ENV["STAGING"].present?)
|
82
|
+
is_staging = is_staging.present?
|
28
83
|
configuration.staging = is_staging
|
29
84
|
Rails.env.class_eval <<-EOC, __FILE__, __LINE__ + 1
|
30
85
|
def staging?
|
@@ -37,15 +92,17 @@ module Ravioli
|
|
37
92
|
is_staging
|
38
93
|
end
|
39
94
|
|
40
|
-
#
|
41
|
-
|
95
|
+
# Iterates through the config directory (including nested folders) and
|
96
|
+
# calls {Ravioli::Builder::load_file} on each JSON or YAML file it
|
97
|
+
# finds. Ignores `config/locales`.
|
98
|
+
def auto_load_files!
|
42
99
|
config_dir = Rails.root.join("config")
|
43
100
|
Dir[config_dir.join("{[!locales/]**/*,*}.{json,yaml,yml}")].each do |config_file|
|
44
|
-
|
101
|
+
auto_load_file(config_file)
|
45
102
|
end
|
46
103
|
end
|
47
104
|
|
48
|
-
#
|
105
|
+
# Loads Rails encrypted credentials that it can. Checks for corresponding private key files, or ENV vars based on the {Ravioli::Builder credentials preadmlogic}
|
49
106
|
def auto_load_credentials!
|
50
107
|
# Load the base config
|
51
108
|
load_credentials(key_path: "config/master.key", env_name: "base")
|
@@ -59,11 +116,23 @@ module Ravioli
|
|
59
116
|
|
60
117
|
# When the builder is done working, lock the configuration and return it
|
61
118
|
def build!
|
119
|
+
if @hijack
|
120
|
+
# Replace this builder with the underlying configuration on the configurations stack...
|
121
|
+
Ravioli.configurations.delete(self)
|
122
|
+
Ravioli.configurations.push(configuration)
|
123
|
+
|
124
|
+
# ...and then reload any config file that referenced the configuration the first time it was
|
125
|
+
# loaded!
|
126
|
+
@reload_paths.each do |path|
|
127
|
+
auto_load_file(path)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
62
131
|
configuration.freeze
|
63
132
|
end
|
64
133
|
|
65
|
-
# Load a
|
66
|
-
def
|
134
|
+
# Load a file either with a given path or by name (e.g. `config/whatever.yml` or `:whatever`)
|
135
|
+
def load_file(path, options = {})
|
67
136
|
config = parse_config_file(path, options)
|
68
137
|
configuration.append(config) if config.present?
|
69
138
|
rescue => error
|
@@ -75,7 +144,7 @@ module Ravioli
|
|
75
144
|
credentials = parse_credentials(path, env_name: env_name, key_path: key_path)
|
76
145
|
configuration.append(credentials) if credentials.present?
|
77
146
|
rescue => error
|
78
|
-
warn "Could not decrypt `#{path}.yml.enc' with key file `#{key_path}' or `ENV[\"#{env_name}\"]'", error
|
147
|
+
warn "Could not decrypt `#{path}.yml.enc' with key file `#{key_path}' or `ENV[\"#{env_name}\"]'", error, critical: false
|
79
148
|
{}
|
80
149
|
end
|
81
150
|
|
@@ -86,6 +155,13 @@ module Ravioli
|
|
86
155
|
|
87
156
|
attr_reader :configuration
|
88
157
|
|
158
|
+
def auto_load_file(config_file)
|
159
|
+
basename = File.basename(config_file, File.extname(config_file))
|
160
|
+
dirname = File.dirname(config_file)
|
161
|
+
key = %w[app application].exclude?(basename) && dirname != config_dir
|
162
|
+
load_file(config_file, key: key)
|
163
|
+
end
|
164
|
+
|
89
165
|
def extract_environmental_config(config)
|
90
166
|
# Check if the config hash is keyed by environment - if not, just return it as-is. It's
|
91
167
|
# considered "keyed by environment" if it contains ONLY env-specific keys.
|
@@ -105,12 +181,23 @@ module Ravioli
|
|
105
181
|
# rubocop:disable Style/MethodMissingSuper
|
106
182
|
# rubocop:disable Style/MissingRespondToMissing
|
107
183
|
def method_missing(*args, &block)
|
184
|
+
if @current_path
|
185
|
+
@reload_paths.add(@current_path)
|
186
|
+
end
|
187
|
+
|
188
|
+
if @current_credentials
|
189
|
+
@reload_credentials.add(@current_credentials)
|
190
|
+
end
|
191
|
+
|
108
192
|
configuration.send(*args, &block)
|
109
193
|
end
|
110
194
|
# rubocop:enable Style/MissingRespondToMissing
|
111
195
|
# rubocop:enable Style/MethodMissingSuper
|
112
196
|
|
113
197
|
def parse_config_file(path, options = {})
|
198
|
+
# Stash a reference to the file we're parsing, so we can reload it later if it tries to use
|
199
|
+
# the configuration object
|
200
|
+
@current_path = path
|
114
201
|
path = path_to_config_file_path(path)
|
115
202
|
|
116
203
|
config = case path.extname.downcase
|
@@ -119,9 +206,11 @@ module Ravioli
|
|
119
206
|
when ".yml", ".yaml"
|
120
207
|
parse_yaml_config_file(path)
|
121
208
|
else
|
122
|
-
raise ParseError.new("
|
209
|
+
raise ParseError.new("Ravioli doesn't know how to parse #{path}")
|
123
210
|
end
|
124
211
|
|
212
|
+
# We are no longer loading anything
|
213
|
+
@current_path = nil
|
125
214
|
# At least expect a hash to be returned from the loaded config file
|
126
215
|
return {} unless config.is_a?(Hash)
|
127
216
|
|
@@ -145,6 +234,7 @@ module Ravioli
|
|
145
234
|
end
|
146
235
|
|
147
236
|
def parse_credentials(path, key_path: path, env_name: path.split("/").last)
|
237
|
+
@current_credentials = path
|
148
238
|
env_name = env_name.to_s
|
149
239
|
env_name = "RAILS_#{env_name.upcase}_KEY" unless env_name.upcase == env_name
|
150
240
|
key_path = path_to_config_file_path(key_path, extnames: "key", quiet: true)
|
@@ -152,8 +242,9 @@ module Ravioli
|
|
152
242
|
options[:env_key] = ENV[env_name].present? ? env_name : SecureRandom.hex(6)
|
153
243
|
|
154
244
|
path = path_to_config_file_path(path, extnames: "yml.enc")
|
155
|
-
|
156
|
-
|
245
|
+
(Rails.application.encrypted(path, **options)&.config || {}).tap do
|
246
|
+
@current_credentials = nil
|
247
|
+
end
|
157
248
|
end
|
158
249
|
|
159
250
|
def parse_json_config_file(path)
|
@@ -162,7 +253,6 @@ module Ravioli
|
|
162
253
|
end
|
163
254
|
|
164
255
|
def parse_yaml_config_file(path)
|
165
|
-
require "erb"
|
166
256
|
contents = File.read(path)
|
167
257
|
erb = ERB.new(contents).tap { |renderer| renderer.filename = path.to_s }
|
168
258
|
YAML.safe_load(erb.result, aliases: true)
|
@@ -192,10 +282,10 @@ module Ravioli
|
|
192
282
|
path
|
193
283
|
end
|
194
284
|
|
195
|
-
def warn(message, error =
|
196
|
-
message = "[
|
285
|
+
def warn(message, error = $!, critical: true)
|
286
|
+
message = "[Ravioli] #{message}"
|
197
287
|
message = "#{message}:\n\n#{error.cause.inspect}" if error&.cause.present?
|
198
|
-
if @strict
|
288
|
+
if @strict && critical
|
199
289
|
raise BuildError.new(message, error)
|
200
290
|
else
|
201
291
|
Rails.logger.warn(message) if defined? Rails
|
@@ -204,6 +294,7 @@ module Ravioli
|
|
204
294
|
end
|
205
295
|
end
|
206
296
|
|
297
|
+
# Error raised when Ravioli is in strict mode. Includes the original error for context.
|
207
298
|
class BuildError < StandardError
|
208
299
|
def initialize(message, cause = nil)
|
209
300
|
super message
|
@@ -214,5 +305,7 @@ module Ravioli
|
|
214
305
|
@cause || super
|
215
306
|
end
|
216
307
|
end
|
308
|
+
|
309
|
+
# Error raised when Ravioli encounters a problem parsing a file
|
217
310
|
class ParseError < StandardError; end
|
218
311
|
end
|
@@ -5,20 +5,17 @@ require "ostruct"
|
|
5
5
|
|
6
6
|
module Ravioli
|
7
7
|
class Configuration < OpenStruct
|
8
|
-
attr_reader :key_path
|
9
|
-
|
10
8
|
def initialize(attributes = {})
|
11
9
|
super({})
|
12
10
|
@key_path = attributes.delete(:key_path)
|
13
11
|
append(attributes)
|
14
12
|
end
|
15
13
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# end
|
20
|
-
|
14
|
+
# Convert a hash to accessors and nested {Ravioli::Configuration} instances.
|
15
|
+
#
|
16
|
+
# @param [Hash, #each] key-value pairs to be converted to accessors
|
21
17
|
def append(attributes = {})
|
18
|
+
return unless attributes.respond_to?(:each)
|
22
19
|
attributes.each do |key, value|
|
23
20
|
self[key.to_sym] = cast(key.to_sym, value)
|
24
21
|
end
|
@@ -40,6 +37,10 @@ module Ravioli
|
|
40
37
|
fetch(*keys) { raise KeyMissingError.new("Could not find value at key path #{keys.inspect}") }
|
41
38
|
end
|
42
39
|
|
40
|
+
def delete(key)
|
41
|
+
table.delete(key.to_s)
|
42
|
+
end
|
43
|
+
|
43
44
|
def fetch(*keys)
|
44
45
|
dig(*keys) || yield
|
45
46
|
end
|
@@ -54,6 +55,8 @@ module Ravioli
|
|
54
55
|
|
55
56
|
private
|
56
57
|
|
58
|
+
attr_reader :key_path
|
59
|
+
|
57
60
|
def build(keys, attributes = {})
|
58
61
|
attributes[:key_path] = key_path_for(keys)
|
59
62
|
child = self.class.new(attributes)
|
data/lib/ravioli/engine.rb
CHANGED
@@ -3,16 +3,18 @@
|
|
3
3
|
module Ravioli
|
4
4
|
class Engine < ::Rails::Engine
|
5
5
|
# Bootstrap Ravioli onto the Rails app
|
6
|
-
initializer "ravioli", before:
|
7
|
-
Rails.extend Ravioli::
|
6
|
+
initializer "ravioli", before: :load_environment_config do |app|
|
7
|
+
Rails.extend Ravioli::RailsConfig unless Rails.respond_to?(:config)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
private
|
12
|
+
|
13
|
+
module RailsConfig
|
12
14
|
def config
|
13
15
|
Ravioli.default || Ravioli.build(namespace: Rails.application&.class&.module_parent, strict: Rails.env.production?) do |config|
|
14
16
|
config.add_staging_flag!
|
15
|
-
config.
|
17
|
+
config.auto_load_files!
|
16
18
|
config.auto_load_credentials!
|
17
19
|
end
|
18
20
|
end
|
data/lib/ravioli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ravioli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Flip Sasser
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,6 +30,48 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 6.0.3.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: guard
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: guard-rubocop
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
33
75
|
- !ruby/object:Gem::Dependency
|
34
76
|
name: pry
|
35
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,16 +132,16 @@ dependencies:
|
|
90
132
|
name: rubocop
|
91
133
|
requirement: !ruby/object:Gem::Requirement
|
92
134
|
requirements:
|
93
|
-
- - "
|
135
|
+
- - ">="
|
94
136
|
- !ruby/object:Gem::Version
|
95
|
-
version: '0
|
137
|
+
version: '1.0'
|
96
138
|
type: :development
|
97
139
|
prerelease: false
|
98
140
|
version_requirements: !ruby/object:Gem::Requirement
|
99
141
|
requirements:
|
100
|
-
- - "
|
142
|
+
- - ">="
|
101
143
|
- !ruby/object:Gem::Version
|
102
|
-
version: '0
|
144
|
+
version: '1.0'
|
103
145
|
- !ruby/object:Gem::Dependency
|
104
146
|
name: rubocop-ordered_methods
|
105
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,44 +160,44 @@ dependencies:
|
|
118
160
|
name: rubocop-performance
|
119
161
|
requirement: !ruby/object:Gem::Requirement
|
120
162
|
requirements:
|
121
|
-
- - "
|
163
|
+
- - ">="
|
122
164
|
- !ruby/object:Gem::Version
|
123
|
-
version: 1.5
|
165
|
+
version: '1.5'
|
124
166
|
type: :development
|
125
167
|
prerelease: false
|
126
168
|
version_requirements: !ruby/object:Gem::Requirement
|
127
169
|
requirements:
|
128
|
-
- - "
|
170
|
+
- - ">="
|
129
171
|
- !ruby/object:Gem::Version
|
130
|
-
version: 1.5
|
172
|
+
version: '1.5'
|
131
173
|
- !ruby/object:Gem::Dependency
|
132
174
|
name: rubocop-rails
|
133
175
|
requirement: !ruby/object:Gem::Requirement
|
134
176
|
requirements:
|
135
|
-
- - "
|
177
|
+
- - ">="
|
136
178
|
- !ruby/object:Gem::Version
|
137
|
-
version: 2.5.
|
179
|
+
version: 2.5.0
|
138
180
|
type: :development
|
139
181
|
prerelease: false
|
140
182
|
version_requirements: !ruby/object:Gem::Requirement
|
141
183
|
requirements:
|
142
|
-
- - "
|
184
|
+
- - ">="
|
143
185
|
- !ruby/object:Gem::Version
|
144
|
-
version: 2.5.
|
186
|
+
version: 2.5.0
|
145
187
|
- !ruby/object:Gem::Dependency
|
146
188
|
name: rubocop-rspec
|
147
189
|
requirement: !ruby/object:Gem::Requirement
|
148
190
|
requirements:
|
149
|
-
- - "
|
191
|
+
- - ">="
|
150
192
|
- !ruby/object:Gem::Version
|
151
|
-
version: '
|
193
|
+
version: '2.0'
|
152
194
|
type: :development
|
153
195
|
prerelease: false
|
154
196
|
version_requirements: !ruby/object:Gem::Requirement
|
155
197
|
requirements:
|
156
|
-
- - "
|
198
|
+
- - ">="
|
157
199
|
- !ruby/object:Gem::Version
|
158
|
-
version: '
|
200
|
+
version: '2.0'
|
159
201
|
- !ruby/object:Gem::Dependency
|
160
202
|
name: simplecov
|
161
203
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,14 +232,14 @@ dependencies:
|
|
190
232
|
requirements:
|
191
233
|
- - "~>"
|
192
234
|
- !ruby/object:Gem::Version
|
193
|
-
version:
|
235
|
+
version: 0.13.0
|
194
236
|
type: :development
|
195
237
|
prerelease: false
|
196
238
|
version_requirements: !ruby/object:Gem::Requirement
|
197
239
|
requirements:
|
198
240
|
- - "~>"
|
199
241
|
- !ruby/object:Gem::Version
|
200
|
-
version:
|
242
|
+
version: 0.13.0
|
201
243
|
- !ruby/object:Gem::Dependency
|
202
244
|
name: yard
|
203
245
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,7 +278,7 @@ licenses:
|
|
236
278
|
metadata:
|
237
279
|
homepage_uri: https://github.com/flipsasser/ravioli
|
238
280
|
source_code_uri: https://github.com/flipsasser/ravioli
|
239
|
-
post_install_message:
|
281
|
+
post_install_message:
|
240
282
|
rdoc_options: []
|
241
283
|
require_paths:
|
242
284
|
- lib
|
@@ -244,15 +286,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
244
286
|
requirements:
|
245
287
|
- - ">="
|
246
288
|
- !ruby/object:Gem::Version
|
247
|
-
version: 2.
|
289
|
+
version: 2.4.0
|
248
290
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
249
291
|
requirements:
|
250
292
|
- - ">="
|
251
293
|
- !ruby/object:Gem::Version
|
252
294
|
version: '0'
|
253
295
|
requirements: []
|
254
|
-
rubygems_version: 3.
|
255
|
-
signing_key:
|
296
|
+
rubygems_version: 3.2.3
|
297
|
+
signing_key:
|
256
298
|
specification_version: 4
|
257
299
|
summary: Grab a fork and twist all your configuration spaghetti into a single, delicious
|
258
300
|
bundle
|