config_file_manager 0.1.2 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b4fdc0a8ed8426e6d4ecd41d04ff9ad0aa8e817aca12189cc6cbe0878b81748
4
- data.tar.gz: 903cfee08159f7a560fbc8305282d540799f06271363862898aaa4121545981c
3
+ metadata.gz: d77a5b859939e565703bc2dc5dce3dd9fe8d4cec4f33c7939585834d991a4e66
4
+ data.tar.gz: bd75f33acab4a3e6790bbf907d0409a0a24023f87f2a7f1f0236af26590525ca
5
5
  SHA512:
6
- metadata.gz: 305ed92cf6e19d9b6b4d5ab1af990f5dde5236c53345e206797081ccb8eb43890def787aa3834fe325ecab0bdd31cfcbe522c88315e11c3abe406ce1654fff38
7
- data.tar.gz: 1c5368b9ef06c10ce0476f1c3f09589869e134547bf7350aad2ef75bb12bd29a0ff0613287cb0a88ddca14f3d8f00773725d26758e658edb07d6b777d65997fc
6
+ metadata.gz: 3ad597c042ac18dcc1502113ad9ba87fb925c76a9ccb2e1e835bab8192a657d4a0ee2d1ce5ee46957db8c2115c0fc608a4a81ac5051ad1d06c7fed9296bb8ee7
7
+ data.tar.gz: 4bdcdb68a55c6f6166ef65b9ba6cfcb858288723894e219843616dbffd4c43f0da70b0bcc3735c5eff8f040430787f60e045e1223f6dda38af083e87e73d4060
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  inherit_gem:
2
- rubocop-espago: rubocop.yml
2
+ rubocop-espago: sorbet.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 3.0
5
+ TargetRubyVersion: 3.3
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 4.0.6
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
- ## [Unreleased]
1
+ ## [0.1.4] - 2026-09-01
2
+
3
+ - Add recursive example directories
4
+ - Switch from YARD to RBS comments
5
+
6
+ ## [0.1.3] - 2023-11-30
7
+
8
+ - Add json parsing
2
9
 
3
10
  ## [0.1.2] - 2023-08-29
4
11
 
data/README.md CHANGED
@@ -38,8 +38,16 @@ You can use this gem to easily configure automatic symlinking of config files in
38
38
  ```rb
39
39
  # config/deploy.rb
40
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)
41
+ # path to the repo root
42
+ root_path = File.expand_path('..', __dir__)
43
+ # path to the `config/` directory
44
+ config_dir_path = File.expand_path(__dir__)
45
+
46
+ config_file_manager = ConfigFileManager.new(config_dir_path)
47
+ # get absolute paths to all config files and change them
48
+ # to relative paths (relative to the repo root)
49
+ linked_files = config_file_manager.files.map { _1.delete_prefix("#{root_path}/") }
50
+ set :linked_files, linked_files
43
51
  ```
44
52
 
45
53
  That way you don't have to specify the config files by hand.
@@ -53,7 +61,7 @@ Create an initializer that will be executed first and creates a configured insta
53
61
  ```rb
54
62
  # config/initializers/0_config_file_manager.rb
55
63
 
56
- CONFIG_MANAGER = ConfigFileManager.new(File.expand_path('..', __dir__), env: Rails.env)
64
+ CONFIG_MANAGER = ConfigFileManager.new(Rails.root.join('config'), env: Rails.env)
57
65
  ```
58
66
 
59
67
  And then you can you it to conveniently load config files.
@@ -181,7 +189,7 @@ loader.to_relative_path("/Users/Verseth/my_app/config/foo.yml")
181
189
  #=> "foo.yml"
182
190
  ```
183
191
 
184
- ## to_absolute_path
192
+ ### to_absolute_path
185
193
 
186
194
  Converts an absolute path within the config directory to a relative path.
187
195
 
@@ -208,7 +216,7 @@ production:
208
216
  foo: prod value <%= 10 - 2 %>
209
217
  ```
210
218
 
211
- You cna load it like so.
219
+ You can load it like so.
212
220
 
