config_file_manager 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7b201bea17abb482354c6f78d6a9d593bea969d1d9230a19f7fc4d4f57e61386
4
+ data.tar.gz: 3dfee6b8202650db06b0b16ffa9635973a7fb6296a9071401e54061af859f8c4
5
+ SHA512:
6
+ metadata.gz: 0cfe298ff1a28b1f7d1deaae12f802eb9eb2d33118c3c8aaf22b991847ed624a1684c8cd6e38a64b6d989685fa32be1406cf13ecb8e436930f3e8ea52c465672
7
+ data.tar.gz: 3d00173997bb351a91a50b0d941f11ba76078579c84b87c652b0febf358ae712971cd5c429c661036ab452b59bf030c84fb7ca6c0272e4236113998eecff0e8e
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ inherit_gem:
2
+ rubocop-espago: rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 3.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2023-08-28
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Mateusz Drewniak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,323 @@
1
+ # ConfigFileManager
2
+
3
+ This gem makes it easier to manage your configuration files in Ruby apps.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add config_file_manager
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install config_file_manager
14
+
15
+ ## Usage
16
+
17
+ This gem adds a new class `ConfigFileManager`, which helps you load and list config files and config directories.
18
+
19
+ The basic idea is that config files with sensitive information should
20
+ not be stored in git (they are often added to `.gitignore`).
21
+ This gem expects that you create dummy/example versions of config files
22
+ that are checked into git.
23
+
24
+ For example let's say that you've got a config file `foo.yml`. This file should be added to gitignore and you should create a dummy version called `foo.yml.example` that will be stored in git.
25
+
26
+ ```
27
+ config/
28
+ ├─ foo.yml -- in .gitignore
29
+ └─ foo.yml.example
30
+ ```
31
+
32
+ You can choose the suffix of the dummy file for example `foo.yml.dummy`.
33
+
34
+ ### with capistrano
35
+
36
+ You can use this gem to easily configure automatic symlinking of config files in `capistrano`.
37
+
38
+ ```rb
39
+ # config/deploy.rb
40
+
41
+ config_file_manager = ConfigFileManager.new(File.expand_path(__dir__))
42
+ set :linked_files, config_file_manager.to_relative_paths(config_file_manager.files)
43
+ ```
44
+
45
+ That way you don't have to specify the config files by hand.
46
+
47
+ ### with Rails
48
+
49
+ This gem can greatly reduce boilerplate in Rails initializers that load config files.
50
+
51
+ Create an initializer that will be executed first and creates a configured instance of `ConfigFileManager` and saves it to a constant so it can be accessed in other initializers.
52
+
53
+ ```rb
54
+ # config/initializers/0_config_file_manager.rb
55
+
56
+ CONFIG_MANAGER = ConfigFileManager.new(File.expand_path('..', __dir__), env: Rails.env)
57
+ ```
58
+
59
+ And then you can you it to conveniently load config files.
60
+
61
+ ```rb
62
+ # config/initializers/foo.rb
63
+
64
+ FOO = CONFIG_MANAGER.load_yaml('foo.yml')
65
+ ```
66
+
67
+ ### ConfigFileManager initializer
68
+
69
+ To start managing your config file you should create a new `ConfigFileManager`.
70
+
71
+ ```rb
72
+ require 'config_file_manager'
73
+
74
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
75
+ ```
76
+
77
+ The loader has one required argument `config_dir`, an absolute path
78
+ to the directory that contains your config files.
79
+
80
+ You can also specify a custom dummy file extension (by default it is `.example`).
81
+
82
+ ```rb
83
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__), example_extension: '.dummy')
84
+ ```
85
+
86
+ In this case the gem would expect something like this:
87
+
88
+ ```
89
+ config/
90
+ ├─ foo.yml -- in .gitignore
91
+ └─ foo.yml.dummy
92
+ ```
93
+
94
+ You can also specify the current environment.
95
+
96
+ ```rb
97
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__), env: 'production')
98
+ ```
99
+
100
+ ### files
101
+
102
+ This method let's you list all required config files (based on the dummy files).
103
+ Let's say that you've got a directory like this.
104
+
105
+ ```
106
+ config/
107
+ ├─ foo.yml.example
108
+ ├─ bar.txt.example
109
+ ├─ bar.txt
110
+ └─ subdir/
111
+ └─ baz.yml.example
112
+ ```
113
+
114
+ Then you could retrieve the absolute paths to all required config files (no matter if they exist or not).
115
+
116
+ ```rb
117
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
118
+ loader.files
119
+ # => ["/Users/Verseth/my_app/config/foo.yml", "/Users/Verseth/my_app/config/bar.txt", "/Users/Verseth/my_app/config/subdir/baz.yml"]
120
+ ```
121
+
122
+ ### missing_files
123
+
124
+ This method let's you list all missing config files (based on the dummy files).
125
+ Let's say that you've got a directory like this.
126
+
127
+ ```
128
+ config/
129
+ ├─ foo.yml.example
130
+ ├─ bar.txt.example
131
+ ├─ bar.txt
132
+ └─ subdir/
133
+ └─ baz.yml.example
134
+ ```
135
+
136
+ Then you could retrieve the absolute paths to all missing config files (dummy files with no real versions).
137
+
138
+ ```rb
139
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
140
+ loader.missing_files
141
+ # => ["/Users/Verseth/my_app/config/foo.yml", "/Users/Verseth/my_app/config/subdir/baz.yml"]
142
+ ```
143
+
144
+ ### create_missing_files
145
+
146
+ This method let's you create all missing config files (by copying the dummy files).
147
+
148
+ Let's say that you've got a directory like this.
149
+
150
+ ```
151
+ config/
152
+ ├─ foo.yml.example
153
+ ├─ bar.txt.example
154
+ ├─ bar.txt
155
+ └─ subdir/
156
+ └─ baz.yml.example
157
+ ```
158
+
159
+ Then you could create the missing files like so.
160
+
161
+ ```rb
162
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
163
+ loader.create_missing_files(print: true)
164
+ # == Copying missing config files ==
165
+ # copy /Users/Verseth/my_app/config/foo.yml.example
166
+ # copy /Users/Verseth/my_app/config/subdir/baz.yml.example
167
+ ```
168
+
169
+ By default no output is printed. To turn it on you must call the method
170
+ with `print: true`.
171
+
172
+ ### to_relative_path
173
+
174
+ Converts an absolute path within the config directory to a relative path.
175
+
176
+ You can use it like so.
177
+
178
+ ```rb
179
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
180
+ loader.to_relative_path("/Users/Verseth/my_app/config/foo.yml")
181
+ #=> "foo.yml"
182
+ ```
183
+
184
+ ## to_absolute_path
185
+
186
+ Converts an absolute path within the config directory to a relative path.
187
+
188
+ You can use it like so.
189
+
190
+ ```rb
191
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
192
+ loader.to_absolute_path("foo.yml")
193
+ #=> "/Users/Verseth/my_app/config/foo.yml"
194
+ ```
195
+
196
+ ### load_yaml
197
+
198
+ Let's you load the content of a YAML file with ERB.
199
+ Keys are symbolized by default. The default environment is `"development"`.
200
+
201
+ Let's say that you've got a config file like this.
202
+ ```yaml
203
+ # config/foo.yml
204
+ development:
205
+ foo: dev value <%= 2 + 5 %>
206
+
207
+ production:
208
+ foo: prod value <%= 10 - 2 %>
209
+ ```
210
+
211
+ You cna load it like so.
212
+
213
+ ```rb
214
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
215
+ loader.load_yaml('foo.yml')
216
+ #=> { foo: "dev value 7" }
217
+ ```
218
+
219
+ You can also load a section for another environment by altering the constructor.
220
+
221
+ ```rb
222
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__), env: 'production')
223
+ loader.load_yaml('foo.yml')
224
+ #=> { foo: "prod value 8" }
225
+ ```
226
+
227
+ Or by passing another argument to the method.
228
+
229
+ ```rb
230
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
231
+ loader.load_yaml('foo.yml', env: 'production')
232
+ #=> { foo: "prod value 8" }
233
+ ```
234
+
235
+ You can also disable key symbolization.
236
+
237
+ ```rb
238
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
239
+ loader.load_yaml('foo.yml', symbolize: false)
240
+ #=> { "foo" => "dev value 7" }
241
+ ```
242
+
243
+ Or load the entire content of the file without looking at a specific environment.
244
+
245
+ ```rb
246
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
247
+ loader.load_yaml('foo.yml', env: nil)
248
+ #=> { development: { foo: "dev value 7" }, production: { foo: "prod value 8" } }
249
+ ```
250
+
251
+ ### load_erb
252
+
253
+ Preprocesses the content of a file with ERB and returns a Ruby `String` with it.
254
+
255
+ Let's say that you've got a config file like this in `config/foo.txt`
256
+
257
+ ```
258
+ This is a file with ERB: <%= 2 - 3 %>
259
+ ```
260
+
261
+ You can load it like so.
262
+
263
+ ```rb
264
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
265
+ loader.load_erb('foo.txt')
266
+ # => "This is a file with ERB: -1"
267
+ ```
268
+
269
+ ### load_file
270
+
271
+ Load the content of the file to a Ruby `String`.
272
+
273
+ Let's say that you've got a config file like this in `config/foo.txt`
274
+
275
+ ```
276
+ This is a file!
277
+ ```
278
+
279
+ You can load it like so.
280
+
281
+ ```rb
282
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
283
+ loader.load_file('foo.txt')
284
+ # => "This is a file!"
285
+ ```
286
+
287
+ ### file_exist?
288
+
289
+ Check whether a file exists under the config directory.
290
+
291
+ Let's say that you've got a directory like this.
292
+
293
+ ```
294
+ config/
295
+ ├─ foo.yml.example
296
+ ├─ bar.txt.example
297
+ ├─ bar.txt
298
+ └─ subdir/
299
+ └─ baz.yml.example
300
+ ```
301
+
302
+ You can perform the following checks.
303
+
304
+ ```rb
305
+ loader = ConfigFileManager.new(File.expand_path('config', __dir__))
306
+ loader.file_exist?('foo.yml.example') #=> true
307
+ loader.file_exist?('bar.yml') #=> false
308
+ loader.file_exist?('subdir/baz.yml.example') #=> true
309
+ ```
310
+
311
+ ## Development
312
+
313
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
314
+
315
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
316
+
317
+ ## Contributing
318
+
319
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Verseth/ruby-config-loader.
320
+
321
+ ## License
322
+
323
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ end
11
+
12
+ require 'rubocop/rake_task'
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ConfigFileManager # rubocop:disable Style/StaticClass
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'yaml'
5
+ require 'erb'
6
+ require 'pastel'
7
+
8
+ require_relative 'config_file_manager/version'
9
+
10
+ # Class that let's you manage your configuration files.
11
+ class ConfigFileManager
12
+ COLORS = ::Pastel.new
13
+
14
+ # Absolute path to the main directory that contains all config files (and subdirectories).
15
+ #
16
+ # @return [String]
17
+ attr_reader :config_dir
18
+
19
+ # Maximum depth of nested directories containing config files.
20
+ #
21
+ # @return [Integer]
22
+ attr_reader :max_dir_depth
23
+
24
+ # Current environment name. Used to load the correct section of YAML files.
25
+ #
26
+ # @return [String]
27
+ attr_reader :env
28
+
29
+ # Extension of the example/dummy version of a config file.
30
+ # eg. `.example`, `.dummy`
31
+ #
32
+ # @return [String]
33
+ attr_reader :example_extension
34
+
35
+ # @param config_dir [String] Absolute path to the root config directory
36
+ # @param example_extension [String]
37
+ # @param max_dir_depth [Integer] Maximum depth of nested directories containing config files.
38
+ # @param env [String] Current environment name
39
+ def initialize(config_dir, example_extension: '.example', max_dir_depth: 5, env: 'development')
40
+ @config_dir = config_dir
41
+ @example_extension = example_extension
42
+ @max_dir_depth = max_dir_depth
43
+ @env = env
44
+ end
45
+
46
+ # Recursively search for files under the `config_dir` directory
47
+ # with the specified extension (eg. `.example`).
48
+ # Returns an array of absolute paths to the found files
49
+ # with the specified extension stripped away.
50
+ #
51
+ # @param example_extension [String] File extension of example files
52
+ # @return [Array<String>]
53
+ def files(example_extension: @example_extension, result: [], depth: 0, dir_path: @config_dir)
54
+ return result if depth > @max_dir_depth
55
+
56
+ ::Dir.each_child(dir_path) do |path|
57
+ abs_path = ::File.join(dir_path, path)
58
+
59
+ if ::File.directory?(abs_path)
60
+ # if the entry is a directory, scan it recursively
61
+ # this essentially performs a depth limited search (DFS with a depth limit)
62
+ next files(
63
+ example_extension: example_extension,
64
+ result: result,
65
+ depth: depth + 1,
66
+ dir_path: abs_path
67
+ )
68
+ end
69
+
70
+ next unless ::File.file?(abs_path) && path.end_with?(example_extension)
71
+
72
+ result << abs_path.delete_suffix(example_extension)
73
+ end
74
+
75
+ result
76
+ end
77
+
78
+ # @param example_extension [String]
79
+ # @return [Array<String>] Absolute paths to missing config files.
80
+ def missing_files(example_extension: @example_extension)
81
+ files(example_extension: example_extension).reject do |file|
82
+ ::File.exist?(file)
83
+ end
84
+ end
85
+
86
+ # Create the missing config files based on their dummy/example versions.
87
+ #
88
+ # @param example_extension [String]
89
+ # @param print [Boolean]
90
+ # @return [void]
91
+ def create_missing_files(example_extension: @example_extension, print: false)
92
+ puts COLORS.blue('== Copying missing config files ==') if print
93
+ files(example_extension: example_extension).each do |file|
94
+ create_missing_file("#{file}#{example_extension}", file, print: print)
95
+ end
96
+ end
97
+
98
+ # Search for directories under the `config_dir` directory
99
+ # with the specified ending (eg. `.example`).
100
+ # Returns an array of absolute paths to the found files
101
+ # with the specified ending stripped away.
102
+ #
103
+ # @param example_extension [String] ending of example directories
104
+ # @return [Array<String>]
105
+ def dirs(example_extension: @example_extension)
106
+ ::Dir.each_child(@config_dir)
107
+ .map { ::File.join(@config_dir, _1) }
108
+ .select { ::File.directory?(_1) && _1.end_with?(example_extension) }
109
+ .map { _1.delete_suffix(example_extension) }
110
+ end
111
+
112
+ # @param example_extension [String]
113
+ # @return [Array<String>] Absolute paths to missing config directories.
114
+ def missing_dirs(example_extension: @example_extension)
115
+ dirs(example_extension: example_extension).reject do |file|
116
+ ::Dir.exist?(file)
117
+ end
118
+ end
119
+
120
+ # Create the missing config directories based on their dummy/example versions.
121
+ #
122
+ # @param example_extension [String]
123
+ # @param print [Boolean]
124
+ # @return [void]
125
+ def create_missing_dirs(example_extension: @example_extension, print: false)
126
+ puts COLORS.blue('== Copying missing config directories ==') if print
127
+ dirs(example_extension: example_extension).each do |dir|
128
+ create_missing_dir("#{dir}#{example_extension}", file, print: print)
129
+ end
130
+ end
131
+
132
+ # Converts a collection of absolute paths to an array of
133
+ # relative paths.
134
+ #
135
+ # @param absolute_paths [Array<String>]
136
+ # @return [Array<String>]
137
+ def to_relative_paths(absolute_paths)
138
+ absolute_paths.map do |path|
139
+ to_relative_path(path)
140
+ end
141
+ end
142
+
143
+ # Converts an absolute path to a relative path
144
+ #
145
+ # @param absolute_path [String]
146
+ # @return [String]
147
+ def to_relative_path(absolute_path)
148
+ absolute_path.delete_prefix("#{@config_dir}/")
149
+ end
150
+
151
+ # Converts a collection of relative paths to an array of
152
+ # absolute paths.
153
+ #
154
+ # @param relative_paths [Array<String>]
155
+ # @return [Array<String>]
156
+ def to_absolute_paths(relative_paths)
157
+ relative_paths.map do |path|
158
+ to_absolute_path(path)
159
+ end
160
+ end
161
+
162
+ # Converts a relative path to an absolute path.
163
+ #
164
+ # @param relative_path [String]
165
+ # @return [String]
166
+ def to_absolute_path(relative_path)
167
+ "#{@config_dir}/#{relative_path}"
168
+ end
169
+
170
+ # @param file_name [Array<String>]
171
+ # @param env [String, nil]
172
+ # @param symbolize [Boolean] Whether the keys should be converted to Ruby symbols
173
+ # @return [Hash, Array]
174
+ def load_yaml(*file_name, env: @env, symbolize: true)
175
+ env = env.to_sym if env && symbolize
176
+ parsed = ::YAML.load(load_erb(*file_name), symbolize_names: symbolize) # rubocop:disable Security/YAMLLoad
177
+ return parsed unless env
178
+
179
+ parsed[env]
180
+ end
181
+
182
+ # @param file_name [Array<String>]
183
+ def delete_file(*file_name)
184
+ ::File.delete(file_path(*file_name))
185
+ end
186
+
187
+ # @param file_name [Array<String>]
188
+ # @return [String]
189
+ def load_erb(*file_name)
190
+ ::ERB.new(load_file(*file_name)).result
191
+ end
192
+
193
+ # @param file_name [Array<String>]
194
+ # @return [String]
195
+ # @raise [SystemCallError]
196
+ def load_file(*file_name)
197
+ ::File.read file_path(*file_name)
198
+ end
199
+
200
+ # @param file_name [Array<String>]
201
+ # @return [Boolean]
202
+ def file_exist?(*file_name)
203
+ ::File.exist? file_path(*file_name)
204
+ end
205
+
206
+ # @param dir_name [Array<String>]
207
+ # @return [Boolean]
208
+ def dir_exist?(*dir_name)
209
+ ::Dir.exist? file_path(*dir_name)
210
+ end
211
+
212
+ # @param file_name [Array<String>]
213
+ # @return [String]
214
+ def file_path(*file_name)
215
+ *path, name = file_name
216
+ ::File.join(@config_dir, *path, name)
217
+ end
218
+
219
+ private
220
+
221
+ # @param original_name [String]
222
+ # @param new_name [String]
223
+ # @param print [Boolean]
224
+ # @return [Boolean]
225
+ def create_missing_file(original_name, new_name, print: false)
226
+ return false if ::File.exist?(new_name)
227
+
228
+ ::FileUtils.cp original_name, new_name
229
+ if print
230
+ copy = COLORS.green.bold 'copy'.rjust(12, ' ')
231
+ puts "#{copy} #{original_name}"
232
+ end
233
+
234
+ true
235
+ end
236
+
237
+ # @param original_name [String]
238
+ # @param new_name [String]
239
+ # @param print [Boolean]
240
+ # @return [Boolean]
241
+ def create_missing_dir(original_name, new_name, print: false)
242
+ return false if ::Dir.exist?(new_name)
243
+
244
+ ::FileUtils.cp_r original_name, new_name
245
+ if print
246
+ copy = COLORS.green.bold 'copy'.rjust(12, ' ')
247
+ puts "#{copy} #{original_name}"
248
+ end
249
+
250
+ true
251
+ end
252
+ end
Binary file
@@ -0,0 +1,4 @@
1
+ module ConfigFileManager
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: config_file_manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateusz Drewniak
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-08-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pastel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.8'
27
+ description: Gem that makes it easy to load config files.
28
+ email:
29
+ - matmg24@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rubocop.yml"
35
+ - CHANGELOG.md
36
+ - LICENSE.txt
37
+ - README.md
38
+ - Rakefile
39
+ - lib/config_file_manager.rb
40
+ - lib/config_file_manager/version.rb
41
+ - pkg/config_loader-0.1.0.gem
42
+ - sig/config_loader.rbs
43
+ homepage: https://github.com/Verseth/ruby-config-loader
44
+ licenses:
45
+ - MIT
46
+ metadata:
47
+ homepage_uri: https://github.com/Verseth/ruby-config-loader
48
+ source_code_uri: https://github.com/Verseth/ruby-config-loader
49
+ rubygems_mfa_required: 'true'
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 3.0.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.4.14
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Gem that makes it easy to load config files.
69
+ test_files: []