dry-configurable 0.8.1 → 0.11.1

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.
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/configurable/errors'
4
+
5
+ module Dry
6
+ module Configurable
7
+ # Common API for both classes and instances
8
+ #
9
+ # @api public
10
+ module Methods
11
+ # @api public
12
+ def configure(&block)
13
+ raise FrozenConfig, 'Cannot modify frozen config' if frozen?
14
+
15
+ yield(config) if block
16
+ self
17
+ end
18
+
19
+ # Finalize and freeze configuration
20
+ #
21
+ # @return [Dry::Configurable::Config]
22
+ #
23
+ # @api public
24
+ def finalize!
25
+ return self if config.frozen?
26
+
27
+ config.finalize!
28
+ self
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,36 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ require 'dry/equalizer'
6
+
7
+ require 'dry/configurable/constants'
8
+ require 'dry/configurable/config'
9
+
1
10
  module Dry
2
11
  module Configurable
3
12
  # This class represents a setting and is used internally.
4
13
  #
5
- # @private
14
+ # @api private
6
15
  class Setting
16
+ include Dry::Equalizer(:name, :value, :options)
17
+
18
+ OPTIONS = %i[input default reader constructor settings].freeze
19
+
20
+ DEFAULT_CONSTRUCTOR = -> v { v }.freeze
21
+
22
+ CLONABLE_VALUE_TYPES = [Array, Hash, Set, Config].freeze
23
+
24
+ # @api private
7
25
  attr_reader :name
8
26
 
27
+ # @api private
28
+ attr_reader :writer_name
29
+
30
+ # @api private
31
+ attr_reader :input
32
+
33
+ # @api private
34
+ attr_reader :default
35
+
36
+ # @api private
37
+ attr_reader :value
38
+
39
+ # @api private
9
40
  attr_reader :options
10
41
 
11
- attr_reader :processor
42
+ # Specialized Setting which includes nested settings
43
+ #
44
+ # @api private
45
+ class Nested < Setting
46
+ CONSTRUCTOR = Config.method(:new)
47
+
48
+ # @api private
49
+ def pristine
50
+ with(input: input.pristine)
51
+ end
52
+
53
+ # @api private
54
+ def constructor
55
+ CONSTRUCTOR
56
+ end
57
+ end
12
58
 
13
- def initialize(name, value, processor, options = EMPTY_HASH)
14
- @name = name.to_sym
15
- @value = value
16
- @processor = processor
59
+ # @api private
60
+ def initialize(name, input: Undefined, default: Undefined, **options)
61
+ @name = name
62
+ @writer_name = :"#{name}="
63
+ @input = input.equal?(Undefined) ? default : input
64
+ @default = default
17
65
  @options = options
18
66
  end
19
67
 
68
+ # @api private
20
69
  def value
21
- Undefined.default(@value, nil)
70
+ @value ||= evaluate
71
+ end
72
+
73
+ # @api private
74
+ def nested(settings)
75
+ Nested.new(name, input: settings, **options)
76
+ end
77
+
78
+ # @api private
79
+ def pristine
80
+ with(input: Undefined)
81
+ end
82
+
83
+ # @api private
84
+ def with(new_opts)
85
+ self.class.new(name, input: input, default: default, **options, **new_opts)
22
86
  end
23
87
 
24
- def undefined?
25
- Undefined.equal?(@value)
88
+ # @api private
89
+ def constructor
90
+ options[:constructor] || DEFAULT_CONSTRUCTOR
26
91
  end
27
92
 
93
+ # @api private
28
94
  def reader?
29
- options[:reader]
95
+ options[:reader].equal?(true)
96
+ end
97
+
98
+ # @api private
99
+ def writer?(meth)
100
+ writer_name.equal?(meth)
101
+ end
102
+
103
+ # @api private
104
+ def clonable_value?
105
+ CLONABLE_VALUE_TYPES.any? { |type| value.is_a?(type) }
106
+ end
107
+
108
+ private
109
+
110
+ # @api private
111
+ def initialize_copy(source)
112
+ super
113
+ @value = source.value.dup if source.clonable_value?
114
+ @options = source.options.dup
30
115
  end
31
116
 
