config_file_manager 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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: []