qonfig 0.0.0 → 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 +4 -4
- data/.gitignore +3 -2
- data/.jrubyrc +1 -0
- data/.rspec +1 -1
- data/.rubocop.yml +74 -0
- data/.travis.yml +10 -2
- data/CHANGELOG.md +5 -0
- data/README.md +214 -20
- data/Rakefile +4 -2
- data/bin/console +4 -11
- data/bin/setup +1 -0
- data/lib/qonfig/command_set.rb +47 -0
- data/lib/qonfig/commands/add_nested_option.rb +46 -0
- data/lib/qonfig/commands/add_option.rb +40 -0
- data/lib/qonfig/commands/base.rb +16 -0
- data/lib/qonfig/commands/compose.rb +34 -0
- data/lib/qonfig/data_set.rb +47 -0
- data/lib/qonfig/dsl.rb +61 -0
- data/lib/qonfig/error.rb +19 -0
- data/lib/qonfig/settings.rb +157 -0
- data/lib/qonfig/settings_builder.rb +20 -0
- data/lib/qonfig/version.rb +5 -1
- data/lib/qonfig.rb +11 -2
- data/qonfig.gemspec +30 -17
- metadata +113 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d774926f0d94544e9d256b7c3e06bbc51b16a51a1323fbcb1f020a1c377ffaf7
|
4
|
+
data.tar.gz: a3d2769d42ba24938db56bd853f65b041a7053af462644a6d4e3ac3109c3b121
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82ac7dd98fdccf5ab5ba846a9c733fbb8e3523676a23b390aca49c587e01b1cf9c76602d5909cda2736c7e4d572ffe219b85e3f7267f4499051c579a5bf59997
|
7
|
+
data.tar.gz: 747f86b8b8f8f2a348ae906e0e3e75a37f45afd896874ee1eb56aa7b66ee6a4c4581d48fbbe3d7d203879c345ff0894ca780f12a5bcbd660b421f7e202c29028
|
data/.gitignore
CHANGED
data/.jrubyrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
debug.fullTrace=true
|
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
DisplayCopNames: true
|
5
|
+
DisplayStyleGuide: true
|
6
|
+
TargetRubyVersion: 2.5.1
|
7
|
+
Include:
|
8
|
+
- lib/**/*
|
9
|
+
- spec/**/*
|
10
|
+
Exclude:
|
11
|
+
- bin/**/*
|
12
|
+
- Gemfile
|
13
|
+
- Rakefile
|
14
|
+
- qonfig.gemspec
|
15
|
+
|
16
|
+
Style/SingleLineMethods:
|
17
|
+
Exclude:
|
18
|
+
- spec/**/*
|
19
|
+
|
20
|
+
Style/RescueModifier:
|
21
|
+
Exclude:
|
22
|
+
- spec/**/*
|
23
|
+
|
24
|
+
Style/IfUnlessModifier:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Metrics/BlockLength:
|
28
|
+
Exclude:
|
29
|
+
- spec/**/*
|
30
|
+
|
31
|
+
Naming/VariableNumber:
|
32
|
+
EnforcedStyle: snake_case
|
33
|
+
|
34
|
+
Style/AsciiComments:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Layout/IndentArray:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/Documentation:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
RSpec/DescribeClass:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/ConditionalAssignment:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Metrics/LineLength:
|
50
|
+
Max: 100
|
51
|
+
|
52
|
+
Style/Alias:
|
53
|
+
EnforcedStyle: prefer_alias_method
|
54
|
+
|
55
|
+
Style/MultilineIfModifier:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Lint/HandleExceptions:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Metrics/MethodLength:
|
62
|
+
Max: 20
|
63
|
+
|
64
|
+
Style/EmptyCaseCondition:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
RSpec/ExampleLength:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
RSpec/MultipleExpectations:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Metrics/AbcSize:
|
74
|
+
Max: 17
|
data/.travis.yml
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
rvm:
|
3
|
+
- 2.2.10
|
4
|
+
- 2.3.7
|
5
|
+
- 2.4.4
|
4
6
|
- 2.5.1
|
5
|
-
|
7
|
+
- ruby-head
|
8
|
+
- jruby-head
|
9
|
+
|
10
|
+
sudo: false
|
11
|
+
cache: bundler
|
12
|
+
before_install: gem install bundler
|
13
|
+
script: bundle exec rspec
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,43 +1,237 @@
|
|
1
|
-
# Qonfig
|
1
|
+
# Qonfig · [](https://badge.fury.io/rb/qonfig) [](https://travis-ci.org/0exp/qonfig) [](https://coveralls.io/github/0exp/qonfig)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
Config. Defined as a class. Used as an instance. Support for inheritance and composition.
|
4
|
+
Lazy instantiation. Command-style DSL. Extremely simple to define. Extremely simple to use. That's all.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
8
|
```ruby
|
12
9
|
gem 'qonfig'
|
13
10
|
```
|
14
11
|
|
15
|
-
|
12
|
+
```shell
|
13
|
+
$ bundle install
|
14
|
+
# --- or ---
|
15
|
+
gem install 'qonfig'
|
16
|
+
```
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'qonfig'
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
16
23
|
|
17
|
-
|
24
|
+
- [Definition and Access](#definition-and-access)
|
25
|
+
- [Configuration](#configuration)
|
26
|
+
- [Inheritance](#inheritance)
|
27
|
+
- [Composition](#composition)
|
28
|
+
- [Hash representation](#hash-representation)
|
29
|
+
- [State freeze](#state-freeze)
|
18
30
|
|
19
|
-
|
31
|
+
---
|
20
32
|
|
21
|
-
|
33
|
+
### Definition and Access
|
22
34
|
|
23
|
-
|
35
|
+
```ruby
|
36
|
+
class Config < Qonfig::DataSet
|
37
|
+
# nil by default
|
38
|
+
setting :project_id
|
39
|
+
|
40
|
+
# nested setting
|
41
|
+
setting :vendor_api do
|
42
|
+
setting :host, 'app.service.com'
|
43
|
+
setting :port, 12345
|
44
|
+
end
|
45
|
+
|
46
|
+
setting :enable_graphql, false
|
47
|
+
|
48
|
+
# nested setting reopening
|
49
|
+
setting :vendor_api do
|
50
|
+
setting :user, 'test_user'
|
51
|
+
setting :password, 'test_password'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
config = Config.new
|
56
|
+
|
57
|
+
config.settings.project_id # => nil
|
58
|
+
config.settings.vendor_api.host # => 'api.service.com'
|
59
|
+
config.settings.vendor_api.port # => 12345
|
60
|
+
config.settings.vendor_api.user # => 'test_user'
|
61
|
+
config.settings.vendor_api.password # => 'test_password'
|
62
|
+
config.settings.enable_graphql # => false
|
63
|
+
|
64
|
+
config.settings[:project_id] # => nil
|
65
|
+
config.settings[:vendor_api][:host] # => 'api.service.com'
|
66
|
+
config.settings[:vendor_api][:port] # => 12345
|
67
|
+
config.settings[:vendor_api][:user] # => 'test_user'
|
68
|
+
config.settings[:vendor_api][:password] # => 'test_password'
|
69
|
+
config.settings[:enable_graphql] # => false
|
70
|
+
```
|
71
|
+
|
72
|
+
---
|
73
|
+
|
74
|
+
### Configuration
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class Config < Qonfig::DataSet
|
78
|
+
setting :testing do
|
79
|
+
setting :engine, :rspec
|
80
|
+
setting :parallel, true
|
81
|
+
end
|
82
|
+
|
83
|
+
setting :geo_api do
|
84
|
+
setting :provider, :google_maps
|
85
|
+
end
|
86
|
+
|
87
|
+
setting :enable_middlewares, false
|
88
|
+
end
|
89
|
+
|
90
|
+
config = Config.new
|
91
|
+
|
92
|
+
# configure via block
|
93
|
+
config.configure do |conf|
|
94
|
+
conf.enable_middlewares = true
|
95
|
+
conf.geo_api.provider = :yandex_maps
|
96
|
+
conf.testing.engine = :mini_test
|
97
|
+
end
|
98
|
+
|
99
|
+
# configure via settings object (by option name)
|
100
|
+
config.settings.enable_middlewares = false
|
101
|
+
config.settings.geo_api.provider = :apple_maps
|
102
|
+
config.settings.testing.engine = :ultra_test
|
103
|
+
|
104
|
+
# configure via settings object (by setting key)
|
105
|
+
config.settings[:enable_middlewares] = true
|
106
|
+
config.settings[:geo_api][:provider] = :rambler_maps
|
107
|
+
config.settings[:testing][:engine] = :mega_test
|
108
|
+
```
|
109
|
+
|
110
|
+
---
|
111
|
+
|
112
|
+
### Inheritance
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class CommonConfig < Qonfig::DataSet
|
116
|
+
setting :uploader, :fog
|
117
|
+
end
|
118
|
+
|
119
|
+
class ProjectConfig < CommonConfig
|
120
|
+
setting :auth_provider, :github
|
121
|
+
end
|
122
|
+
|
123
|
+
project_config = ProjectConfig.new
|
124
|
+
|
125
|
+
# inherited setting
|
126
|
+
project_config.settings.uploader # => :fog
|
24
127
|
|
25
|
-
|
128
|
+
# own setting
|
129
|
+
project_config.settings.auth_provider # => :github
|
130
|
+
```
|
131
|
+
|
132
|
+
---
|
133
|
+
|
134
|
+
### Composition
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
class SharedConfig < Qonfig::DataSet
|
138
|
+
setting :logger, Logger.new
|
139
|
+
end
|
140
|
+
|
141
|
+
class ServerConfig < Qonfig::DataSet
|
142
|
+
setting :port, 12345
|
143
|
+
setting :address, '0.0.0.0'
|
144
|
+
end
|
26
145
|
|
27
|
-
|
146
|
+
class DatabaseConfig < Qonfig::DataSet
|
147
|
+
setting :user, 'test'
|
148
|
+
setting :password, 'testpaswd'
|
149
|
+
end
|
28
150
|
|
29
|
-
|
151
|
+
class ProjectConfig < Qonfig::DataSet
|
152
|
+
compose SharedConfig
|
30
153
|
|
31
|
-
|
154
|
+
setting :server do
|
155
|
+
compose ServerConfig
|
156
|
+
end
|
157
|
+
|
158
|
+
setting :db do
|
159
|
+
compose DatabaseConfig
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
project_config = ProjectConfig.new
|
164
|
+
|
165
|
+
# fields from SharedConfig
|
166
|
+
project_config.settings.logger # => #<Logger:0x66f57048>
|
167
|
+
|
168
|
+
# fields from ServerConfig
|
169
|
+
project_config.settings.server.port # => 12345
|
170
|
+
project_config.settings.server.address # => '0.0.0.0'
|
171
|
+
|
172
|
+
# fields from DatabaseConfig
|
173
|
+
project_config.settings.db.user # => 'test'
|
174
|
+
project_config.settings.db.password # => 'testpaswd'
|
175
|
+
```
|
32
176
|
|
33
|
-
|
177
|
+
---
|
178
|
+
|
179
|
+
### Hash representation
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
class Config < Qonfig::DataSet
|
183
|
+
setting :serializers do
|
184
|
+
setting :json do
|
185
|
+
setting :engine, :ok
|
186
|
+
end
|
187
|
+
|
188
|
+
setting :hash do
|
189
|
+
setting :engine, :native
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
setting :adapter do
|
194
|
+
setting :default: :memory_sync
|
195
|
+
end
|
196
|
+
|
197
|
+
setting :logger, Logger.new(STDOUT)
|
198
|
+
end
|
199
|
+
|
200
|
+
Config.new.to_h
|
201
|
+
|
202
|
+
{
|
203
|
+
serializers: {
|
204
|
+
json: { engine: :ok },
|
205
|
+
hash: { engine: :native },
|
206
|
+
},
|
207
|
+
adapter: { default: :memory_sync },
|
208
|
+
logger: #<Logger:0x4b0d79fc>
|
209
|
+
}
|
210
|
+
```
|
211
|
+
|
212
|
+
---
|
213
|
+
|
214
|
+
### State freeze
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
class Config < Qonfig::DataSet
|
218
|
+
setting :logger, Logger.new(STDOUT)
|
219
|
+
setting :worker, :sidekiq
|
220
|
+
end
|
221
|
+
|
222
|
+
config = Config.new
|
223
|
+
config.freeze!
|
224
|
+
|
225
|
+
config.settings.logger = Logger.new(StringIO.new) # => Qonfig::FrozenSettingsError
|
226
|
+
config.settings.worker = :que # => Qonfig::FrozenSettingsError
|
227
|
+
```
|
34
228
|
|
35
|
-
|
229
|
+
---
|
36
230
|
|
37
231
|
## License
|
38
232
|
|
39
|
-
|
233
|
+
Released under MIT License.
|
40
234
|
|
41
|
-
##
|
235
|
+
## Authors
|
42
236
|
|
43
|
-
|
237
|
+
Rustam Ibragimov.
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'qonfig'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
6
|
+
require 'pry'
|
7
|
+
Pry.start
|
data/bin/setup
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class CommandSet
|
7
|
+
# @return [Array<Qonfig::Commands::Base>]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
attr_reader :commands
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
# @since 0.1.0
|
15
|
+
def initialize
|
16
|
+
@commands = []
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param command [Qonfig::Commands::Base]
|
20
|
+
# @return [void]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
# @since 0.1.0
|
24
|
+
def add_command(command)
|
25
|
+
commands << command
|
26
|
+
end
|
27
|
+
alias_method :<<, :add_command
|
28
|
+
|
29
|
+
# @param block [Proc]
|
30
|
+
# @return [Enumerable]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.1.0
|
34
|
+
def each(&block)
|
35
|
+
block_given? ? commands.each(&block) : commands.each
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param command_set [Qonfig::CommandSet]
|
39
|
+
# @return [Qonfig::CommandSet]
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
# @since 0.1.0
|
43
|
+
def concat(command_set)
|
44
|
+
commands.concat(command_set.commands)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
module Commands
|
5
|
+
# @api private
|
6
|
+
# @since 0.1.0
|
7
|
+
class AddNestedOption < Base
|
8
|
+
# @return [String,Symbol]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
attr_reader :key
|
13
|
+
|
14
|
+
# @return [Proc]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.1.0
|
18
|
+
attr_reader :nested_definitions
|
19
|
+
|
20
|
+
# @param key [String,Symbol]
|
21
|
+
# @param nested_definitions [Proc]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
# @since 0.1.0
|
25
|
+
def initialize(key, nested_definitions)
|
26
|
+
@key = key
|
27
|
+
@nested_definitions = nested_definitions
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param settings [Qonfig::Settings]
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @since 0.1.0
|
35
|
+
def call(settings)
|
36
|
+
nested_data_set = Class.new(Qonfig::DataSet).tap do |data_set|
|
37
|
+
data_set.instance_eval(&nested_definitions)
|
38
|
+
end
|
39
|
+
|
40
|
+
nested_settings = nested_data_set.new.settings
|
41
|
+
|
42
|
+
settings.__define_setting__(key, nested_settings)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
module Commands
|
5
|
+
# @api private
|
6
|
+
# @since 0.1.0
|
7
|
+
class AddOption < Base
|
8
|
+
# @return [String,Symbol]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
attr_reader :key
|
13
|
+
|
14
|
+
# @return [Object]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.1.0
|
18
|
+
attr_reader :value
|
19
|
+
|
20
|
+
# @param key [String,Symbol]
|
21
|
+
# @param value [Object]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
# @since 0.1.0
|
25
|
+
def initialize(key, value)
|
26
|
+
@key = key
|
27
|
+
@value = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param settings [Qonfig::Settings]
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @since 0.1.0
|
35
|
+
def call(settings)
|
36
|
+
settings.__define_setting__(key, value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
module Commands
|
5
|
+
# @api private
|
6
|
+
# @since 0.1.0
|
7
|
+
class Base
|
8
|
+
# @param settings [Qonfig::Settings]
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def call(settings); end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
module Commands
|
5
|
+
# @api private
|
6
|
+
# @since 0.1.0
|
7
|
+
class Compose < Base
|
8
|
+
# @return [Qonfig::DataSet]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
attr_reader :data_set_klass
|
13
|
+
|
14
|
+
# @param data_set_klass [Qonfig::DataSet]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.1.0
|
18
|
+
def initialize(data_set_klass)
|
19
|
+
@data_set_klass = data_set_klass
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param settings [Qonfig::Settings]
|
23
|
+
# @return [void]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @since 0.1.0
|
27
|
+
def call(settings)
|
28
|
+
composite_settings = data_set_klass.new.settings
|
29
|
+
|
30
|
+
settings.__append_settings__(composite_settings)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api public
|
5
|
+
# @since 0.1.0
|
6
|
+
class DataSet
|
7
|
+
# @since 0.1.0
|
8
|
+
extend Qonfig::DSL
|
9
|
+
|
10
|
+
# @return [Qonfig::Settings]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
attr_reader :settings
|
15
|
+
|
16
|
+
# @api public
|
17
|
+
# @since 0.1.0
|
18
|
+
def initialize
|
19
|
+
@settings = Qonfig::SettingsBuilder.build(self.class.commands)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [void]
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
# @since 0.1.0
|
26
|
+
def freeze!
|
27
|
+
settings.__freeze__
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
# @since 0.1.0
|
34
|
+
def configure
|
35
|
+
yield(settings) if block_given?
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Hash]
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
# @since 0.1.0
|
42
|
+
def to_h
|
43
|
+
settings.__to_hash__
|
44
|
+
end
|
45
|
+
alias_method :to_hash, :to_h
|
46
|
+
end
|
47
|
+
end
|
data/lib/qonfig/dsl.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
module DSL
|
7
|
+
class << self
|
8
|
+
# @param child_klass [Qonfig::DataSet]
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def extended(child_klass)
|
14
|
+
child_klass.instance_variable_set(:@commands, Qonfig::CommandSet.new)
|
15
|
+
|
16
|
+
class << child_klass
|
17
|
+
def inherited(child_klass)
|
18
|
+
child_klass.instance_variable_set(:@commands, Qonfig::CommandSet.new)
|
19
|
+
child_klass.commands.concat(commands)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Qonfig::CommandSet]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def commands
|
30
|
+
@commands
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param key [String,Symbol]
|
34
|
+
# @param initial_value [Object]
|
35
|
+
# @param nested_settings [Proc]
|
36
|
+
# @return [void]
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
# @since 0.1.0
|
40
|
+
def setting(key, initial_value = nil, &nested_settings)
|
41
|
+
unless key.is_a?(Symbol) || key.is_a?(String)
|
42
|
+
raise Qonfig::ArgumentError, 'Setting key should be a symbol or a string!'
|
43
|
+
end
|
44
|
+
|
45
|
+
if block_given?
|
46
|
+
commands << Qonfig::Commands::AddNestedOption.new(key, nested_settings)
|
47
|
+
else
|
48
|
+
commands << Qonfig::Commands::AddOption.new(key, initial_value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param data_set_klass [Class{Qonfig::DataSet}]
|
53
|
+
# @return [void]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
# @sine 0.1.0
|
57
|
+
def compose(data_set_klass)
|
58
|
+
commands << Qonfig::Commands::Compose.new(data_set_klass)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/qonfig/error.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api public
|
5
|
+
# @since 0.1.0
|
6
|
+
Error = Class.new(StandardError)
|
7
|
+
|
8
|
+
# @api public
|
9
|
+
# @since 0.1.0
|
10
|
+
ArgumentError = Class.new(Error)
|
11
|
+
|
12
|
+
# @api public
|
13
|
+
# @since 0.1.0
|
14
|
+
UnknownSettingError = Class.new(Error)
|
15
|
+
|
16
|
+
# @api public
|
17
|
+
# @since 0.1.0
|
18
|
+
FrozenSettingsError = Class.new(Error)
|
19
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Settings
|
7
|
+
# @return [Hash]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
attr_reader :__options__
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
# @since 0.1.0
|
15
|
+
def initialize
|
16
|
+
@__options__ = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param key [Symbol,String]
|
20
|
+
# @param value [Object]
|
21
|
+
# @return [void]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
# @since 0.1.0
|
25
|
+
def __define_setting__(key, value)
|
26
|
+
# :nocov:
|
27
|
+
unless key.is_a?(Symbol) || key.is_a?(String)
|
28
|
+
raise Qonfig::ArgumentError, 'Setting key should be a symbol or a string'
|
29
|
+
end
|
30
|
+
# :nocov:
|
31
|
+
|
32
|
+
case
|
33
|
+
when !__options__.key?(key)
|
34
|
+
__options__[key] = value
|
35
|
+
when __options__[key].is_a?(Qonfig::Settings) && value.is_a?(Qonfig::Settings)
|
36
|
+
__options__[key].__append_settings__(value)
|
37
|
+
else
|
38
|
+
__options__[key] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
__define_accessor__(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param settings [Qonfig::Settings]
|
45
|
+
# @return [void]
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
# @since 0.1.0
|
49
|
+
def __append_settings__(settings)
|
50
|
+
settings.__options__.each_pair do |key, value|
|
51
|
+
__define_setting__(key, value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param key [Symbol,String]
|
56
|
+
# @return [Object]
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
# @since 0.1.0
|
60
|
+
def [](key)
|
61
|
+
unless __options__.key?(key)
|
62
|
+
raise Qonfig::UnknownSettingError, "Setting with <#{key}> key does not exist!"
|
63
|
+
end
|
64
|
+
|
65
|
+
__options__[key]
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param key [String, Symbol]
|
69
|
+
# @param value [Object]
|
70
|
+
# @return [void]
|
71
|
+
#
|
72
|
+
# @api public
|
73
|
+
# @since 0.1.0
|
74
|
+
def []=(key, value)
|
75
|
+
unless __options__.key?(key)
|
76
|
+
raise Qonfig::UnknownSettingError, "Setting with <#{key}> key does not exist!"
|
77
|
+
end
|
78
|
+
|
79
|
+
if __options__.frozen?
|
80
|
+
raise Qonfig::FrozenSettingsError, 'Can not modify frozen Settings'
|
81
|
+
end
|
82
|
+
|
83
|
+
__options__[key] = value
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Hash]
|
87
|
+
#
|
88
|
+
# @api public
|
89
|
+
# @since 0.1.0
|
90
|
+
def __to_hash__
|
91
|
+
__options__.dup.tap do |hash|
|
92
|
+
__options__.each_pair do |key, value|
|
93
|
+
hash[key] = value.is_a?(Qonfig::Settings) ? value.__to_hash__ : value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param method_name [String, Symbol]
|
99
|
+
# @param arguments [Array<Object>]
|
100
|
+
# @param block [Proc]
|
101
|
+
# @return [void]
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
# @since 0.1.0
|
105
|
+
def method_missing(method_name, *arguments, &block)
|
106
|
+
super
|
107
|
+
rescue NoMethodError
|
108
|
+
raise Qonfig::UnknownSettingError, "Setting with <#{method_name}> ley doesnt exist!"
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Boolean]
|
112
|
+
#
|
113
|
+
# @api public
|
114
|
+
# @since 0.1.0
|
115
|
+
def respond_to_missing?(method_name, include_private = false)
|
116
|
+
# :nocov:
|
117
|
+
__options__.key?(method_name.to_s) || __options__.key?(method_name.to_sym) || super
|
118
|
+
# :nocov:
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [void]
|
122
|
+
#
|
123
|
+
# @api private
|
124
|
+
# @since 0.1.0
|
125
|
+
def __freeze__
|
126
|
+
__options__.freeze
|
127
|
+
|
128
|
+
__options__.each_value do |value|
|
129
|
+
value.__freeze__ if value.is_a?(Qonfig::Settings)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# @param key [Symbol,String]
|
136
|
+
# @return [Object]
|
137
|
+
#
|
138
|
+
# @api private
|
139
|
+
# @since 0.1.0
|
140
|
+
def __define_accessor__(key)
|
141
|
+
begin
|
142
|
+
singleton_class.send(:undef_method, key)
|
143
|
+
rescue NameError
|
144
|
+
end
|
145
|
+
|
146
|
+
begin
|
147
|
+
singleton_class.send(:undef_method, "#{key}=")
|
148
|
+
rescue NameError
|
149
|
+
end
|
150
|
+
|
151
|
+
define_singleton_method(key) { self.[](key) }
|
152
|
+
define_singleton_method("#{key}=") do |value|
|
153
|
+
self.[]=(key, value)
|
154
|
+
end unless __options__[key].is_a?(Qonfig::Settings)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qonfig
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
module SettingsBuilder
|
7
|
+
class << self
|
8
|
+
# @param [Qonfig::CommandSet]
|
9
|
+
# @return [Qonfig::Settings]
|
10
|
+
#
|
11
|
+
# @ api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def build(commands)
|
14
|
+
Qonfig::Settings.new.tap do |settings|
|
15
|
+
commands.each { |command| command.call(settings) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/qonfig/version.rb
CHANGED
data/lib/qonfig.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Qonfig
|
4
|
-
|
4
|
+
require_relative 'qonfig/error'
|
5
|
+
require_relative 'qonfig/commands/base'
|
6
|
+
require_relative 'qonfig/commands/add_option'
|
7
|
+
require_relative 'qonfig/commands/add_nested_option'
|
8
|
+
require_relative 'qonfig/commands/compose'
|
9
|
+
require_relative 'qonfig/command_set'
|
10
|
+
require_relative 'qonfig/settings'
|
11
|
+
require_relative 'qonfig/settings_builder'
|
12
|
+
require_relative 'qonfig/dsl'
|
13
|
+
require_relative 'qonfig/data_set'
|
5
14
|
end
|
data/qonfig.gemspec
CHANGED
@@ -1,27 +1,40 @@
|
|
1
|
+
# codning: utf-8
|
1
2
|
|
2
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'qonfig/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.
|
8
|
-
spec.version = Qonfig::VERSION
|
9
|
-
spec.authors = ["Rustam Ibragimov"]
|
10
|
-
spec.email = ["iamdaiver@icloud.com"]
|
8
|
+
spec.required_ruby_version = '>= 2.2.10'
|
11
9
|
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.
|
10
|
+
spec.name = 'qonfig'
|
11
|
+
spec.version = Qonfig::VERSION
|
12
|
+
spec.authors = ['Rustam Ibragimov']
|
13
|
+
spec.email = ['iamdaiver@icloud.com']
|
14
|
+
spec.summary = 'Config object'
|
15
|
+
spec.description = 'Config. Defined as a class. Used as an instance. ' \
|
16
|
+
'Support for inheritance and composition. ' \
|
17
|
+
'Command-style DSL. Lazy instantiation.' \
|
18
|
+
'Extremely simple to define. Extremely simple to use. That\'s all.'
|
19
|
+
spec.homepage = 'https://github.com/0exp/qonfig'
|
20
|
+
spec.license = 'MIT'
|
16
21
|
|
17
|
-
spec.
|
22
|
+
spec.bindir = 'bin'
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
27
|
f.match(%r{^(test|spec|features)/})
|
19
28
|
end
|
20
|
-
spec.bindir = "exe"
|
21
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = ["lib"]
|
23
29
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
30
|
+
spec.add_development_dependency 'coveralls', '~> 0.8'
|
31
|
+
spec.add_development_dependency 'simplecov', '~> 0.14'
|
32
|
+
spec.add_development_dependency 'simplecov-json', '~> 0.2'
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0.55'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.7'
|
35
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.25'
|
36
|
+
|
37
|
+
spec.add_development_dependency 'bundler'
|
38
|
+
spec.add_development_dependency 'rake'
|
39
|
+
spec.add_development_dependency 'pry'
|
27
40
|
end
|
metadata
CHANGED
@@ -1,58 +1,144 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qonfig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: coveralls
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0.8'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: simplecov
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0.14'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov-json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.55'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.55'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rspec
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
75
|
+
version: '3.7'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
55
|
-
|
82
|
+
version: '3.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.25'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.25'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Config. Defined as a class. Used as an instance. Support for inheritance
|
140
|
+
and composition. Command-style DSL. Lazy instantiation.Extremely simple to define.
|
141
|
+
Extremely simple to use. That's all.
|
56
142
|
email:
|
57
143
|
- iamdaiver@icloud.com
|
58
144
|
executables: []
|
@@ -60,8 +146,11 @@ extensions: []
|
|
60
146
|
extra_rdoc_files: []
|
61
147
|
files:
|
62
148
|
- ".gitignore"
|
149
|
+
- ".jrubyrc"
|
63
150
|
- ".rspec"
|
151
|
+
- ".rubocop.yml"
|
64
152
|
- ".travis.yml"
|
153
|
+
- CHANGELOG.md
|
65
154
|
- CODE_OF_CONDUCT.md
|
66
155
|
- Gemfile
|
67
156
|
- LICENSE.txt
|
@@ -70,6 +159,16 @@ files:
|
|
70
159
|
- bin/console
|
71
160
|
- bin/setup
|
72
161
|
- lib/qonfig.rb
|
162
|
+
- lib/qonfig/command_set.rb
|
163
|
+
- lib/qonfig/commands/add_nested_option.rb
|
164
|
+
- lib/qonfig/commands/add_option.rb
|
165
|
+
- lib/qonfig/commands/base.rb
|
166
|
+
- lib/qonfig/commands/compose.rb
|
167
|
+
- lib/qonfig/data_set.rb
|
168
|
+
- lib/qonfig/dsl.rb
|
169
|
+
- lib/qonfig/error.rb
|
170
|
+
- lib/qonfig/settings.rb
|
171
|
+
- lib/qonfig/settings_builder.rb
|
73
172
|
- lib/qonfig/version.rb
|
74
173
|
- qonfig.gemspec
|
75
174
|
homepage: https://github.com/0exp/qonfig
|
@@ -84,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
183
|
requirements:
|
85
184
|
- - ">="
|
86
185
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
186
|
+
version: 2.2.10
|
88
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
188
|
requirements:
|
90
189
|
- - ">="
|
@@ -95,5 +194,5 @@ rubyforge_project:
|
|
95
194
|
rubygems_version: 2.7.6
|
96
195
|
signing_key:
|
97
196
|
specification_version: 4
|
98
|
-
summary:
|
197
|
+
summary: Config object
|
99
198
|
test_files: []
|