myway_config 0.1.1

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.
data/docs/api/base.md ADDED
@@ -0,0 +1,292 @@
1
+ # MywayConfig::Base
2
+
3
+ Base class for configuration. Extends `Anyway::Config`.
4
+
5
+ ## Class Methods
6
+
7
+ ### config_name
8
+
9
+ Set the configuration name.
10
+
11
+ ```ruby
12
+ config_name :myapp
13
+ ```
14
+
15
+ **Parameters:**
16
+
17
+ - `name` (Symbol) - The configuration name
18
+
19
+ **Used for:**
20
+
21
+ - Finding config files (`config/myapp.yml`)
22
+ - XDG config path (`~/.config/myapp/config.yml`)
23
+ - Loader registration
24
+
25
+ ---
26
+
27
+ ### env_prefix
28
+
29
+ Set the environment variable prefix.
30
+
31
+ ```ruby
32
+ env_prefix :myapp
33
+ ```
34
+
35
+ **Parameters:**
36
+
37
+ - `prefix` (Symbol) - The prefix for environment variables
38
+
39
+ **Result:**
40
+
41
+ Environment variables like `MYAPP_DATABASE__HOST` will be recognized.
42
+
43
+ ---
44
+
45
+ ### defaults_path
46
+
47
+ Register the defaults file path.
48
+
49
+ ```ruby
50
+ defaults_path File.expand_path("config/defaults.yml", __dir__)
51
+ ```
52
+
53
+ **Parameters:**
54
+
55
+ - `path` (String) - Absolute path to the defaults YAML file
56
+
57
+ **Raises:**
58
+
59
+ - `ConfigurationError` if the file does not exist
60
+
61
+ ---
62
+
63
+ ### auto_configure!
64
+
65
+ Auto-generate attributes and coercions from the YAML schema.
66
+
67
+ ```ruby
68
+ auto_configure!
69
+ ```
70
+
71
+ **Raises:**
72
+
73
+ - `ConfigurationError` if `defaults_path` is not set
74
+
75
+ **Behavior:**
76
+
77
+ - Creates `attr_config` for each key in the `defaults:` section
78
+ - Coerces Hash values to `ConfigSection`
79
+ - Coerces Symbol values to symbols
80
+
81
+ ---
82
+
83
+ ### schema
84
+
85
+ Returns the defaults section from the YAML file.
86
+
87
+ ```ruby
88
+ MyConfig.schema # => {database: {host: "localhost", ...}, ...}
89
+ ```
90
+
91
+ **Returns:**
92
+
93
+ - `Hash` - The parsed `defaults:` section
94
+
95
+ ---
96
+
97
+ ### config_section_coercion
98
+
99
+ Create a coercion proc that merges with schema defaults.
100
+
101
+ ```ruby
102
+ coerce_types(
103
+ database: config_section_coercion(:database)
104
+ )
105
+ ```
106
+
107
+ **Parameters:**
108
+
109
+ - `section_key` (Symbol) - The section key in the schema
110
+
111
+ **Returns:**
112
+
113
+ - `Proc` - Coercion proc for use with `coerce_types`
114
+
115
+ ---
116
+
117
+ ### config_section
118
+
119
+ Create a simple ConfigSection coercion (without schema defaults).
120
+
121
+ ```ruby
122
+ coerce_types(
123
+ settings: config_section
124
+ )
125
+ ```
126
+
127
+ **Returns:**
128
+
129
+ - `Proc` - Coercion proc
130
+
131
+ ---
132
+
133
+ ### to_symbol
134
+
135
+ Create a symbol coercion proc.
136
+
137
+ ```ruby
138
+ coerce_types(
139
+ log_level: to_symbol
140
+ )
141
+ ```
142
+
143
+ **Returns:**
144
+
145
+ - `Proc` - Coercion proc that converts to symbol
146
+
147
+ ---
148
+
149
+ ### env
150
+
151
+ Get the current environment.
152
+
153
+ ```ruby
154
+ MyConfig.env # => "development"
155
+ ```
156
+
157
+ **Returns:**
158
+
159
+ - `String` - Current environment name
160
+
161
+ **Priority:**
162
+
163
+ 1. `Anyway::Settings.current_environment`
164
+ 2. `ENV['RAILS_ENV']`
165
+ 3. `ENV['RACK_ENV']`
166
+ 4. `'development'`
167
+
168
+ ---
169
+
170
+ ### valid_environments
171
+
172
+ Get list of valid environment names from the defaults file.
173
+
174
+ ```ruby
175
+ MyConfig.valid_environments # => [:development, :production, :test]
176
+ ```
177
+
178
+ **Returns:**
179
+
180
+ - `Array<Symbol>` - Environment names defined in YAML
181
+
182
+ ---
183
+
184
+ ### valid_environment?
185
+
186
+ Check if current environment is valid.
187
+
188
+ ```ruby
189
+ MyConfig.valid_environment? # => true
190
+ ```
191
+
192
+ **Returns:**
193
+
194
+ - `Boolean` - true if environment has a section in YAML
195
+
196
+ ---
197
+
198
+ ## Instance Methods
199
+
200
+ ### initialize
201
+
202
+ Create a new configuration instance.
203
+
204
+ ```ruby
205
+ # Default (use loaders)
206
+ config = MyConfig.new
207
+
208
+ # From file path
209
+ config = MyConfig.new("/path/to/config.yml")
210
+
211
+ # From Hash
212
+ config = MyConfig.new(database: { host: "custom" })
213
+ ```
214
+
215
+ **Parameters:**
216
+
217
+ - `source` (nil, String, Pathname, Hash) - Configuration source
218
+
219
+ **Raises:**
220
+
221
+ - `ConfigurationError` if file path doesn't exist
222
+ - `ConfigurationError` if source type is invalid
223
+
224
+ ---
225
+
226
+ ### environment
227
+
228
+ Get the current environment name.
229
+
230
+ ```ruby
231
+ config.environment # => "development"
232
+ ```
233
+
234
+ **Returns:**
235
+
236
+ - `String` - Current environment
237
+
238
+ ---
239
+
240
+ ### development?
241
+
242
+ Check if running in development environment.
243
+
244
+ ```ruby
245
+ config.development? # => true
246
+ ```
247
+
248
+ ---
249
+
250
+ ### production?
251
+
252
+ Check if running in production environment.
253
+
254
+ ```ruby
255
+ config.production? # => false
256
+ ```
257
+
258
+ ---
259
+
260
+ ### test?
261
+
262
+ Check if running in test environment.
263
+
264
+ ```ruby
265
+ config.test? # => false
266
+ ```
267
+
268
+ ---
269
+
270
+ ### valid_environment?
271
+
272
+ Check if current environment is valid.
273
+
274
+ ```ruby
275
+ config.valid_environment? # => true
276
+ ```
277
+
278
+ ## Example
279
+
280
+ ```ruby
281
+ class MyApp::Config < MywayConfig::Base
282
+ config_name :myapp
283
+ env_prefix :myapp
284
+ defaults_path File.expand_path("config/defaults.yml", __dir__)
285
+ auto_configure!
286
+ end
287
+
288
+ config = MyApp::Config.new
289
+ config.database.host # => "localhost"
290
+ config.environment # => "development"
291
+ config.development? # => true
292
+ ```
@@ -0,0 +1,368 @@
1
+ # ConfigSection
2
+
3
+ Hash-like wrapper for nested configuration with method access and Enumerable support.
4
+
5
+ ## Overview
6
+
7
+ `ConfigSection` wraps Hash values from YAML, providing:
8
+
9
+ - Method access (`config.database.host`)
10
+ - Bracket access (`config.database[:host]`)
11
+ - Enumerable iteration
12
+ - Hash-like methods (`keys`, `values`, `fetch`, `dig`)
13
+
14
+ ## Constructor
15
+
16
+ ### new
17
+
18
+ Create a new ConfigSection from a Hash.
19
+
20
+ ```ruby
21
+ section = MywayConfig::ConfigSection.new(host: "localhost", port: 5432)
22
+ ```
23
+
24
+ **Parameters:**
25
+
26
+ - `hash` (Hash) - The hash to wrap (default: `{}`)
27
+
28
+ **Behavior:**
29
+
30
+ - Keys are symbolized
31
+ - Nested Hashes become nested ConfigSections
32
+
33
+ ---
34
+
35
+ ## Access Methods
36
+
37
+ ### Method Access
38
+
39
+ ```ruby
40
+ section.host # => "localhost"
41
+ section.port # => 5432
42
+ section.missing # => nil
43
+ ```
44
+
45
+ ### Bracket Access
46
+
47
+ ```ruby
48
+ section[:host] # => "localhost"
49
+ section["host"] # => "localhost"
50
+ ```
51
+
52
+ ### Setting Values
53
+
54
+ ```ruby
55
+ section.host = "new-host"
56
+ section[:port] = 5433
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Hash Methods
62
+
63
+ ### keys
64
+
65
+ Get all keys.
66
+
67
+ ```ruby
68
+ section.keys # => [:host, :port, :name]
69
+ ```
70
+
71
+ **Returns:**
72
+
73
+ - `Array<Symbol>` - All keys
74
+
75
+ ---
76
+
77
+ ### values
78
+
79
+ Get all values.
80
+
81
+ ```ruby
82
+ section.values # => ["localhost", 5432, "myapp_db"]
83
+ ```
84
+
85
+ **Returns:**
86
+
87
+ - `Array` - All values
88
+
89
+ ---
90
+
91
+ ### size / length
92
+
93
+ Get the number of keys.
94
+
95
+ ```ruby
96
+ section.size # => 3
97
+ section.length # => 3
98
+ ```
99
+
100
+ **Returns:**
101
+
102
+ - `Integer` - Number of keys
103
+
104
+ ---
105
+
106
+ ### key? / has_key? / include? / member?
107
+
108
+ Check if a key exists.
109
+
110
+ ```ruby
111
+ section.key?(:host) # => true
112
+ section.has_key?(:host) # => true
113
+ section.include?(:host) # => true
114
+ section.member?(:host) # => true
115
+ ```
116
+
117
+ **Parameters:**
118
+
119
+ - `key` (Symbol, String) - The key to check
120
+
121
+ **Returns:**
122
+
123
+ - `Boolean` - true if key exists
124
+
125
+ ---
126
+
127
+ ### empty?
128
+
129
+ Check if the section has no keys.
130
+
131
+ ```ruby
132
+ section.empty? # => false
133
+ MywayConfig::ConfigSection.new.empty? # => true
134
+ ```
135
+
136
+ **Returns:**
137
+
138
+ - `Boolean` - true if no keys
139
+
140
+ ---
141
+
142
+ ### fetch
143
+
144
+ Fetch a value with optional default.
145
+
146
+ ```ruby
147
+ # With key
148
+ section.fetch(:host) # => "localhost"
149
+
150
+ # With default value
151
+ section.fetch(:missing, "default") # => "default"
152
+
153
+ # With block
154
+ section.fetch(:missing) { |k| "no #{k}" } # => "no missing"
155
+
156
+ # Without default (raises KeyError)
157
+ section.fetch(:missing) # => KeyError: key not found: :missing
158
+ ```
159
+
160
+ **Parameters:**
161
+
162
+ - `key` (Symbol, String) - The key to fetch
163
+ - `default` (Object) - Optional default value
164
+
165
+ **Yields:**
166
+
167
+ - `key` - When block provided and key missing
168
+
169
+ **Returns:**
170
+
171
+ - `Object` - The value or default
172
+
173
+ **Raises:**
174
+
175
+ - `KeyError` - If key not found and no default
176
+
177
+ ---
178
+
179
+ ### dig
180
+
181
+ Access nested values safely.
182
+
183
+ ```ruby
184
+ config.api.dig(:headers, :content_type) # => "application/json"
185
+ config.api.dig(:missing, :nested) # => nil
186
+ ```
187
+
188
+ **Parameters:**
189
+
190
+ - `keys` (Array<Symbol, String>) - Keys to dig through
191
+
192
+ **Returns:**
193
+
194
+ - `Object, nil` - The value or nil if not found
195
+
196
+ ---
197
+
198
+ ### [] and []=
199
+
200
+ Bracket access and assignment.
201
+
202
+ ```ruby
203
+ section[:host] # => "localhost"
204
+ section[:host] = "new-host"
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Enumerable Methods
210
+
211
+ ConfigSection includes `Enumerable`, providing all iteration methods.
212
+
213
+ ### each
214
+
215
+ Iterate over key-value pairs.
216
+
217
+ ```ruby
218
+ section.each do |key, value|
219
+ puts "#{key}: #{value}"
220
+ end
221
+ ```
222
+
223
+ ---
224
+
225
+ ### map
226
+
227
+ Transform key-value pairs.
228
+
229
+ ```ruby
230
+ section.map { |k, v| "#{k}=#{v}" }
231
+ # => ["host=localhost", "port=5432"]
232
+ ```
233
+
234
+ ---
235
+
236
+ ### select / reject
237
+
238
+ Filter key-value pairs.
239
+
240
+ ```ruby
241
+ section.select { |k, v| v.is_a?(Integer) }
242
+ # => [[:port, 5432], [:pool, 5]]
243
+
244
+ section.reject { |k, v| v.nil? }
245
+ ```
246
+
247
+ ---
248
+
249
+ ### find / detect
250
+
251
+ Find first matching pair.
252
+
253
+ ```ruby
254
+ section.find { |k, v| v == 5432 }
255
+ # => [:port, 5432]
256
+ ```
257
+
258
+ ---
259
+
260
+ ### any? / all? / none?
261
+
262
+ Check conditions.
263
+
264
+ ```ruby
265
+ section.any? { |k, v| v.nil? } # => false
266
+ section.all? { |k, v| v } # => true
267
+ section.none? { |k, v| v.nil? } # => true
268
+ ```
269
+
270
+ ---
271
+
272
+ ### Other Enumerable Methods
273
+
274
+ All standard Enumerable methods work:
275
+
276
+ - `count`, `first`, `take`, `drop`
277
+ - `min`, `max`, `minmax`
278
+ - `sort`, `sort_by`
279
+ - `group_by`, `partition`
280
+ - `reduce`, `inject`
281
+ - And more...
282
+
283
+ ---
284
+
285
+ ## Conversion Methods
286
+
287
+ ### to_h
288
+
289
+ Convert to a plain Ruby Hash.
290
+
291
+ ```ruby
292
+ section.to_h
293
+ # => {host: "localhost", port: 5432, name: "myapp_db"}
294
+ ```
295
+
296
+ Nested ConfigSections are also converted:
297
+
298
+ ```ruby
299
+ config.api.to_h
300
+ # => {
301
+ # base_url: "https://api.example.com",
302
+ # timeout: 30,
303
+ # headers: {content_type: "application/json"}
304
+ # }
305
+ ```
306
+
307
+ **Returns:**
308
+
309
+ - `Hash` - Plain Ruby Hash
310
+
311
+ ---
312
+
313
+ ### merge
314
+
315
+ Merge with another ConfigSection or Hash.
316
+
317
+ ```ruby
318
+ overrides = { host: "new-host", pool: 10 }
319
+ merged = section.merge(overrides)
320
+
321
+ merged.host # => "new-host"
322
+ merged.pool # => 10
323
+ merged.port # => 5432 (from original)
324
+ ```
325
+
326
+ **Parameters:**
327
+
328
+ - `other` (ConfigSection, Hash) - Values to merge
329
+
330
+ **Returns:**
331
+
332
+ - `ConfigSection` - New merged ConfigSection
333
+
334
+ ---
335
+
336
+ ## Examples
337
+
338
+ ### Building Connection Strings
339
+
340
+ ```ruby
341
+ db = config.database
342
+ connection_string = "postgres://#{db.host}:#{db.port}/#{db.name}"
343
+ # => "postgres://localhost:5432/myapp_db"
344
+ ```
345
+
346
+ ### Filtering Configuration
347
+
348
+ ```ruby
349
+ # Get all non-nil settings
350
+ config.database.reject { |k, v| v.nil? }.to_h
351
+ ```
352
+
353
+ ### Transforming Values
354
+
355
+ ```ruby
356
+ # Upcase all string values
357
+ config.database.map { |k, v|
358
+ [k, v.is_a?(String) ? v.upcase : v]
359
+ }.to_h
360
+ ```
361
+
362
+ ### Safe Nested Access
363
+
364
+ ```ruby
365
+ # Won't raise even if path doesn't exist
366
+ timeout = config.api.dig(:retry, :timeout) || 30
367
+ ```
368
+
data/docs/api/index.md ADDED
@@ -0,0 +1,85 @@
1
+ # API Reference
2
+
3
+ Complete API documentation for MywayConfig.
4
+
5
+ ## Core Classes
6
+
7
+ - [MywayConfig::Base](base.md) - Base class for configuration
8
+ - [ConfigSection](config-section.md) - Hash-like configuration sections
9
+ - [Loaders](loaders.md) - Configuration loaders
10
+
11
+ ## Module
12
+
13
+ ### MywayConfig
14
+
15
+ The main module provides setup and error classes.
16
+
17
+ #### Methods
18
+
19
+ ##### `MywayConfig.setup!`
20
+
21
+ Registers the XDG and defaults loaders with Anyway Config. Called automatically when the gem is loaded.
22
+
23
+ ```ruby
24
+ MywayConfig.setup!
25
+ ```
26
+
27
+ ##### `MywayConfig.setup?`
28
+
29
+ Check if setup has been completed.
30
+
31
+ ```ruby
32
+ MywayConfig.setup? # => true
33
+ ```
34
+
35
+ ##### `MywayConfig.reset!`
36
+
37
+ Reset setup state (mainly for testing).
38
+
39
+ ```ruby
40
+ MywayConfig.reset!
41
+ ```
42
+
43
+ ## Error Classes
44
+
45
+ ### MywayConfig::Error
46
+
47
+ Base error class for all MywayConfig errors.
48
+
49
+ ```ruby
50
+ begin
51
+ # ...
52
+ rescue MywayConfig::Error => e
53
+ # Handle any MywayConfig error
54
+ end
55
+ ```
56
+
57
+ ### MywayConfig::ConfigurationError
58
+
59
+ Raised for configuration problems:
60
+
61
+ - Missing defaults file
62
+ - Invalid constructor argument
63
+ - `auto_configure!` called without `defaults_path`
64
+
65
+ ```ruby
66
+ begin
67
+ MyConfig.new("/nonexistent/file.yml")
68
+ rescue MywayConfig::ConfigurationError => e
69
+ puts "Config error: #{e.message}"
70
+ end
71
+ ```
72
+
73
+ ### MywayConfig::ValidationError
74
+
75
+ Reserved for validation errors (future use).
76
+
77
+ ## Constants
78
+
79
+ ### MywayConfig::VERSION
80
+
81
+ The gem version string.
82
+
83
+ ```ruby
84
+ MywayConfig::VERSION # => "0.1.0"
85
+ ```