32
- def node?
33
- Settings === @value
117
+ # @api private
118
+ def evaluate
119
+ @value = constructor[input.equal?(Undefined) ? nil : input]
34
120
  end
35
121
  end
36
122
  end
@@ -1,91 +1,71 @@
1
- require 'set'
2
- require 'concurrent/array'
3
- require 'dry/configurable/settings/argument_parser'
4
- require 'dry/configurable/setting'
5
- require 'dry/configurable/config'
1
+ # frozen_string_literal: true
2
+
3
+ require 'concurrent/map'
4
+
5
+ require 'dry/equalizer'
6
+ require 'dry/configurable/constants'
6
7
 
7
8
  module Dry
8
9
  module Configurable
9
- # A collection of settings. This is not part of the public API.
10
+ # A settings map
10
11
  #
11
- # @private
12
+ # @api private
12
13
  class Settings
13
- Parser = ArgumentParser.new.freeze
14
+ include Dry::Equalizer(:elements)
14
15
 
15
- class DSL
16
- def self.call(&block)
17
- new.instance_exec do
18
- instance_exec(&block)
19
- @settings
20
- end
21
- end
16
+ include Enumerable
22
17
 
23
- def initialize
24
- @settings = Settings.new
25
- end
18
+ # @api private
19
+ attr_reader :elements
26
20
 
27
- def setting(*args, &block)
28
- @settings.add(*args, &block)
29
- end
21
+ # @api private
22
+ def initialize(elements = EMPTY_ARRAY)
23
+ initialize_elements(elements)
30
24
  end
31
25
 
32
- # Capture nested config definition
33
- #
34
- # @return [Dry::Configurable::Setting]
35
- def self.capture(&block)
36
- DSL.(&block)
26
+ # @api private
27
+ def <<(setting)
28
+ elements[setting.name] = setting
29
+ self
37
30
  end
38
31
 
39
- attr_reader :settings
40
-
41
- attr_reader :config_class
42
-
43
- attr_reader :names
44
-
45
- def initialize(settings = ::Concurrent::Array.new)
46
- @settings = settings
47
- @config_class = Config[self]
48
- @names = Set.new(settings.map(&:name))
49
- yield(self) if block_given?
32
+ # @api private
33
+ def [](name)
34
+ elements[name]
50
35
  end
51
36
 
52
- def add(key, value = Undefined, options = Undefined, &block)
53
- extended = singleton_class < Configurable
54
- raise_already_defined_config(key) if extended && configured?
55
-
56
- Setting.new(key, *Parser.(value, options, block)).tap do |s|
57
- settings << s
58
- names << s.name
59
- end
60
- end
61
-
62
- def each
63
- settings.each { |s| yield(s) }
37
+ # @api private
38
+ def key?(name)
39
+ keys.include?(name)
64
40
  end
65
41
 
66
- def empty?
67
- settings.empty?
42
+ # @api private
43
+ def keys
44
+ elements.keys
68
45
  end
69
46
 
70
- def name?(name)
71
- names.include?(name)
47
+ # @api private
48
+ def each(&block)
49
+ elements.values.each(&block)
72
50
  end
73
51
 
74
- def dup
75
- Settings.new(settings.dup)
52
+ # @api private
53
+ def pristine
54
+ self.class.new(map(&:pristine))
76
55
  end
77
56
 
78
- def freeze
79
- settings.freeze
80
- super
81
- end
57
+ private
82
58
 
83
- def create_config
84
- config_class.new
59
+ # @api private
60
+ def initialize_copy(source)
61
+ initialize_elements(source.map(&:dup))
85
62
  end
86
63
 
87
- def config_defined?
88
- config_class.config_defined?
64
+ # @api private
65
+ def initialize_elements(elements)
66
+ @elements = elements.each_with_object(Concurrent::Map.new) { |s, m|
67
+ m[s.name] = s
68
+ }
89
69
  end
90
70
  end
91
71
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Configurable
3
5
  # Methods meant to be used in a testing scenario
@@ -8,11 +10,7 @@ module Dry
8
10
  #
9
11
  # @api public
10
12
  def reset_config
11
- if self.is_a?(Class)
12
- @config = _settings.create_config
13
- else
14
- @config = self.class._settings.create_config
15
- end
13
+ @config = config.pristine
16
14
  end
