qonfig 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []