sinclair 2.0.0 → 2.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/README.md +3 -3
- data/config/check_specs.yml +2 -0
- data/config/yardstick.yml +5 -1
- data/lib/sinclair/chain_settable.rb +83 -0
- data/lib/sinclair/class_methods.rb +2 -2
- data/lib/sinclair/core_ext/object.rb +39 -0
- data/lib/sinclair/env_settable.rb +35 -17
- data/lib/sinclair/settable/builder.rb +140 -0
- data/lib/sinclair/settable/caster.rb +61 -0
- data/lib/sinclair/settable/class_methods.rb +80 -0
- data/lib/sinclair/settable.rb +115 -0
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +2 -0
- data/spec/integration/yard/sinclair/env_settable_spec.rb +6 -25
- data/spec/integration/yard/sinclair/settable/caster_spec.rb +41 -0
- data/spec/integration/yard/sinclair/settable/class_methods_spec.rb +11 -0
- data/spec/integration/yard/sinclair/settable_spec.rb +26 -0
- data/spec/lib/sinclair/chain_settable_spec.rb +76 -0
- data/spec/lib/sinclair/class_methods_spec.rb +24 -4
- data/spec/lib/sinclair/env_settable_spec.rb +4 -2
- data/spec/lib/sinclair/settable/builder_spec.rb +47 -0
- data/spec/lib/sinclair/settable_spec.rb +46 -0
- data/spec/support/files/config.yml +1 -0
- data/spec/support/models/app_client.rb +1 -0
- data/spec/support/models/complex_builder.rb +17 -0
- data/spec/support/models/hash_app_client.rb +14 -0
- data/spec/support/models/hash_settable.rb +10 -0
- data/spec/support/models/json_env_settings.rb +18 -0
- data/spec/support/models/math_env_settings.rb +17 -0
- data/spec/support/models/my_app_client.rb +1 -0
- data/spec/support/models/non_default_app_client.rb +8 -0
- data/spec/support/models/yaml_file_settings.rb +26 -0
- data/spec/support/shared_examples/settable.rb +86 -0
- metadata +22 -5
- data/lib/sinclair/env_settable/builder.rb +0 -61
- data/spec/lib/sinclair/env_settable/builder_spec.rb +0 -35
- data/spec/support/shared_examples/env_settable.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bca1f4b9666c1916f4131d87e1f2acb9d417b0190bad68502299b0aa597dd19c
|
4
|
+
data.tar.gz: 329ca4de9e7ed56c10c6306801fd001a4a10eb890a9e145cb2a5db7009afbf75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5b81908de91bc67ad5aa309d212ed5f3250f2ff01b78c0549ba1bb137f07955462ef6f4b48f998fbb36917cc0a739b2befe80b9798906d4ca00c1d5cdd71468
|
7
|
+
data.tar.gz: a53161407bbafb1a1150b4a6643af49bbab613290bbbcdd7fe839575384a4b954d3bc17feeb7943b409a09db7a74a690184590d59d5452b2e00769c1e4e9826c
|
data/README.md
CHANGED
@@ -15,13 +15,13 @@ create custom comparators, configure your application, create powerfull options,
|
|
15
15
|
|
16
16
|
Employing Sinclair in your applications helps you streamline your development workflow and enhance your development process through more efficient, cleaner code
|
17
17
|
|
18
|
-
Current Release: [2.
|
18
|
+
Current Release: [2.1.0](https://github.com/darthjee/sinclair/tree/2.1.0)
|
19
19
|
|
20
|
-
[Next release](https://github.com/darthjee/sinclair/compare/2.
|
20
|
+
[Next release](https://github.com/darthjee/sinclair/compare/2.1.0...master)
|
21
21
|
|
22
22
|
Yard Documentation
|
23
23
|
-------------------
|
24
|
-
[https://www.rubydoc.info/gems/sinclair/2.
|
24
|
+
[https://www.rubydoc.info/gems/sinclair/2.1.0](https://www.rubydoc.info/gems/sinclair/2.1.0)
|
25
25
|
|
26
26
|
Installation
|
27
27
|
---------------
|
data/config/check_specs.yml
CHANGED
data/config/yardstick.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
threshold:
|
1
|
+
threshold: 99.9
|
2
2
|
require_exact_threshold: false
|
3
3
|
rules:
|
4
4
|
ApiTag::Presence:
|
@@ -39,6 +39,8 @@ rules:
|
|
39
39
|
- Sinclair::Matchers#change_class_method
|
40
40
|
- Sinclair::Model.for
|
41
41
|
- Sinclair::Model.initialize_with
|
42
|
+
- Sinclair::Settable#setting_with_options
|
43
|
+
- Sinclair::Settable::Builder#read_block
|
42
44
|
ReturnTag:
|
43
45
|
enabled: true
|
44
46
|
exclude:
|
@@ -48,6 +50,7 @@ rules:
|
|
48
50
|
- Sinclair::MethodBuilder#build_from_definition
|
49
51
|
- Sinclair::Matchers::ChangeClassMethodOn#raise_block_syntax_error
|
50
52
|
- Sinclair::Matchers::ChangeInstanceMethodOn#raise_block_syntax_error
|
53
|
+
- Sinclair::Settable::Builder#read_block
|
51
54
|
Summary::Presence:
|
52
55
|
enabled: true
|
53
56
|
exclude:
|
@@ -79,6 +82,7 @@ rules:
|
|
79
82
|
- Sinclair::Model::Builder#initialize
|
80
83
|
- Sinclair::Options#initialize
|
81
84
|
- Sinclair::Options::Builder#initialize
|
85
|
+
- Sinclair::Settable::Builder#initialize
|
82
86
|
Summary::Length:
|
83
87
|
enabled: true
|
84
88
|
exclude: []
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api public
|
5
|
+
# @author darthjee
|
6
|
+
#
|
7
|
+
# Settable that recovers data from other settables
|
8
|
+
#
|
9
|
+
# Each setting obeys a settable order and when a setting value is not found,
|
10
|
+
# the next is checked
|
11
|
+
module ChainSettable
|
12
|
+
include Sinclair::Settable
|
13
|
+
extend Sinclair::Settable::ClassMethods
|
14
|
+
|
15
|
+
read_with do |key, sources: nil, sources_map: {}|
|
16
|
+
sources.map_and_find do |source|
|
17
|
+
sources_map[source].public_send(key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @private
|
24
|
+
# @api public
|
25
|
+
# @visibility public
|
26
|
+
#
|
27
|
+
# Register a setting source
|
28
|
+
#
|
29
|
+
# @param key [Symbol] key identifying the setting
|
30
|
+
# @param source [Class<Settable>] Setting source class
|
31
|
+
#
|
32
|
+
# @return [Class<Settable>]
|
33
|
+
def source(key, source)
|
34
|
+
sources_map[key] = source
|
35
|
+
end
|
36
|
+
|
37
|
+
# @private
|
38
|
+
# @api public
|
39
|
+
# @visibility public
|
40
|
+
#
|
41
|
+
# Defines the order of the settings
|
42
|
+
#
|
43
|
+
# @param sources [Array<Symbol>] lis of sources in order
|
44
|
+
#
|
45
|
+
# @return [Array<Symbol>]
|
46
|
+
def sources(*sources)
|
47
|
+
@sources = sources
|
48
|
+
end
|
49
|
+
|
50
|
+
# @private
|
51
|
+
# @api private
|
52
|
+
#
|
53
|
+
# Hash with all Setting classes defined
|
54
|
+
#
|
55
|
+
# @return [Hash<Symbol,Settable>]
|
56
|
+
def sources_map
|
57
|
+
@sources_map ||= {}
|
58
|
+
end
|
59
|
+
|
60
|
+
# @private
|
61
|
+
# @api private
|
62
|
+
#
|
63
|
+
# Order of sources to be checked by default
|
64
|
+
#
|
65
|
+
# @return [Hash<Symbol,Settable>]
|
66
|
+
def sources_order
|
67
|
+
@sources || sources_map.keys
|
68
|
+
end
|
69
|
+
|
70
|
+
# @private
|
71
|
+
# @api private
|
72
|
+
#
|
73
|
+
# Returns default options passed to {read_block}
|
74
|
+
#
|
75
|
+
# @return [Hash<Symbol,Object>]
|
76
|
+
def default_options
|
77
|
+
{
|
78
|
+
sources: sources_order,
|
79
|
+
sources_map: sources_map
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -32,8 +32,8 @@ class Sinclair
|
|
32
32
|
# model = MyPerson.new
|
33
33
|
#
|
34
34
|
# model.random_name # returns 'John 803 Doe'
|
35
|
-
def build(
|
36
|
-
new(
|
35
|
+
def build(*args, **opts, &block)
|
36
|
+
new(*args, **opts).tap do |builder|
|
37
37
|
builder.instance_eval(&block) if block_given?
|
38
38
|
end.build
|
39
39
|
end
|
@@ -23,4 +23,43 @@ class Object
|
|
23
23
|
classes.any?(method(:is_a?))
|
24
24
|
end
|
25
25
|
# rubocop:enable Naming/PredicateName
|
26
|
+
|
27
|
+
# Maps the elements into a new value, returning only one
|
28
|
+
#
|
29
|
+
# The result to be returned is
|
30
|
+
# the first mapping that is evaluated to true
|
31
|
+
#
|
32
|
+
# This method is equivalent to #map#find but
|
33
|
+
# only calling the map block up to when a value
|
34
|
+
# is found
|
35
|
+
#
|
36
|
+
# @yield (*args) mappig block
|
37
|
+
#
|
38
|
+
# @example Using an array of keys to remove remove elements of a hash
|
39
|
+
#
|
40
|
+
# service_map = {
|
41
|
+
# a: nil,
|
42
|
+
# b: false,
|
43
|
+
# c: 'found me',
|
44
|
+
# d: nil,
|
45
|
+
# e: 'didnt find me'
|
46
|
+
# }
|
47
|
+
#
|
48
|
+
# keys = %i[a b c d e]
|
49
|
+
#
|
50
|
+
# keys.map_and_find do |key| #
|
51
|
+
# service_values.delete(key) #
|
52
|
+
# end # returns 'found me'
|
53
|
+
#
|
54
|
+
# service_map # has lost only 3 keys returning
|
55
|
+
# # { d: nil, e: 'didnt find me' }
|
56
|
+
#
|
57
|
+
# @return [::Object]
|
58
|
+
def map_and_find
|
59
|
+
mapped = nil
|
60
|
+
find do |*args|
|
61
|
+
mapped = yield(*args)
|
62
|
+
end
|
63
|
+
mapped || nil
|
64
|
+
end
|
26
65
|
end
|
@@ -13,20 +13,25 @@ class Sinclair
|
|
13
13
|
# settings_prefix 'MY_APP'
|
14
14
|
#
|
15
15
|
# with_settings :username, :password, host: 'my-host.com'
|
16
|
+
# setting_with_options :port, type: :integer
|
16
17
|
# end
|
17
18
|
#
|
18
19
|
# ENV['MY_APP_USERNAME'] = 'my_login'
|
20
|
+
# ENV['MY_APP_PORT'] = '8080'
|
19
21
|
#
|
20
22
|
# MyAppClient.username # returns 'my_login'
|
21
23
|
# MyAppClient.password # returns nil
|
22
24
|
# MyAppClient.host # returns 'my-host.com'
|
23
|
-
#
|
24
|
-
# ENV['MY_APP_HOST'] = 'other-host.com'
|
25
|
-
#
|
26
|
-
# MyAppClient.host # returns 'other-host.com'
|
27
|
-
#
|
25
|
+
# MyAppClient.port # returns 8080
|
28
26
|
module EnvSettable
|
29
|
-
|
27
|
+
include Sinclair::Settable
|
28
|
+
extend Sinclair::Settable::ClassMethods
|
29
|
+
|
30
|
+
read_with do |key, prefix: nil|
|
31
|
+
env_key = [prefix, key].compact.join('_').to_s.upcase
|
32
|
+
|
33
|
+
ENV[env_key]
|
34
|
+
end
|
30
35
|
|
31
36
|
private
|
32
37
|
|
@@ -41,25 +46,38 @@ class Sinclair
|
|
41
46
|
# @return [String]
|
42
47
|
#
|
43
48
|
# @example (see EnvSettable)
|
44
|
-
def settings_prefix(prefix)
|
49
|
+
def settings_prefix(prefix = nil)
|
50
|
+
return @settings_prefix || superclass_prefix unless prefix
|
51
|
+
|
45
52
|
@settings_prefix = prefix
|
46
53
|
end
|
47
54
|
|
48
55
|
# @private
|
49
|
-
# @api
|
50
|
-
# @visibility public
|
56
|
+
# @api private
|
51
57
|
#
|
52
|
-
#
|
58
|
+
# Default options when creating the method
|
53
59
|
#
|
54
|
-
#
|
55
|
-
# to be added
|
56
|
-
# @param defaults [Hash] Settings with default values
|
60
|
+
# Prefix is included in default options
|
57
61
|
#
|
58
|
-
# @return
|
62
|
+
# @return [Hash]
|
63
|
+
def default_options
|
64
|
+
super.merge(
|
65
|
+
prefix: settings_prefix
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @private
|
70
|
+
# @api private
|
59
71
|
#
|
60
|
-
#
|
61
|
-
|
62
|
-
|
72
|
+
# Returns the prefix set up for a superclass
|
73
|
+
#
|
74
|
+
# This ensures that an inherited class also has a prefix
|
75
|
+
#
|
76
|
+
# @return [String]
|
77
|
+
def superclass_prefix
|
78
|
+
return unless superclass.is_a?(Sinclair::EnvSettable)
|
79
|
+
|
80
|
+
superclass.settings_prefix
|
63
81
|
end
|
64
82
|
end
|
65
83
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
module Settable
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Env setting methods builder
|
9
|
+
#
|
10
|
+
# This builder does the magic of adding methods
|
11
|
+
# that will fetch variables from env or a default value
|
12
|
+
class Builder < Sinclair
|
13
|
+
# @param klass [Class] Setting class where the methods will be added to
|
14
|
+
# @param settings_name [Array<Symbol>] list of all settings to be added
|
15
|
+
# @param options [Hash] Options of setting.
|
16
|
+
#
|
17
|
+
# Each settable might have their own set options defined in
|
18
|
+
# {Sinclair::Settable::ClassMethods#read_with Settable.read_with},
|
19
|
+
# and then passed to the buildr on
|
20
|
+
# {Sinclair::Settable#setting_with_options Settable#setting_with_options}
|
21
|
+
#
|
22
|
+
# @option options type [Symbol] type to cast the value fetched
|
23
|
+
# @option options default [Object] Default value
|
24
|
+
def initialize(klass, *settings_name, **options)
|
25
|
+
super(klass, **options)
|
26
|
+
|
27
|
+
@settings = settings_name
|
28
|
+
|
29
|
+
add_all_methods
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
delegate :type, to: :options_object
|
35
|
+
# @method type
|
36
|
+
# @private
|
37
|
+
# @api private
|
38
|
+
#
|
39
|
+
# Returns the type to cast the retrieved value
|
40
|
+
#
|
41
|
+
# @return [Symbol]
|
42
|
+
|
43
|
+
delegate :settable_module, to: :klass
|
44
|
+
# @method settable_module
|
45
|
+
# @private
|
46
|
+
# @api private
|
47
|
+
#
|
48
|
+
# Module of settable that the class extends
|
49
|
+
#
|
50
|
+
# @return [Module]
|
51
|
+
|
52
|
+
delegate :read_with, to: :settable_module
|
53
|
+
# @method read_with
|
54
|
+
# @private
|
55
|
+
# @api private
|
56
|
+
#
|
57
|
+
# Returns proc for extracting values when reading a setting
|
58
|
+
#
|
59
|
+
# @see add_setting_method
|
60
|
+
# @see Settable::ClassMethods#read_with
|
61
|
+
# @return [Proc]
|
62
|
+
alias read_block read_with
|
63
|
+
|
64
|
+
attr_reader :settings
|
65
|
+
# @method settings
|
66
|
+
# @private
|
67
|
+
# @api private
|
68
|
+
#
|
69
|
+
# Name of all settings to be added
|
70
|
+
#
|
71
|
+
# @return [Array<Symbol>]
|
72
|
+
|
73
|
+
# @private
|
74
|
+
# @api private
|
75
|
+
#
|
76
|
+
# Process all settings adding the methods
|
77
|
+
#
|
78
|
+
# @return (see settings)
|
79
|
+
def add_all_methods
|
80
|
+
settings.each do |name|
|
81
|
+
add_setting_method(name)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @private
|
86
|
+
#
|
87
|
+
# Add one setting class method to settings class
|
88
|
+
#
|
89
|
+
# @return (see Sinclair#add_class_method)
|
90
|
+
def add_setting_method(name)
|
91
|
+
options = call_options
|
92
|
+
block = read_block
|
93
|
+
caster = caster_class.caster_for(type)
|
94
|
+
default = options_object.default
|
95
|
+
|
96
|
+
add_class_method(name, cached: :full) do
|
97
|
+
value = instance_exec(name, **options, &block)
|
98
|
+
|
99
|
+
value ? caster.cast(value) : default
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @private
|
104
|
+
#
|
105
|
+
# Options that will be accepted by {read_block}
|
106
|
+
#
|
107
|
+
# The given options are sliced based on the accepted parameters
|
108
|
+
# from read_blocks
|
109
|
+
#
|
110
|
+
# @see read_block_options
|
111
|
+
# @see Settable::ClassMethods#read_with
|
112
|
+
# @return [Hash<Symbol, Object>]
|
113
|
+
def call_options
|
114
|
+
@call_options ||= options.slice(*read_block_options)
|
115
|
+
end
|
116
|
+
|
117
|
+
# @private
|
118
|
+
#
|
119
|
+
# List all keys accepted by {read_block}
|
120
|
+
#
|
121
|
+
# @see call_options
|
122
|
+
# @see Settable::ClassMethods#read_with
|
123
|
+
# @return [Array<Symbol>]
|
124
|
+
def read_block_options
|
125
|
+
read_block.parameters.select do |(type, _name)|
|
126
|
+
type == :key
|
127
|
+
end.map(&:second)
|
128
|
+
end
|
129
|
+
|
130
|
+
# @private
|
131
|
+
#
|
132
|
+
# Returns caster configured for casting the returning values
|
133
|
+
#
|
134
|
+
# @return [Class<Settable::Caster>]
|
135
|
+
def caster_class
|
136
|
+
settable_module::Caster
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
module Settable
|
5
|
+
# @api public
|
6
|
+
#
|
7
|
+
# Class responsible for casting the values
|
8
|
+
#
|
9
|
+
# New types can be added
|
10
|
+
#
|
11
|
+
# @example Adding a casting type to {Sinclair::Settable::Caster Sinclair::Settable::Caster}
|
12
|
+
# class Sinclair
|
13
|
+
# module Settable
|
14
|
+
# class Caster
|
15
|
+
# cast_with(:squared) { |value| value.to_f**2 }
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# class MathEnvSettings
|
21
|
+
# extend Sinclair::EnvSettable
|
22
|
+
#
|
23
|
+
# settings_prefix 'MATH'
|
24
|
+
#
|
25
|
+
# setting_with_options :value, type: :squared
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# ENV['MATH_VALUE'] = '80'
|
29
|
+
#
|
30
|
+
# settable.value # returns 6400.0
|
31
|
+
#
|
32
|
+
# @example Creating a new caster
|
33
|
+
# module JsonEnvSettable
|
34
|
+
# include Sinclair::EnvSettable
|
35
|
+
# extend Sinclair::Settable::ClassMethods
|
36
|
+
#
|
37
|
+
# class Caster < Sinclair::Settable::Caster
|
38
|
+
# cast_with(:json) { |value| JSON.parse(value) }
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# class JsonEnvSettings
|
43
|
+
# extend JsonEnvSettable
|
44
|
+
#
|
45
|
+
# settings_prefix 'JSON'
|
46
|
+
#
|
47
|
+
# setting_with_options :config, type: :json
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# hash = { key: 'value' }
|
51
|
+
#
|
52
|
+
# ENV['JSON_CONFIG'] = hash.to_json
|
53
|
+
#
|
54
|
+
# settable.config # returns { 'key' => 'value' }
|
55
|
+
class Caster < Sinclair::Caster
|
56
|
+
cast_with(:integer, &:to_i)
|
57
|
+
cast_with(:string, &:to_s)
|
58
|
+
cast_with(:float, &:to_f)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
module Settable
|
5
|
+
# @api public
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Class methods availabe inside a Settable module
|
9
|
+
#
|
10
|
+
# The methods should help configuring the settable
|
11
|
+
#
|
12
|
+
# @see #read_with
|
13
|
+
module ClassMethods
|
14
|
+
# Register and return a block for reading a setting
|
15
|
+
#
|
16
|
+
# @param read_block [Proc] the block that will be used when
|
17
|
+
# reading a setting key
|
18
|
+
#
|
19
|
+
# When the block is called, it will receive the key and any
|
20
|
+
# given options
|
21
|
+
#
|
22
|
+
# @return [Proc]
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# # config.yml
|
26
|
+
# # timeout: 10
|
27
|
+
#
|
28
|
+
# # yaml_file_settable.rb
|
29
|
+
#
|
30
|
+
# module YamlFileSettable
|
31
|
+
# include Sinclair::Settable
|
32
|
+
# extend Sinclair::Settable::ClassMethods
|
33
|
+
#
|
34
|
+
# read_with do |key, default: nil|
|
35
|
+
# loaded_yaml[key.to_s] || default
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def loaded_yaml
|
39
|
+
# YAML.load_file(setting_file)
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# def setting_file(file_path = @setting_file)
|
43
|
+
# @setting_file = file_path
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # yaml_file_settings.rb
|
48
|
+
#
|
49
|
+
# class YamlFileSettings
|
50
|
+
# extend YamlFileSettable
|
51
|
+
#
|
52
|
+
# setting_file 'config.yml'
|
53
|
+
#
|
54
|
+
# setting_with_options :timeout, default: 30
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# YamlFileSettings.timeout # returns 10
|
58
|
+
def read_with(&read_block)
|
59
|
+
return @read_block = read_block if read_block
|
60
|
+
return @read_block if @read_block
|
61
|
+
|
62
|
+
superclass_settable&.read_with
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @private
|
68
|
+
# @api private
|
69
|
+
#
|
70
|
+
# Returns a {Settable} module representing a superclass
|
71
|
+
#
|
72
|
+
# @return [Module]
|
73
|
+
def superclass_settable
|
74
|
+
included_modules.find do |modu|
|
75
|
+
modu <= Sinclair::Settable
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api public
|
5
|
+
# @author darthjee
|
6
|
+
#
|
7
|
+
# Module to be extended or included, allowing settings to be read from a source
|
8
|
+
#
|
9
|
+
# @see Sinclair::EnvSettable
|
10
|
+
#
|
11
|
+
# @example Creating a custom settable
|
12
|
+
#
|
13
|
+
# module HashSettable
|
14
|
+
# extend Sinclair::Settable::ClassMethods
|
15
|
+
# include Sinclair::Settable
|
16
|
+
#
|
17
|
+
# read_with do |key, default: nil|
|
18
|
+
# self::HASH[key] || default
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# class HashAppClient
|
23
|
+
# extend HashSettable
|
24
|
+
#
|
25
|
+
# HASH = {}
|
26
|
+
#
|
27
|
+
# with_settings :username, :password, host: 'my-host.com'
|
28
|
+
# setting_with_options :port, type: :integer
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# ENV[:username] = 'my_login'
|
32
|
+
# ENV[:port] = '8080'
|
33
|
+
#
|
34
|
+
# HashAppClient.username # returns 'my_login'
|
35
|
+
# HashAppClient.password # returns nil
|
36
|
+
# HashAppClient.host # returns 'my-host.com'
|
37
|
+
# HashAppClient.port # returns 8080
|
38
|
+
module Settable
|
39
|
+
autoload :Builder, 'sinclair/settable/builder'
|
40
|
+
autoload :Caster, 'sinclair/settable/caster'
|
41
|
+
autoload :ClassMethods, 'sinclair/settable/class_methods'
|
42
|
+
|
43
|
+
extend Sinclair::Settable::ClassMethods
|
44
|
+
|
45
|
+
# @api private
|
46
|
+
#
|
47
|
+
# returns the settable module that the class extends
|
48
|
+
#
|
49
|
+
# This is used in order to find out what is the read block used
|
50
|
+
# by the settable
|
51
|
+
#
|
52
|
+
# @return [Module] a +Sinclair::Settable+
|
53
|
+
def settable_module
|
54
|
+
@settable_module ||= singleton_class.included_modules.find do |modu|
|
55
|
+
modu <= Sinclair::Settable
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# @private
|
62
|
+
# @api public
|
63
|
+
# @visibility public
|
64
|
+
#
|
65
|
+
# Adds settings
|
66
|
+
#
|
67
|
+
# @param settings_name [Array<Symbol,String>] Name of all settings
|
68
|
+
# to be added
|
69
|
+
# @param defaults [Hash] Settings with default values
|
70
|
+
#
|
71
|
+
# @example (see Settable)
|
72
|
+
# @example (see EnvSettable)
|
73
|
+
#
|
74
|
+
# @see setting_with_options
|
75
|
+
#
|
76
|
+
# @return [Hash<Symbol, Object>]
|
77
|
+
def with_settings(*settings_name, **defaults)
|
78
|
+
setting_with_options(*settings_name)
|
79
|
+
|
80
|
+
defaults.each do |key, default|
|
81
|
+
setting_with_options(key, default: default)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @private
|
86
|
+
# @api public
|
87
|
+
# @visibility public
|
88
|
+
#
|
89
|
+
# Add setting with options
|
90
|
+
#
|
91
|
+
# @param settings_name [Array<Symbol,String>] Name of all settings
|
92
|
+
# to be added
|
93
|
+
# @param options [Hash<Symbol, Object>] setting exposition options
|
94
|
+
# @option options type [Symbol] type to cast the value fetched
|
95
|
+
# @option options default [Object] Default value
|
96
|
+
#
|
97
|
+
# @see with_settings
|
98
|
+
# @return (see Sinclair#build)
|
99
|
+
def setting_with_options(*settings_name, **options)
|
100
|
+
opts = default_options.merge(options)
|
101
|
+
|
102
|
+
Builder.build(self, *settings_name, **opts)
|
103
|
+
end
|
104
|
+
|
105
|
+
# @private
|
106
|
+
# @api private
|
107
|
+
#
|
108
|
+
# Default options when creating the method
|
109
|
+
#
|
110
|
+
# @return [Hash]
|
111
|
+
def default_options
|
112
|
+
{}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/sinclair/version.rb
CHANGED