dry-configurable 0.8.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,118 @@
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
12
52
 
13
- def initialize(name, value, processor, options = EMPTY_HASH)
14
- @name = name.to_sym
15
- @value = value
16
- @processor = processor
53
+ # @api private
54
+ def constructor
55
+ CONSTRUCTOR
56
+ end
57
+ end
58
+
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
66
+ set!
67
+ end
68
+
69
+ # @api private
70
+ def nested(settings)
71
+ Nested.new(name, input: settings, **options)
18
72
  end
19
73
 
20
- def value
21
- Undefined.default(@value, nil)
74
+ # @api private
75
+ def pristine
76
+ with(input: Undefined)
22
77
  end
23
78
 
24
- def undefined?
25
- Undefined.equal?(@value)
79
+ # @api private
80
+ def with(new_opts)
81
+ self.class.new(name, input: input, default: default, **options, **new_opts)
26
82
  end
27
83
 
84
+ # @api private
85
+ def constructor
86
+ options[:constructor] || DEFAULT_CONSTRUCTOR
87
+ end
88
+
89
+ # @api private
28
90
  def reader?
29
- options[:reader]
91
+ options[:reader].equal?(true)
92
+ end
93
+
94
+ # @api private
95
+ def writer?(meth)
96
+ writer_name.equal?(meth)
97
+ end
98
+
99
+ # @api private
100
+ def clonable_value?
101
+ CLONABLE_VALUE_TYPES.any? { |type| value.is_a?(type) }
102
+ end
103
+
104
+ private
105
+
106
+ # @api private
107
+ def initialize_copy(source)
108
+ super
109
+ @value = source.value.dup if source.clonable_value?
110
+ @options = source.options.dup
30
111
  end
31
112
 
32
- def node?
33
- Settings === @value
113
+ # @api private
114
+ def set!
115
+ @value = constructor[input.equal?(Undefined) ? nil : input]
34
116
  end
35
117
  end
36
118
  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.0'.freeze
6
+ VERSION = '0.11.0'
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.0
4
+ version: 0.11.0
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-05 00:00:00.000000000 Z
11
+ date: 2020-02-15 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/**/*