dry-configurable 0.11.5
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 +7 -0
- data/CHANGELOG.md +177 -0
- data/LICENSE +20 -0
- data/README.md +29 -0
- data/dry-configurable.gemspec +38 -0
- data/lib/dry-configurable.rb +3 -0
- data/lib/dry/configurable.rb +66 -0
- data/lib/dry/configurable/class_methods.rb +103 -0
- data/lib/dry/configurable/compiler.rb +45 -0
- data/lib/dry/configurable/config.rb +129 -0
- data/lib/dry/configurable/constants.rb +12 -0
- data/lib/dry/configurable/dsl.rb +62 -0
- data/lib/dry/configurable/dsl/args.rb +58 -0
- data/lib/dry/configurable/errors.rb +11 -0
- data/lib/dry/configurable/instance_methods.rb +46 -0
- data/lib/dry/configurable/methods.rb +32 -0
- data/lib/dry/configurable/setting.rb +130 -0
- data/lib/dry/configurable/settings.rb +72 -0
- data/lib/dry/configurable/test_interface.rb +24 -0
- data/lib/dry/configurable/version.rb +8 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f0faa56dea70f112144295394747175b526e116cdfd09d3ccfa047b85dd06b11
|
4
|
+
data.tar.gz: 48fc6304ef41ea05076765bbe8f7286e90ed69ee54b388650d3654b74b4ebfda
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9c6c284433350053c27e745a8bcb0a0c000c22d4fe684c39eeb20340d026b764f8d80ee155a30ba88af66f4e9ba1022e1572accfa5aff4657b463978534d964e
|
7
|
+
data.tar.gz: ed4d650fb3f2d7f92d05bad9575c452bf67138489a734e91ccc4fb6d9fa5932a6dee72430a84c7b2994b8d28bb42a6d7c4dda8e5b82e9ce51ac588a0888f1b2b
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
## 0.11.5 2020-03-23
|
2
|
+
|
3
|
+
|
4
|
+
### Fixed
|
5
|
+
|
6
|
+
- When settings are copied or cloned, unevaluated values will no longer be copied. This prevents unintended crashes when settings have constructors expecting a certain type of value, but that value is yet to be provided (Fixed via #87) (@timriley)
|
7
|
+
|
8
|
+
|
9
|
+
[Compare v0.11.4...v0.11.5](https://github.com/dry-rb/dry-configurable/compare/v0.11.4...v0.11.5)
|
10
|
+
|
11
|
+
## 0.11.4 2020-03-16
|
12
|
+
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
|
16
|
+
- `Config#update` returns `self` again (issue #60 fixed via #92) (@solnic)
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- `Setting#inspect` no longer uses its value - this could cause crashes when inspecting settings that are yet to have a value applied (e.g. when they have a constructor that expects a value to be present) (@timriley)
|
21
|
+
|
22
|
+
[Compare v0.11.3...v0.11.4](https://github.com/dry-rb/dry-configurable/compare/v0.11.3...v0.11.4)
|
23
|
+
|
24
|
+
## 0.11.3 2020-02-22
|
25
|
+
|
26
|
+
|
27
|
+
### Fixed
|
28
|
+
|
29
|
+
- Retrieving settings by a string name works again (issue #82) (@waiting-for-dev)
|
30
|
+
|
31
|
+
|
32
|
+
[Compare v0.11.2...v0.11.3](https://github.com/dry-rb/dry-configurable/compare/v0.11.2...v0.11.3)
|
33
|
+
|
34
|
+
## 0.11.2 2020-02-20
|
35
|
+
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
|
39
|
+
- Warning about redefined `Setting#value` is gone (@solnic)
|
40
|
+
|
41
|
+
|
42
|
+
[Compare v0.11.1...v0.11.2](https://github.com/dry-rb/dry-configurable/compare/v0.11.1...v0.11.2)
|
43
|
+
|
44
|
+
## 0.11.1 2020-02-18
|
45
|
+
|
46
|
+
|
47
|
+
### Fixed
|
48
|
+
|
49
|
+
- You can use `:settings` as a config key again (issue #80) (@solnic)
|
50
|
+
- Setting value is lazy-evaluated now, which fixes some cases where a constructor could crash with a `nil` value (@solnic)
|
51
|
+
|
52
|
+
|
53
|
+
[Compare v0.11.0...v0.11.1](https://github.com/dry-rb/dry-configurable/compare/v0.11.0...v0.11.1)
|
54
|
+
|
55
|
+
## 0.11.0 2020-02-15
|
56
|
+
|
57
|
+
Complete rewrite of the library while keeping the public API intact. See #78 for a detailed overview.
|
58
|
+
|
59
|
+
### Changed
|
60
|
+
|
61
|
+
- Accessing config in a parent class no longer prevents you from adding more settings in a child class (@solnic)
|
62
|
+
- (internal) New low-level Setting and Config API (@solnic)
|
63
|
+
- (internal) `config` objects use method_missing now (@solnic)
|
64
|
+
|
65
|
+
[Compare v0.10.0...v0.11.0](https://github.com/dry-rb/dry-configurable/compare/v0.10.0...v0.11.0)
|
66
|
+
|
67
|
+
## 0.10.0 2020-01-31
|
68
|
+
|
69
|
+
YANKED because the change also broke inheritance for classes that used `configured` before other classes inherited from them.
|
70
|
+
|
71
|
+
### Changed
|
72
|
+
|
73
|
+
- Inheriting settings no longer defines the config object. This change fixed a use case where parent class that already used its config would prevent a child class from adding new settings (@solnic)
|
74
|
+
|
75
|
+
[Compare v0.9.0...v0.10.0](https://github.com/dry-rb/dry-configurable/compare/v0.9.0...v0.10.0)
|
76
|
+
|
77
|
+
## 0.9.0 2019-11-06
|
78
|
+
|
79
|
+
|
80
|
+
### Fixed
|
81
|
+
|
82
|
+
- Support for reserved names in settings. Some Kernel methods (`public_send` and `class` specifically) are not available if you use access settings via method call. Same for methods of the `Config` class. You can still access them with `[]` and `[]=`. Ruby keywords are fully supported. Invalid names containing special symbols (including `!` and `?`) are rejected. Note that these changes don't affect the `reader` option, if you define a setting named `:class` and pass `reader: true` ... well ... (flash-gordon)
|
83
|
+
- Settings can be redefined in subclasses without a warning about overriding exsting methods (flash-gordon)
|
84
|
+
- Fix warnings about using keyword arguments in 2.7 (koic)
|
85
|
+
|
86
|
+
|
87
|
+
[Compare v0.8.3...v0.9.0](https://github.com/dry-rb/dry-configurable/compare/v0.8.3...v0.9.0)
|
88
|
+
|
89
|
+
## 0.8.3 2019-05-29
|
90
|
+
|
91
|
+
|
92
|
+
### Fixed
|
93
|
+
|
94
|
+
- `Configurable#dup` and `Configurable#clone` make a copy of instance-level config so that it doesn't get mutated/shared across instances (flash-gordon)
|
95
|
+
|
96
|
+
|
97
|
+
[Compare v0.8.2...v0.8.3](https://github.com/dry-rb/dry-configurable/compare/v0.8.2...v0.8.3)
|
98
|
+
|
99
|
+
## 0.8.2 2019-02-25
|
100
|
+
|
101
|
+
|
102
|
+
### Fixed
|
103
|
+
|
104
|
+
- Test interface support for modules ([Neznauy](https://github.com/Neznauy))
|
105
|
+
|
106
|
+
|
107
|
+
[Compare v0.8.1...v0.8.2](https://github.com/dry-rb/dry-configurable/compare/v0.8.1...v0.8.2)
|
108
|
+
|
109
|
+
## 0.8.1 2019-02-06
|
110
|
+
|
111
|
+
|
112
|
+
### Fixed
|
113
|
+
|
114
|
+
- `.configure` doesn't require a block, this makes the behavior consistent with the previous versions ([flash-gordon](https://github.com/flash-gordon))
|
115
|
+
|
116
|
+
|
117
|
+
[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-configurable/compare/v0.8.0...v0.8.1)
|
118
|
+
|
119
|
+
## 0.8.0 2019-02-05
|
120
|
+
|
121
|
+
|
122
|
+
### Added
|
123
|
+
|
124
|
+
- Support for instance-level configuration landed. For usage, `include` the module instead of extending ([flash-gordon](https://github.com/flash-gordon))
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class App
|
128
|
+
include Dry::Configurable
|
129
|
+
|
130
|
+
setting :database
|
131
|
+
end
|
132
|
+
|
133
|
+
production = App.new
|
134
|
+
production.config.database = ENV['DATABASE_URL']
|
135
|
+
production.finalize!
|
136
|
+
|
137
|
+
development = App.new
|
138
|
+
development.config.database = 'jdbc:sqlite:memory'
|
139
|
+
development.finalize!
|
140
|
+
```
|
141
|
+
- Config values can be set from a hash with `.update`. Nested settings are supported ([flash-gordon](https://github.com/flash-gordon))
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
class App
|
145
|
+
extend Dry::Configurable
|
146
|
+
|
147
|
+
setting :db do
|
148
|
+
setting :host
|
149
|
+
setting :port
|
150
|
+
end
|
151
|
+
|
152
|
+
config.update(YAML.load(File.read("config.yml")))
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
156
|
+
### Fixed
|
157
|
+
|
158
|
+
- A number of bugs related to inheriting settings from parent class were fixed. Ideally, new behavior will be :100: predictable but if you observe any anomaly, please report ([flash-gordon](https://github.com/flash-gordon))
|
159
|
+
|
160
|
+
### Changed
|
161
|
+
|
162
|
+
- [BREAKING] Minimal supported Ruby version is set to 2.3 ([flash-gordon](https://github.com/flash-gordon))
|
163
|
+
|
164
|
+
[Compare v0.7.0...v0.8.0](https://github.com/dry-rb/dry-configurable/compare/v0.7.0...v0.8.0)
|
165
|
+
|
166
|
+
## 0.7.0 2017-04-25
|
167
|
+
|
168
|
+
|
169
|
+
### Added
|
170
|
+
|
171
|
+
- Introduce `Configurable.finalize!` which freezes config and its dependencies ([qcam](https://github.com/qcam))
|
172
|
+
|
173
|
+
### Fixed
|
174
|
+
|
175
|
+
- Allow for boolean false as default setting value ([yuszuv](https://github.com/yuszuv))
|
176
|
+
- Convert nested configs to nested hashes with `Config#to_h` ([saverio-kantox](https://github.com/saverio-kantox))
|
177
|
+
- Disallow modification on frozen config ([qcam](https://github.com/qcam))
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015-2020 dry-rb team
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
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, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
[gem]: https://rubygems.org/gems/dry-configurable
|
2
|
+
[actions]: https://github.com/dry-rb/dry-configurable/actions
|
3
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-configurable
|
4
|
+
[chat]: https://dry-rb.zulipchat.com
|
5
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-configurable
|
6
|
+
|
7
|
+
# dry-configurable [][chat]
|
8
|
+
|
9
|
+
[][gem]
|
10
|
+
[][actions]
|
11
|
+
[][codacy]
|
12
|
+
[][codacy]
|
13
|
+
[][inchpages]
|
14
|
+
|
15
|
+
## Links
|
16
|
+
|
17
|
+
* [User documentation](http://dry-rb.org/gems/dry-configurable)
|
18
|
+
* [API documentation](http://rubydoc.info/gems/dry-configurable)
|
19
|
+
|
20
|
+
## Supported Ruby versions
|
21
|
+
|
22
|
+
This library officially supports the following Ruby versions:
|
23
|
+
|
24
|
+
* MRI >= `2.4`
|
25
|
+
* jruby >= `9.2`
|
26
|
+
|
27
|
+
## License
|
28
|
+
|
29
|
+
See `LICENSE` file.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# this file is managed by dry-rb/devtools project
|
3
|
+
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require 'dry/configurable/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'dry-configurable'
|
10
|
+
spec.authors = ["Andy Holland"]
|
11
|
+
spec.email = ["andyholland1991@aol.com"]
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.version = Dry::Configurable::VERSION.dup
|
14
|
+
|
15
|
+
spec.summary = "A mixin to add configuration functionality to your classes"
|
16
|
+
spec.description = spec.summary
|
17
|
+
spec.homepage = 'https://dry-rb.org/gems/dry-configurable'
|
18
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-configurable.gemspec", "lib/**/*"]
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = []
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-configurable/blob/master/CHANGELOG.md'
|
25
|
+
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-configurable'
|
26
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-configurable/issues'
|
27
|
+
|
28
|
+
spec.required_ruby_version = ">= 2.4.0"
|
29
|
+
|
30
|
+
# to update dependencies edit project.yml
|
31
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
32
|
+
spec.add_runtime_dependency "dry-core", "~> 0.4", ">= 0.4.7"
|
33
|
+
spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
|
34
|
+
|
35
|
+
spec.add_development_dependency "bundler"
|
36
|
+
spec.add_development_dependency "rake"
|
37
|
+
spec.add_development_dependency "rspec"
|
38
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'concurrent/array'
|
4
|
+
|
5
|
+
require 'dry/configurable/constants'
|
6
|
+
require 'dry/configurable/class_methods'
|
7
|
+
require 'dry/configurable/instance_methods'
|
8
|
+
require 'dry/configurable/config'
|
9
|
+
require 'dry/configurable/setting'
|
10
|
+
|
11
|
+
module Dry
|
12
|
+
# A simple configuration mixin
|
13
|
+
#
|
14
|
+
# @example class-level configuration
|
15
|
+
#
|
16
|
+
# class App
|
17
|
+
# extend Dry::Configurable
|
18
|
+
#
|
19
|
+
# setting :database do
|
20
|
+
# setting :dsn, 'sqlite:memory'
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# App.config.database.dsn = 'jdbc:sqlite:memory'
|
25
|
+
# App.config.database.dsn
|
26
|
+
# # => "jdbc:sqlite:memory"
|
27
|
+
#
|
28
|
+
# @example instance-level configuration
|
29
|
+
#
|
30
|
+
# class App
|
31
|
+
# include Dry::Configurable
|
32
|
+
#
|
33
|
+
# setting :database
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# production = App.new
|
37
|
+
# production.config.database = ENV['DATABASE_URL']
|
38
|
+
# production.finalize!
|
39
|
+
#
|
40
|
+
# development = App.new
|
41
|
+
# development.config.database = 'jdbc:sqlite:memory'
|
42
|
+
# development.finalize!
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
module Configurable
|
46
|
+
# @api private
|
47
|
+
def self.extended(klass)
|
48
|
+
super
|
49
|
+
klass.extend(ClassMethods)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def self.included(klass)
|
54
|
+
super
|
55
|
+
klass.class_eval do
|
56
|
+
extend(ClassMethods)
|
57
|
+
include(InstanceMethods)
|
58
|
+
|
59
|
+
class << self
|
60
|
+
undef :config
|
61
|
+
undef :configure
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'dry/configurable/constants'
|
6
|
+
require 'dry/configurable/dsl'
|
7
|
+
require 'dry/configurable/methods'
|
8
|
+
require 'dry/configurable/settings'
|
9
|
+
|
10
|
+
module Dry
|
11
|
+
module Configurable
|
12
|
+
module ClassMethods
|
13
|
+
include Methods
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
def inherited(klass)
|
17
|
+
super
|
18
|
+
|
19
|
+
parent_settings = (respond_to?(:config) ? config._settings : _settings)
|
20
|
+
|
21
|
+
klass.instance_variable_set('@_settings', parent_settings)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add a setting to the configuration
|
25
|
+
#
|
26
|
+
# @param [Mixed] key
|
27
|
+
# The accessor key for the configuration value
|
28
|
+
# @param [Mixed] default
|
29
|
+
# The default config value
|
30
|
+
#
|
31
|
+
# @yield
|
32
|
+
# If a block is given, it will be evaluated in the context of
|
33
|
+
# a new configuration class, and bound as the default value
|
34
|
+
#
|
35
|
+
# @return [Dry::Configurable::Config]
|
36
|
+
#
|
37
|
+
# @api public
|
38
|
+
def setting(*args, &block)
|
39
|
+
setting = __config_dsl__.setting(*args, &block)
|
40
|
+
|
41
|
+
_settings << setting
|
42
|
+
|
43
|
+
__config_reader__.define(setting.name) if setting.reader?
|
44
|
+
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return declared settings
|
49
|
+
#
|
50
|
+
# @return [Set<Symbol>]
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
def settings
|
54
|
+
@settings ||= Set[*_settings.map(&:name)]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return declared settings
|
58
|
+
#
|
59
|
+
# @return [Settings]
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
def _settings
|
63
|
+
@_settings ||= Settings.new
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return configuration
|
67
|
+
#
|
68
|
+
# @return [Config]
|
69
|
+
#
|
70
|
+
# @api public
|
71
|
+
def config
|
72
|
+
@config ||= Config.new(_settings)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @api private
|
76
|
+
def __config_dsl__
|
77
|
+
@dsl ||= DSL.new
|
78
|
+
end
|
79
|
+
|
80
|
+
# @api private
|
81
|
+
def __config_reader__
|
82
|
+
@__config_reader__ ||=
|
83
|
+
begin
|
84
|
+
reader = Module.new do
|
85
|
+
def self.define(name)
|
86
|
+
define_method(name) do
|
87
|
+
config[name]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
if included_modules.include?(InstanceMethods)
|
93
|
+
include(reader)
|
94
|
+
end
|
95
|
+
|
96
|
+
extend(reader)
|
97
|
+
|
98
|
+
reader
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/configurable/setting'
|
4
|
+
require 'dry/configurable/settings'
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Configurable
|
8
|
+
# Setting compiler used internally by the DSL
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Compiler
|
12
|
+
def call(ast)
|
13
|
+
Settings.new.tap do |settings|
|
14
|
+
ast.each do |node|
|
15
|
+
settings << visit(node)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def visit(node)
|
22
|
+
type, rest = node
|
23
|
+
public_send(:"visit_#{type}", rest)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
def visit_constructor(node)
|
28
|
+
setting, constructor = node
|
29
|
+
visit(setting).with(constructor: constructor)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def visit_setting(node)
|
34
|
+
name, default, opts = node
|
35
|
+
Setting.new(name, **opts, default: default)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def visit_nested(node)
|
40
|
+
parent, children = node
|
41
|
+
visit(parent).nested(call(children))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'concurrent/map'
|
4
|
+
|
5
|
+
require 'dry/equalizer'
|
6
|
+
|
7
|
+
require 'dry/configurable/constants'
|
8
|
+
require 'dry/configurable/errors'
|
9
|
+
|
10
|
+
module Dry
|
11
|
+
module Configurable
|
12
|
+
# Config exposes setting values through a convenient API
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
class Config
|
16
|
+
include Dry::Equalizer(:values)
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
attr_reader :_settings
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
attr_reader :_resolved
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
def initialize(settings)
|
26
|
+
@_settings = settings.dup
|
27
|
+
@_resolved = Concurrent::Map.new
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get config value by a key
|
31
|
+
#
|
32
|
+
# @param [String,Symbol] name
|
33
|
+
#
|
34
|
+
# @return Config value
|
35
|
+
def [](name)
|
36
|
+
name = name.to_sym
|
37
|
+
raise ArgumentError, "+#{name}+ is not a setting name" unless _settings.key?(name)
|
38
|
+
|
39
|
+
_settings[name].value
|
40
|
+
end
|
41
|
+
|
42
|
+
# Set config value.
|
43
|
+
# Note that finalized configs cannot be changed.
|
44
|
+
#
|
45
|
+
# @param [String,Symbol] name
|
46
|
+
# @param [Object] value
|
47
|
+
def []=(name, value)
|
48
|
+
public_send(:"#{name}=", value)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Update config with new values
|
52
|
+
#
|
53
|
+
# @param values [Hash] A hash with new values
|
54
|
+
#
|
55
|
+
# @return [Config]
|
56
|
+
#
|
57
|
+
# @api public
|
58
|
+
def update(values)
|
59
|
+
values.each do |key, value|
|
60
|
+
case value
|
61
|
+
when Hash
|
62
|
+
self[key].update(value)
|
63
|
+
else
|
64
|
+
self[key] = value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
# Dump config into a hash
|
71
|
+
#
|
72
|
+
# @return [Hash]
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def values
|
76
|
+
_settings
|
77
|
+
.map { |setting| [setting.name, setting.value] }
|
78
|
+
.map { |key, value| [key, value.is_a?(self.class) ? value.to_h : value] }
|
79
|
+
.to_h
|
80
|
+
end
|
81
|
+
alias_method :to_h, :values
|
82
|
+
alias_method :to_hash, :values
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
def finalize!
|
86
|
+
_settings.freeze
|
87
|
+
freeze
|
88
|
+
end
|
89
|
+
|
90
|
+
# @api private
|
91
|
+
def pristine
|
92
|
+
self.class.new(_settings.pristine)
|
93
|
+
end
|
94
|
+
|
95
|
+
# @api private
|
96
|
+
def respond_to_missing?(meth, include_private = false)
|
97
|
+
super || _settings.key?(resolve(meth))
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# @api private
|
103
|
+
def method_missing(meth, *args)
|
104
|
+
setting = _settings[resolve(meth)]
|
105
|
+
|
106
|
+
super unless setting
|
107
|
+
|
108
|
+
if setting.writer?(meth)
|
109
|
+
raise FrozenConfig, 'Cannot modify frozen config' if frozen?
|
110
|
+
|
111
|
+
_settings << setting.with(input: args[0])
|
112
|
+
else
|
113
|
+
setting.value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
def resolve(meth)
|
119
|
+
_resolved.fetch(meth) { _resolved[meth] = meth.to_s.tr('=', '').to_sym }
|
120
|
+
end
|
121
|
+
|
122
|
+
# @api private
|
123
|
+
def initialize_copy(source)
|
124
|
+
super
|
125
|
+
@_settings = source._settings.dup
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/configurable/constants'
|
4
|
+
require 'dry/configurable/setting'
|
5
|
+
require 'dry/configurable/settings'
|
6
|
+
require 'dry/configurable/compiler'
|
7
|
+
require 'dry/configurable/dsl/args'
|
8
|
+
|
9
|
+
module Dry
|
10
|
+
module Configurable
|
11
|
+
# Setting DSL used by the class API
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class DSL
|
15
|
+
VALID_NAME = /\A[a-z_]\w*\z/i.freeze
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
attr_reader :compiler
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
attr_reader :ast
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
def initialize(&block)
|
25
|
+
@compiler = Compiler.new
|
26
|
+
@ast = []
|
27
|
+
instance_exec(&block) if block
|
28
|
+
end
|
29
|
+
|
30
|
+
# Register a new setting node and compile it into a setting object
|
31
|
+
#
|
32
|
+
# @see ClassMethods.setting
|
33
|
+
# @api public
|
34
|
+
# @return Setting
|
35
|
+
def setting(name, *args, &block)
|
36
|
+
unless VALID_NAME.match?(name.to_s)
|
37
|
+
raise ArgumentError, "#{name} is not a valid setting name"
|
38
|
+
end
|
39
|
+
|
40
|
+
args = Args.new(args)
|
41
|
+
|
42
|
+
args.ensure_valid_options
|
43
|
+
|
44
|
+
default, opts = args
|
45
|
+
|
46
|
+
node = [:setting, [name.to_sym, default, opts == default ? EMPTY_HASH : opts]]
|
47
|
+
|
48
|
+
if block
|
49
|
+
if block.arity.zero?
|
50
|
+
ast << [:nested, [node, DSL.new(&block).ast]]
|
51
|
+
else
|
52
|
+
ast << [:constructor, [node, block]]
|
53
|
+
end
|
54
|
+
else
|
55
|
+
ast << node
|
56
|
+
end
|
57
|
+
|
58
|
+
compiler.visit(ast.last)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/configurable/constants'
|
4
|
+
require 'dry/configurable/setting'
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Configurable
|
8
|
+
class DSL
|
9
|
+
# @api private
|
10
|
+
class Args
|
11
|
+
# @api private
|
12
|
+
attr_reader :args
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
attr_reader :size
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
attr_reader :opts
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def initialize(args)
|
22
|
+
@args = args
|
23
|
+
@size = args.size
|
24
|
+
@opts = Setting::OPTIONS
|
25
|
+
end
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
def ensure_valid_options
|
29
|
+
return unless options
|
30
|
+
|
31
|
+
keys = options.keys - opts
|
32
|
+
raise ArgumentError, "Invalid options: #{keys.inspect}" unless keys.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
# @api private
|
36
|
+
def to_ary
|
37
|
+
[default, options || EMPTY_HASH]
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
def default
|
42
|
+
if size.equal?(1) && options.nil?
|
43
|
+
args[0]
|
44
|
+
elsif size > 1 && options
|
45
|
+
args[0]
|
46
|
+
else
|
47
|
+
Undefined
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def options
|
53
|
+
args.detect { |arg| arg.is_a?(Hash) && (opts & arg.keys).any? }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/configurable/config'
|
4
|
+
require 'dry/configurable/methods'
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Configurable
|
8
|
+
# Instance-level API when `Dry::Configurable` is included in a class
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
module InstanceMethods
|
12
|
+
include Methods
|
13
|
+
|
14
|
+
# Return object's configuration
|
15
|
+
#
|
16
|
+
# @return [Config]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
attr_reader :config
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def initialize(*)
|
23
|
+
@config = Config.new(self.class._settings.dup)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
# Finalize the config and freeze the object
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
def finalize!
|
31
|
+
return self if frozen?
|
32
|
+
|
33
|
+
super
|
34
|
+
freeze
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# @api public
|
40
|
+
def initialize_copy(source)
|
41
|
+
super
|
42
|
+
@config = source.config.dup
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/configurable/errors'
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Configurable
|
7
|
+
# Common API for both classes and instances
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
module Methods
|
11
|
+
# @api public
|
12
|
+
def configure(&block)
|
13
|
+
raise FrozenConfig, 'Cannot modify frozen config' if frozen?
|
14
|
+
|
15
|
+
yield(config) if block
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Finalize and freeze configuration
|
20
|
+
#
|
21
|
+
# @return [Dry::Configurable::Config]
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
def finalize!
|
25
|
+
return self if config.frozen?
|
26
|
+
|
27
|
+
config.finalize!
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'dry/equalizer'
|
6
|
+
|
7
|
+
require 'dry/configurable/constants'
|
8
|
+
require 'dry/configurable/config'
|
9
|
+
|
10
|
+
module Dry
|
11
|
+
module Configurable
|
12
|
+
# This class represents a setting and is used internally.
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
class Setting
|
16
|
+
include Dry::Equalizer(:name, :value, :options, inspect: false)
|
17
|
+
|
18
|
+
OPTIONS = %i[input default reader constructor settings].freeze
|
19
|
+
|
20
|
+
DEFAULT_CONSTRUCTOR = -> v { v }.freeze
|
21
|
+
|
22
|
+
CLONABLE_VALUE_TYPES = [Array, Hash, Set, Config].freeze
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
attr_reader :name
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
attr_reader :writer_name
|
29
|
+
|
30
|
+
# @api private
|
31
|
+
attr_reader :input
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
attr_reader :default
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
attr_reader :options
|
38
|
+
|
39
|
+
# Specialized Setting which includes nested settings
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
class Nested < Setting
|
43
|
+
CONSTRUCTOR = Config.method(:new)
|
44
|
+
|
45
|
+
# @api private
|
46
|
+
def pristine
|
47
|
+
with(input: input.pristine)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @api private
|
51
|
+
def constructor
|
52
|
+
CONSTRUCTOR
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def initialize(name, input: Undefined, default: Undefined, **options)
|
58
|
+
@name = name
|
59
|
+
@writer_name = :"#{name}="
|
60
|
+
@input = input.equal?(Undefined) ? default : input
|
61
|
+
@default = default
|
62
|
+
@options = options
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
def input_defined?
|
67
|
+
!input.equal?(Undefined)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @api private
|
71
|
+
def value
|
72
|
+
@value ||= evaluate
|
73
|
+
end
|
74
|
+
|
75
|
+
# @api private
|
76
|
+
def evaluated?
|
77
|
+
instance_variable_defined?(:@value)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @api private
|
81
|
+
def nested(settings)
|
82
|
+
Nested.new(name, input: settings, **options)
|
83
|
+
end
|
84
|
+
|
85
|
+
# @api private
|
86
|
+
def pristine
|
87
|
+
with(input: Undefined)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @api private
|
91
|
+
def with(new_opts)
|
92
|
+
self.class.new(name, input: input, default: default, **options, **new_opts)
|
93
|
+
end
|
94
|
+
|
95
|
+
# @api private
|
96
|
+
def constructor
|
97
|
+
options[:constructor] || DEFAULT_CONSTRUCTOR
|
98
|
+
end
|
99
|
+
|
100
|
+
# @api private
|
101
|
+
def reader?
|
102
|
+
options[:reader].equal?(true)
|
103
|
+
end
|
104
|
+
|
105
|
+
# @api private
|
106
|
+
def writer?(meth)
|
107
|
+
writer_name.equal?(meth)
|
108
|
+
end
|
109
|
+
|
110
|
+
# @api private
|
111
|
+
def clonable_value?
|
112
|
+
CLONABLE_VALUE_TYPES.any? { |type| value.is_a?(type) }
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
def initialize_copy(source)
|
119
|
+
super
|
120
|
+
@value = source.value.dup if source.input_defined? && source.clonable_value?
|
121
|
+
@options = source.options.dup
|
122
|
+
end
|
123
|
+
|
124
|
+
# @api private
|
125
|
+
def evaluate
|
126
|
+
@value = constructor[input.equal?(Undefined) ? nil : input]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'concurrent/map'
|
4
|
+
|
5
|
+
require 'dry/equalizer'
|
6
|
+
require 'dry/configurable/constants'
|
7
|
+
|
8
|
+
module Dry
|
9
|
+
module Configurable
|
10
|
+
# A settings map
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
class Settings
|
14
|
+
include Dry::Equalizer(:elements)
|
15
|
+
|
16
|
+
include Enumerable
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
attr_reader :elements
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def initialize(elements = EMPTY_ARRAY)
|
23
|
+
initialize_elements(elements)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
def <<(setting)
|
28
|
+
elements[setting.name] = setting
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def [](name)
|
34
|
+
elements[name]
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def key?(name)
|
39
|
+
keys.include?(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def keys
|
44
|
+
elements.keys
|
45
|
+
end
|
46
|
+
|
47
|
+
# @api private
|
48
|
+
def each(&block)
|
49
|
+
elements.values.each(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def pristine
|
54
|
+
self.class.new(map(&:pristine))
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# @api private
|
60
|
+
def initialize_copy(source)
|
61
|
+
initialize_elements(source.map(&:dup))
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def initialize_elements(elements)
|
66
|
+
@elements = elements.each_with_object(Concurrent::Map.new) { |s, m|
|
67
|
+
m[s.name] = s
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Configurable
|
5
|
+
# Methods meant to be used in a testing scenario
|
6
|
+
module TestInterface
|
7
|
+
# Resets configuration to default values
|
8
|
+
#
|
9
|
+
# @return [Dry::Configurable::Config]
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
def reset_config
|
13
|
+
@config = config.pristine
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Mixes in test interface into the configurable module
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
def enable_test_interface
|
21
|
+
extend Dry::Configurable::TestInterface
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dry-configurable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.11.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andy Holland
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: concurrent-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.4'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.4.7
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0.4'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.4.7
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: dry-equalizer
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.2'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.2'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
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'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
description: A mixin to add configuration functionality to your classes
|
104
|
+
email:
|
105
|
+
- andyholland1991@aol.com
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- CHANGELOG.md
|
111
|
+
- LICENSE
|
112
|
+
- README.md
|
113
|
+
- dry-configurable.gemspec
|
114
|
+
- lib/dry-configurable.rb
|
115
|
+
- lib/dry/configurable.rb
|
116
|
+
- lib/dry/configurable/class_methods.rb
|
117
|
+
- lib/dry/configurable/compiler.rb
|
118
|
+
- lib/dry/configurable/config.rb
|
119
|
+
- lib/dry/configurable/constants.rb
|
120
|
+
- lib/dry/configurable/dsl.rb
|
121
|
+
- lib/dry/configurable/dsl/args.rb
|
122
|
+
- lib/dry/configurable/errors.rb
|
123
|
+
- lib/dry/configurable/instance_methods.rb
|
124
|
+
- lib/dry/configurable/methods.rb
|
125
|
+
- lib/dry/configurable/setting.rb
|
126
|
+
- lib/dry/configurable/settings.rb
|
127
|
+
- lib/dry/configurable/test_interface.rb
|
128
|
+
- lib/dry/configurable/version.rb
|
129
|
+
homepage: https://dry-rb.org/gems/dry-configurable
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata:
|
133
|
+
allowed_push_host: https://rubygems.org
|
134
|
+
changelog_uri: https://github.com/dry-rb/dry-configurable/blob/master/CHANGELOG.md
|
135
|
+
source_code_uri: https://github.com/dry-rb/dry-configurable
|
136
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-configurable/issues
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.4.0
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubygems_version: 3.0.3
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: A mixin to add configuration functionality to your classes
|
156
|
+
test_files: []
|