213
221
  ```rb
214
222
  loader = ConfigFileManager.new(File.expand_path('config', __dir__))
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ConfigFileManager # rubocop:disable Style/StaticClass
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.4'
5
5
  end
@@ -1,6 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'fileutils'
5
+ require 'json'
4
6
  require 'yaml'
5
7
  require 'erb'
6
8
  require 'pastel'
@@ -13,29 +15,30 @@ class ConfigFileManager
13
15
 
14
16
  # Absolute path to the main directory that contains all config files (and subdirectories).
15
17
  #
16
- # @return [String]
18
+ #: String
17
19
  attr_reader :config_dir
18
20
 
19
21
  # Maximum depth of nested directories containing config files.
20
22
  #
21
- # @return [Integer]
23
+ #: Integer
22
24
  attr_reader :max_dir_depth
23
25
 
24
26
  # Current environment name. Used to load the correct section of YAML files.
25
27
  #
26
- # @return [String]
28
+ #: String
27
29
  attr_reader :env
28
30
 
29
31
  # Extension of the example/dummy version of a config file.
30
32
  # eg. `.example`, `.dummy`
31
33
  #
32
- # @return [String]
34
+ #: String
33
35
  attr_reader :example_extension
34
36
 
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
37
+ # @param config_dir Absolute path to the root config directory
38
+ # @param max_dir_depth Maximum depth of nested directories containing config files.
39
+ # @param env Current environment name
40
+ #
41
+ #: (String config_dir, ?example_extension: String, ?max_dir_depth: Integer, ?env: String) -> void
39
42
  def initialize(config_dir, example_extension: '.example', max_dir_depth: 5, env: 'development')
40
43
  @config_dir = config_dir
41
44
  @example_extension = example_extension
@@ -48,8 +51,9 @@ class ConfigFileManager
48
51
  # Returns an array of absolute paths to the found files
49
52
  # with the specified extension stripped away.
50
53
  #
51
- # @param example_extension [String] File extension of example files
52
- # @return [Array<String>]
54
+ # @param example_extension File extension of example files
55
+ #
56
+ #: (?example_extension: String, ?result: Array[String], ?depth: Integer, ?dir_path: String) -> Array[String]
53
57
  def files(example_extension: @example_extension, result: [], depth: 0, dir_path: @config_dir)
54
58
  return result if depth > @max_dir_depth
55
59
 
@@ -61,9 +65,9 @@ class ConfigFileManager
61
65
  # this essentially performs a depth limited search (DFS with a depth limit)
62
66
  next files(
63
67
  example_extension: example_extension,
64
- result: result,
65
- depth: depth + 1,
66
- dir_path: abs_path
68
+ result: result,
69
+ depth: depth + 1,
70
+ dir_path: abs_path,
67
71
  )
68
72
  end
69
73
 
@@ -75,8 +79,9 @@ class ConfigFileManager
75
79
  result
76
80
  end
77
81
 
78
- # @param example_extension [String]
79
- # @return [Array<String>] Absolute paths to missing config files.
82
+ # Absolute paths to missing config files.
83
+ #
84
+ #: (?example_extension: String) -> Array[String]
80
85
  def missing_files(example_extension: @example_extension)
81
86
  files(example_extension: example_extension).reject do |file|
82
87
  ::File.exist?(file)
@@ -85,9 +90,7 @@ class ConfigFileManager
85
90
 
86
91
  # Create the missing config files based on their dummy/example versions.
87
92
  #
88
- # @param example_extension [String]
89
- # @param print [Boolean]
90
- # @return [void]
93
+ #: (?example_extension: String, ?print: bool) -> void
91
94
  def create_missing_files(example_extension: @example_extension, print: false)
92
95
  puts COLORS.blue('== Copying missing config files ==') if print
93
96
  files(example_extension: example_extension).each do |file|
@@ -95,22 +98,44 @@ class ConfigFileManager
95
98
  end
96
99
  end
97
100
 
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.
101
+ # Recursively search for directories under the `config_dir` directory
102
+ # with the specified extension (eg. `.example`).
103
+ # Returns an array of absolute paths to the found directories
104
+ # with the specified extension stripped away.
105
+ #
106
+ # @param example_extension ending of example directories
102
107
  #
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) }
108
+ #: (?example_extension: String, ?result: Array[String], ?depth: Integer, ?dir_path: String) -> Array[String]
109
+ def dirs(example_extension: @example_extension, result: [], depth: 0, root_dir_path: @config_dir)
110
+ return result if depth > @max_dir_depth
111
+
112
+ ::Dir.each_child(root_dir_path) do |path|
113
+ abs_path = ::File.join(root_dir_path, path)
114
+
115
+ next unless ::File.directory?(abs_path)
116
+
117
+ # if the entry is a directory with the example extension, add it to the result array
118
+ if path.end_with?(example_extension)
119
+ result << abs_path.delete_suffix(example_extension)
120
+ next
121
+ end
122
+
123
+ # if the entry is a directory without the example extension, scan it recursively
124
+ # this essentially performs a depth limited search (DFS with a depth limit)
125
+ next dirs(
126
+ example_extension: example_extension,
127
+ result: result,
128
+ depth: depth + 1,
129
+ root_dir_path: abs_path,
130
+ )
131
+ end
132
+
133
+ result
110
134
  end
111
135
 
112
- # @param example_extension [String]
113
- # @return [Array<String>] Absolute paths to missing config directories.
136
+ # Absolute paths to missing config directories.
137
+ #
138
+ #: (?example_extension: String) -> Array[String]
114
139
  def missing_dirs(example_extension: @example_extension)
115
140
  dirs(example_extension: example_extension).reject do |file|
116
141
  ::Dir.exist?(file)
@@ -119,9 +144,7 @@ class ConfigFileManager
119
144
 
120
145
  # Create the missing config directories based on their dummy/example versions.
121
146
  #
122
- # @param example_extension [String]
123
- # @param print [Boolean]
124
- # @return [void]
147
+ #: (?example_extension: String, ?print: bool) -> void
125
148
  def create_missing_dirs(example_extension: @example_extension, print: false)
126
149
  puts COLORS.blue('== Copying missing config directories ==') if print
127
150
  dirs(example_extension: example_extension).each do |dir|
@@ -132,8 +155,7 @@ class ConfigFileManager
132
155
  # Converts a collection of absolute paths to an array of
133
156
  # relative paths.
134
157
  #
135
- # @param absolute_paths [Array<String>]
136
- # @return [Array<String>]
158
+ #: (Array[String] absolute_paths) -> Array[String]
137
159
  def to_relative_paths(absolute_paths)
138
160
  absolute_paths.map do |path|
139
161
  to_relative_path(path)
@@ -142,8 +164,7 @@ class ConfigFileManager
142
164
 
143
165
  # Converts an absolute path to a relative path
144
166
  #
145
- # @param absolute_path [String]
146
- # @return [String]
167
+ #: (String absolute_path) -> String
147
168
  def to_relative_path(absolute_path)
148
169
  absolute_path.delete_prefix("#{@config_dir}/")
149
170
  end
@@ -151,8 +172,7 @@ class ConfigFileManager
151
172
  # Converts a collection of relative paths to an array of
152
173
  # absolute paths.
153
174
  #
154
- # @param relative_paths [Array<String>]
155
- # @return [Array<String>]
175
+ #: (Array[String] relative_paths) -> Array[String]
156
176
  def to_absolute_paths(relative_paths)
157
177
  relative_paths.map do |path|
158
178
  to_absolute_path(path)
@@ -161,16 +181,14 @@ class ConfigFileManager
161
181
 
162
182
  # Converts a relative path to an absolute path.
163
183
  #
164
- # @param relative_path [String]
165
- # @return [String]
184
+ #: (String relative_path) -> String
166
185
  def to_absolute_path(relative_path)
167
186
  "#{@config_dir}/#{relative_path}"
168
187
  end
169
188
 
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]
189
+ # @param symbolize Whether the keys should be converted to Ruby symbols
190
+ #
191
+ #: (*String file_name, ?env: String?, ?symbolize: bool) -> untyped
174
192
  def load_yaml(*file_name, env: @env, symbolize: true)
175
193
  env = env.to_sym if env && symbolize
176
194
  parsed = ruby_load_yaml(load_erb(*file_name), symbolize_names: symbolize)
@@ -179,43 +197,50 @@ class ConfigFileManager
179
197
  parsed[env]
180
198
  end
181
199
 
182
- # @param file_name [Array<String>]
200
+ # @param symbolize Whether the keys should be converted to Ruby symbols
201
+ #
202
+ #: (*String file_name, ?env: String?, ?symbolize: bool) -> untyped
203
+ def load_json(*file_name, env: @env, symbolize: true)
204
+ env = env.to_sym if env && symbolize
205
+ parsed = ::JSON.parse(load_erb(*file_name), symbolize_names: symbolize)
206
+ return parsed unless env
207
+
208
+ parsed[env]
209
+ end
210
+
211
+ #: (*String file_name) -> void
183
212
  def delete_file(*file_name)
184
213
  ::File.delete(file_path(*file_name))
185
214
  end
186
215
 
187
- # @param dir_name [Array<String>]
216
+ #: (*String dir_name) -> void
188
217
  def delete_dir(*dir_name)
189
218
  ::FileUtils.rm_r(file_path(*dir_name))
190
219
  end
191
220
 
192
- # @param file_name [Array<String>]
193
- # @return [String]
221
+ #: (*String file_name) -> String
194
222
  def load_erb(*file_name)
195
223
  ::ERB.new(load_file(*file_name)).result
196
224
  end
197
225
 
198
- # @param file_name [Array<String>]
199
- # @return [String]
200
226
  # @raise [SystemCallError]
227
+ #
228
+ #: (*String file_name) -> String
201
229
  def load_file(*file_name)
202
230
  ::File.read file_path(*file_name)
203
231
  end
204
232
 
205
- # @param file_name [Array<String>]
206
- # @return [Boolean]
233
+ #: (*String file_name) -> bool
207
234
  def file_exist?(*file_name)
208
235
  ::File.exist? file_path(*file_name)
209
236
  end
210
237
 
211
- # @param dir_name [Array<String>]
212
- # @return [Boolean]
238
+ #: (*String dir_name) -> bool
213
239
  def dir_exist?(*dir_name)
214
240
  ::Dir.exist? file_path(*dir_name)
215
241
  end
216
242
 
217
- # @param file_name [Array<String>]
218
- # @return [String]
243
+ #: (*String file_name) -> String
219
244
  def file_path(*file_name)
220
245
  *path, name = file_name
221
246
  ::File.join(@config_dir, *path, name)
@@ -224,19 +249,22 @@ class ConfigFileManager
224
249
  private
225
250
 
226
251
  if ::Psych::VERSION >= '4'
227
- def ruby_load_yaml(content, **options) # rubocop:disable Style/DocumentationMethod
228
- ::YAML.load(content, aliases: true, **options) # rubocop:disable Security/YAMLLoad
252
+ # Load YAML content using the Psych 4+ API.
253
+ #
254
+ #: (String content, **untyped options) -> untyped
255
+ def ruby_load_yaml(content, **options)
256
+ ::YAML.load(content, aliases: true, **options)
229
257
  end
230
258
  else
231
- def ruby_load_yaml(content, **options) # rubocop:disable Style/DocumentationMethod
232
- ::YAML.load(content, **options) # rubocop:disable Security/YAMLLoad
259
+ # Load YAML content using the pre Psych 4 API.
260
+ #
261
+ #: (String content, **untyped options) -> untyped
262
+ def ruby_load_yaml(content, **options)
263
+ ::YAML.load(content, **options)
233
264
  end
234
265
  end
235
266
 
236
- # @param original_name [String]
237
- # @param new_name [String]
238
- # @param print [Boolean]
239
- # @return [Boolean]
267
+ #: (String original_name, String new_name, ?print: bool) -> bool
240
268
  def create_missing_file(original_name, new_name, print: false)
241
269
  return false if ::File.exist?(new_name)
242
270
 
@@ -249,10 +277,7 @@ class ConfigFileManager
249
277
  true
250
278
  end
251
279
 
252
- # @param original_name [String]
253
- # @param new_name [String]
254
- # @param print [Boolean]
255
- # @return [Boolean]
280
+ #: (String original_name, String new_name, ?print: bool) -> bool
256
281
  def create_missing_dir(original_name, new_name, print: false)
257
282
  return false if ::Dir.exist?(new_name)
258
283
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: config_file_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Drewniak
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-08-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: pastel
@@ -32,13 +31,13 @@ extensions: []
32
31
  extra_rdoc_files: []
33
32
  files:
34
33
  - ".rubocop.yml"
34
+ - ".ruby-version"
35
35
  - CHANGELOG.md
36
36
  - LICENSE.txt
37
37
  - README.md
38
38
  - Rakefile
39
39
  - lib/config_file_manager.rb
40
40
  - lib/config_file_manager/version.rb
41
- - sig/config_loader.rbs
42
41
  homepage: https://github.com/Verseth/ruby-config-loader
43
42
  licenses:
44
43
  - MIT
@@ -46,7 +45,6 @@ metadata:
46
45
  homepage_uri: https://github.com/Verseth/ruby-config-loader
47
46
  source_code_uri: https://github.com/Verseth/ruby-config-loader
48
47
  rubygems_mfa_required: 'true'
49
- post_install_message:
50
48
  rdoc_options: []
51
49
  require_paths:
52
50
  - lib
@@ -54,15 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
52
  requirements:
55
53
  - - ">="
56
54
  - !ruby/object:Gem::Version
57
- version: 3.0.0
55
+ version: 3.3.0
58
56
  required_rubygems_version: !ruby/object:Gem::Requirement
59
57
  requirements:
60
58
  - - ">="
61
59
  - !ruby/object:Gem::Version
62
60
  version: '0'
63
61
  requirements: []
64
- rubygems_version: 3.4.14
65
- signing_key:
62
+ rubygems_version: 4.0.16
66
63
  specification_version: 4
67
64
  summary: Gem that makes it easy to load config files.
68
65
  test_files: []
@@ -1,4 +0,0 @@
1
- module ConfigFileManager
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end