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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 640c084d4fd0dc167cfb9b52d12ae4d2f70382ec4d2f576703fc8be3a748fc08
4
- data.tar.gz: a36a0d612d46c542e9e20609a57c6fcf9ea244fce30fdbf295af8bc130ac9223
3
+ metadata.gz: d774926f0d94544e9d256b7c3e06bbc51b16a51a1323fbcb1f020a1c377ffaf7
4
+ data.tar.gz: a3d2769d42ba24938db56bd853f65b041a7053af462644a6d4e3ac3109c3b121
5
5
  SHA512:
6
- metadata.gz: 3922f86f65e5d9486074c9ca425821a1d6d6ccb8e9655089c20e95696ece61a99a00e18aa19078b6fa71f069acad5558dcf3a622944c2b72348996774a8e79fc
7
- data.tar.gz: f71c819eafab31c35d1faa5cfeaa6a28c9fcee4898d2dc492385391c04e4c50c7376ca2f5a45560d86b25fa98bfab486122f970d9d86c70c77b318a98ab79ccb
6
+ metadata.gz: 82ac7dd98fdccf5ab5ba846a9c733fbb8e3523676a23b390aca49c587e01b1cf9c76602d5909cda2736c7e4d572ffe219b85e3f7267f4499051c579a5bf59997
7
+ data.tar.gz: 747f86b8b8f8f2a348ae906e0e3e75a37f45afd896874ee1eb56aa7b66ee6a4c4581d48fbbe3d7d203879c345ff0894ca780f12a5bcbd660b421f7e202c29028
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
-
10
- # rspec failure tracking
11
9
  .rspec_status
10
+ Gemfile.lock
11
+ /.idea
12
+ .ruby-version
data/.jrubyrc ADDED
@@ -0,0 +1 @@
1
+ debug.fullTrace=true
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --format documentation
2
1
  --color
2
+ --format=progress
3
3
  --require spec_helper
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
- before_install: gem install bundler -v 1.16.1
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
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.1.0] - 2018-05-xx
5
+ - Release :)
data/README.md CHANGED
@@ -1,43 +1,237 @@
1
- # Qonfig
1
+ # Qonfig · [![Gem Version](https://badge.fury.io/rb/qonfig.svg)](https://badge.fury.io/rb/qonfig) [![Build Status](https://travis-ci.org/0exp/qonfig.svg?branch=master)](https://travis-ci.org/0exp/qonfig) [![Coverage Status](https://coveralls.io/repos/github/0exp/qonfig/badge.svg)](https://coveralls.io/github/0exp/qonfig)
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/qonfig`. To experiment with that code, run `bin/console` for an interactive prompt.
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
- And then execute:
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
- $ bundle
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
- Or install it yourself as:
31
+ ---
20
32
 
21
- $ gem install qonfig
33
+ ### Definition and Access
22
34
 
23
- ## Usage
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
- TODO: Write usage instructions here
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
- ## Development
146
+ class DatabaseConfig < Qonfig::DataSet
147
+ setting :user, 'test'
148
+ setting :password, 'testpaswd'
149
+ end
28
150
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
151
+ class ProjectConfig < Qonfig::DataSet
152
+ compose SharedConfig
30
153
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
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
- ## Contributing
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
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/qonfig. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
229
+ ---
36
230
 
37
231
  ## License
38
232
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
233
+ Released under MIT License.
40
234
 
41
- ## Code of Conduct
235
+ ## Authors
42
236
 
43
- Everyone interacting in the Qonfig project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/qonfig/blob/master/CODE_OF_CONDUCT.md).
237
+ Rustam Ibragimov.
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
data/bin/console CHANGED
@@ -1,14 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "qonfig"
3
+ require 'bundler/setup'
4
+ require 'qonfig'
5
5
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
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
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+
2
3
  set -euo pipefail
3
4
  IFS=$'\n\t'
4
5
  set -vx
@@ -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
@@ -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
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Qonfig
2
- VERSION = "0.0.0"
4
+ # @api public
5
+ # @since 0.1.0
6
+ VERSION = '0.1.0'
3
7
  end
data/lib/qonfig.rb CHANGED
@@ -1,5 +1,14 @@
1
- require "qonfig/version"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Qonfig
4
- # Your code goes here...
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("../lib", __FILE__)
3
+ lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "qonfig/version"
5
+ require 'qonfig/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "qonfig"
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.summary = "Soon"
13
- spec.description = "Soon"
14
- spec.homepage = "https://github.com/0exp/qonfig"
15
- spec.license = "MIT"
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.files = `git ls-files -z`.split("\x0").reject do |f|
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 "bundler", "~> 1.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
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.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-26 00:00:00.000000000 Z
11
+ date: 2018-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: coveralls
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
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: '1.16'
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: simplecov
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
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: '10.0'
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.0'
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.0'
55
- description: Soon
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: '0'
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: Soon
197
+ summary: Config object
99
198
  test_files: []