17
15
  end
18
16
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Configurable
3
5
  # @api public
4
- VERSION = '0.8.1'.freeze
6
+ VERSION = '0.11.1'
5
7
  end
6
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-configurable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-06 00:00:00.000000000 Z
11
+ date: 2020-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 0.4.7
47
+ - !ruby/object:Gem::Dependency
48
+ name: dry-equalizer
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.2'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.2'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: bundler
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -86,38 +100,40 @@ dependencies:
86
100
  - - ">="
87
101
  - !ruby/object:Gem::Version
88
102
  version: '0'
89
- description:
103
+ description: A mixin to add configuration functionality to your classes
90
104
  email:
91
105
  - andyholland1991@aol.com
92
106
  executables: []
93
107
  extensions: []
94
108
  extra_rdoc_files: []
95
109
  files:
96
- - ".codeclimate.yml"
97
- - ".gitignore"
98
- - ".rspec"
99
- - ".travis.yml"
100
110
  - CHANGELOG.md
101
- - CONTRIBUTING.md
102
- - Gemfile
103
111
  - LICENSE
104
112
  - README.md
105
- - Rakefile
106
113
  - dry-configurable.gemspec
107
114
  - lib/dry-configurable.rb
108
115
  - lib/dry/configurable.rb
116
+ - lib/dry/configurable/class_methods.rb
117
+ - lib/dry/configurable/compiler.rb
109
118
  - lib/dry/configurable/config.rb
110
- - lib/dry/configurable/error.rb
119
+ - lib/dry/configurable/constants.rb
120
+ - lib/dry/configurable/dsl.rb
121
+ - lib/dry/configurable/dsl/args.rb
122
+ - lib/dry/configurable/errors.rb
123
+ - lib/dry/configurable/instance_methods.rb
124
+ - lib/dry/configurable/methods.rb
111
125
  - lib/dry/configurable/setting.rb
112
126
  - lib/dry/configurable/settings.rb
113
- - lib/dry/configurable/settings/argument_parser.rb
114
127
  - lib/dry/configurable/test_interface.rb
115
128
  - lib/dry/configurable/version.rb
116
- - rakelib/rubocop.rake
117
- homepage: https://github.com/dry-rb/dry-configurable
129
+ homepage: https://dry-rb.org/gems/dry-configurable
118
130
  licenses:
119
131
  - MIT
120
- metadata: {}
132
+ metadata:
133
+ allowed_push_host: https://rubygems.org
134
+ changelog_uri: https://github.com/dry-rb/dry-configurable/blob/master/CHANGELOG.md
135
+ source_code_uri: https://github.com/dry-rb/dry-configurable
136
+ bug_tracker_uri: https://github.com/dry-rb/dry-configurable/issues
121
137
  post_install_message:
122
138
  rdoc_options: []
123
139
  require_paths:
@@ -126,14 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
142
  requirements:
127
143
  - - ">="
128
144
  - !ruby/object:Gem::Version
129
- version: 2.3.0
145
+ version: 2.4.0
130
146
  required_rubygems_version: !ruby/object:Gem::Requirement
131
147
  requirements:
132
148
  - - ">="
133
149
  - !ruby/object:Gem::Version
134
150
  version: '0'
135
151
  requirements: []
136
- rubygems_version: 3.0.1
152
+ rubygems_version: 3.0.3
137
153
  signing_key:
138
154
  specification_version: 4
139
155
  summary: A mixin to add configuration functionality to your classes
data/.codeclimate.yml DELETED
@@ -1,23 +0,0 @@
1
- engines:
2
- rubocop:
3
- enabled: true
4
- checks:
5
- Rubocop/Metrics/LineLength:
6
- enabled: true
7
- max: 120
8
- Rubocop/Style/Documentation:
9
- enabled: false
10
- Rubocop/Lint/HandleExceptions:
11
- enabled: true
12
- exclude:
13
- - rakelib/*.rake
14
- Rubocop/Style/FileName:
15
- enabled: true
16
- exclude:
17
- - lib/dry-configurable.rb
18
- ratings:
19
- paths:
20
- - lib/**/*.rb
21
- exclude_paths:
22
- - spec/**/*
23
- - examples/**/*