configurability 3.2.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,11 +39,22 @@ class Configurability::SettingInstaller
39
39
 
40
40
  ### Add accessors with the specified +name+ to the target.
41
41
  def add_setting_accessors( name, options, &writer_hook )
42
+ if options[:use_class_vars]
43
+ self.target.class_variable_set( "@@#{name}", nil )
44
+ else
45
+ self.target.instance_variable_set( "@#{name}", nil )
46
+ end
47
+
42
48
  reader = self.make_setting_reader( name, options )
43
49
  writer = self.make_setting_writer( name, options, &writer_hook )
44
50
 
45
51
  self.target.define_singleton_method( "#{name}", &reader )
46
52
  self.target.define_singleton_method( "#{name}=", &writer )
53
+
54
+ if options[:predicate]
55
+ predicate = self.make_setting_predicate( name, options )
56
+ self.target.define_singleton_method( "#{name}?", &predicate )
57
+ end
47
58
  end
48
59
 
49
60
 
@@ -56,7 +67,9 @@ class Configurability::SettingInstaller
56
67
  self.class_variable_get("@@#{name}")
57
68
  end
58
69
  else
59
- return lambda { self.instance_variable_get("@#{name}") }
70
+ return lambda {
71
+ self.instance_variable_get("@#{name}")
72
+ }
60
73
  end
61
74
  end
62
75
 
@@ -79,6 +92,22 @@ class Configurability::SettingInstaller
79
92
  end
80
93
 
81
94
 
95
+ ### Create the body of the setting predicate method with the specified +name+ and +options+.
96
+ def make_setting_predicate( name, options )
97
+ if options[:use_class_vars]
98
+ return lambda do
99
+ Loggability[ Configurability ].debug "Using class variables for %s of %p" %
100
+ [ name, self ]
101
+ self.class_variable_get("@@#{name}") ? true : false
102
+ end
103
+ else
104
+ return lambda {
105
+ self.instance_variable_get("@#{name}") ? true : false
106
+ }
107
+ end
108
+ end
109
+
110
+
82
111
  ### Add a default for +name+ to the CONFIG_DEFAULTS constant of the target, creating
83
112
  ### it if necessary.
84
113
  def add_default( name, options )
@@ -119,13 +119,6 @@ describe Configurability::Config do
119
119
  end
120
120
 
121
121
 
122
- it "untaints values loaded from a config" do
123
- yaml = TEST_CONFIG.dup.taint
124
- config = described_class.new( yaml )
125
- expect( config.listsection.first ).to_not be_tainted
126
- expect( config.textsection ).to_not be_tainted
127
- end
128
-
129
122
 
130
123
  context "a config with nil keys" do
131
124
 
@@ -167,6 +160,11 @@ describe Configurability::Config do
167
160
  end
168
161
 
169
162
 
163
+ it "supports two-argument respond_to?" do
164
+ expect( config.respond_to?(:section, true) ).to be_truthy
165
+ end
166
+
167
+
170
168
  it "contains values specified in the source" do
171
169
  # section:
172
170
  # subsection:
@@ -255,7 +253,7 @@ describe Configurability::Config do
255
253
  # loading from a file
256
254
  context " loaded from a file" do
257
255
  before( :all ) do
258
- filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
256
+ filename = Dir::Tmpname.create( ['./test', '.conf'] ) {}
259
257
  @tmpfile = Pathname( filename )
260
258
  @tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
261
259
  end
@@ -284,7 +282,7 @@ describe Configurability::Config do
284
282
 
285
283
  it "can be written to a different file" do
286
284
  begin
287
- path = Dir::Tmpname.make_tmpname( './another-', '.config' )
285
+ path = Dir::Tmpname.create( ['./another-', '.config'] ) {}
288
286
 
289
287
  config.write( path )
290
288
  expect( File.read(path) ).to match( /section: ?\n subsection/ )
@@ -333,7 +331,7 @@ describe Configurability::Config do
333
331
  context " whose file changes after loading" do
334
332
 
335
333
  before( :all ) do
336
- filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
334
+ filename = Dir::Tmpname.create( ['./test', '.conf'] ) {}
337
335
  @tmpfile = Pathname( filename )
338
336
  @tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
339
337
  end
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'ipaddr'
4
+ require 'socket'
3
5
  require 'ostruct'
4
6
  require 'helpers'
5
7
 
@@ -17,11 +19,13 @@ describe Configurability do
17
19
 
18
20
  before( :each ) do
19
21
  Configurability.configurable_objects.clear
22
+ Configurability.after_configure_hooks.clear
20
23
  Configurability.reset
21
24
  end
22
25
 
23
26
  after( :all ) do
24
27
  Configurability.configurable_objects.clear
28
+ Configurability.after_configure_hooks.clear
25
29
  Configurability.reset
26
30
  end
27
31
 
@@ -404,21 +408,22 @@ describe Configurability do
404
408
  defaults = Configurability.gather_defaults
405
409
 
406
410
  expect( defaults ).to eq({ testconfig: { sect1: {sect2: { one: 1, two: 2 }} } })
411
+ expect( klass.config_key ).to eq( :testconfig__sect1__sect2 )
407
412
  end
408
413
 
409
414
 
410
415
  it "can return a Configurability::Config object with defaults, too" do
411
- klass1 = Class.new do
416
+ _klass1 = Class.new do
412
417
  extend Configurability
413
418
  config_key :testconfig
414
419
  self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
415
420
  end
416
- klass2 = Class.new do
421
+ _klass2 = Class.new do
417
422
  extend Configurability
418
423
  config_key :testconfig
419
424
  self::DEFAULT_CONFIG = { :two => 2, :types => {:two => true} }
420
425
  end
421
- klass3 = Class.new do
426
+ _klass3 = Class.new do
422
427
  extend Configurability
423
428
  config_key :otherconfig
424
429
  def self::defaults; { :other => true }; end
@@ -442,7 +447,7 @@ describe Configurability do
442
447
  self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
443
448
  Configurability.log.debug "Defaults: %p" % [ self.defaults ]
444
449
  end
445
- subclass = Class.new( klass ) do
450
+ _subclass = Class.new( klass ) do
446
451
  config_key :spanishconfig
447
452
  self::CONFIG_DEFAULTS = { :uno => 1 }
448
453
  end
@@ -670,7 +675,6 @@ describe Configurability do
670
675
  end
671
676
 
672
677
  child_class = Class.new( parent_class )
673
- child_class..extend( Configurability )
674
678
  child_class.configurability( :testconfig ) do
675
679
  setting :environment, default: :staging
676
680
  setting :apikey, default: 'foom'
@@ -705,6 +709,82 @@ describe Configurability do
705
709
  from( nil )
706
710
  end
707
711
 
712
+
713
+ it "allows declaration of singleton helper methods" do
714
+ mod.configurability( :testconfig ) do
715
+ def self::parse_ip_blocks( *values )
716
+ values.flatten.map do |value|
717
+ IPAddr.new( value, Socket::AF_INET )
718
+ end
719
+ end
720
+ setting :whitelisted_ip_blocks do |*values|
721
+ parse_ip_blocks( values )
722
+ end
723
+ setting :blacklisted_ip_blocks do |*values|
724
+ parse_ip_blocks( values )
725
+ end
726
+ end
727
+
728
+ expect {
729
+ mod.whitelisted_ip_blocks = ['127.0.0.1/8', '203.0.113.0/24']
730
+ }.to change { mod.whitelisted_ip_blocks }.to([
731
+ IPAddr.new( '127.0.0.0/8' ), IPAddr.new( '203.0.113.0/24' )
732
+ ])
733
+ end
734
+
735
+
736
+ it "can declare a predicate method for a setting" do
737
+ mod.configurability( :testconfig ) do
738
+ setting :use_whitelist, default: false, predicate: true
739
+ end
740
+
741
+ expect {
742
+ mod.use_whitelist = true
743
+ }.to change { mod.use_whitelist? }.from( false ).to( true )
744
+ end
745
+
746
+ end
747
+
748
+
749
+ describe "hooks" do
750
+
751
+ it "will call any registered callbacks after the config is installed" do
752
+ hook_was_called = false
753
+ Configurability.after_configure do
754
+ hook_was_called = true
755
+ end
756
+ Configurability.call_after_configure_hooks
757
+
758
+ expect( hook_was_called ).to be( true )
759
+ end
760
+
761
+
762
+ it "will immediately call after_config callbacks registered after the config is installed" do
763
+ hook_was_called = false
764
+ Configurability.call_after_configure_hooks
765
+
766
+ Configurability.after_configure do
767
+ hook_was_called = true
768
+ end
769
+
770
+ expect( hook_was_called ).to be( true )
771
+ end
772
+
773
+
774
+ it "can add new after_configure hooks even while the current ones are being run" do
775
+ hook_was_called = false
776
+ Configurability.after_configure do
777
+ Configurability.after_configure do
778
+ hook_was_called = true
779
+ end
780
+ end
781
+
782
+ Configurability.call_after_configure_hooks
783
+
784
+ expect( hook_was_called ).to be( true )
785
+ end
786
+
787
+
708
788
  end
709
789
 
710
790
  end
@@ -35,6 +35,8 @@ RSpec.configure do |config|
35
35
  config.mock_with( :rspec ) do |mock|
36
36
  mock.syntax = :expect
37
37
  end
38
+ config.warnings = true
39
+ config.profile_examples = 5
38
40
 
39
41
  config.include( Loggability::SpecHelpers )
40
42
  end
metadata CHANGED
@@ -1,42 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configurability
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
8
8
  - Mahlon E. Smith
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - |
13
13
  -----BEGIN CERTIFICATE-----
14
- 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
- GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
16
- 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
- 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
- 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
- 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
- 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
- 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
- 4MAX2qqKX/FKXqmFO+AGsbwYTEds1mksBF3fGsFgsQWxftG8GfZQ9+Cyu2+l1eOw
23
- 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
- +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
- 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
- /D+K9JW9DDs3Yjgv9k4h7YMhW5gftosd+NkNC/+Y2CkCAwEAAaN1MHMwCQYDVR0T
27
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
35
+ k9FjI4d9EP54gS/4
38
36
  -----END CERTIFICATE-----
39
- date: 2017-04-18 00:00:00.000000000 Z
37
+ date: 2020-12-28 00:00:00.000000000 Z
40
38
  dependencies:
41
39
  - !ruby/object:Gem::Dependency
42
40
  name: loggability
@@ -44,56 +42,28 @@ dependencies:
44
42
  requirements:
45
43
  - - "~>"
46
44
  - !ruby/object:Gem::Version
47
- version: '0.12'
45
+ version: '0.15'
48
46
  type: :runtime
49
47
  prerelease: false
50
48
  version_requirements: !ruby/object:Gem::Requirement
51
49
  requirements:
52
50
  - - "~>"
53
51
  - !ruby/object:Gem::Version
54
- version: '0.12'
55
- - !ruby/object:Gem::Dependency
56
- name: hoe-mercurial
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.4'
52
+ version: '0.15'
69
53
  - !ruby/object:Gem::Dependency
70
- name: hoe-deveiate
54
+ name: rake-deveiate
71
55
  requirement: !ruby/object:Gem::Requirement
72
56
  requirements:
73
57
  - - "~>"
74
58
  - !ruby/object:Gem::Version
75
- version: '0.8'
59
+ version: '0.17'
76
60
  type: :development
77
61
  prerelease: false
78
62
  version_requirements: !ruby/object:Gem::Requirement
79
63
  requirements:
80
64
  - - "~>"
81
65
  - !ruby/object:Gem::Version
82
- version: '0.8'
83
- - !ruby/object:Gem::Dependency
84
- name: hoe-highline
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '0.2'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0.2'
66
+ version: '0.17'
97
67
  - !ruby/object:Gem::Dependency
98
68
  name: simplecov
99
69
  requirement: !ruby/object:Gem::Requirement
@@ -114,58 +84,25 @@ dependencies:
114
84
  requirements:
115
85
  - - "~>"
116
86
  - !ruby/object:Gem::Version
117
- version: '3.5'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '3.5'
125
- - !ruby/object:Gem::Dependency
126
- name: rdoc
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '4.0'
87
+ version: '3.9'
132
88
  type: :development
133
89
  prerelease: false
134
90
  version_requirements: !ruby/object:Gem::Requirement
135
91
  requirements:
136
92
  - - "~>"
137
93
  - !ruby/object:Gem::Version
138
- version: '4.0'
139
- - !ruby/object:Gem::Dependency
140
- name: hoe
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '3.15'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '3.15'
153
- description: |-
154
- Configurability is a unified, non-intrusive, assume-nothing configuration system
155
- for Ruby. It lets you keep the configuration for multiple objects in a single
156
- config file, load the file when it's convenient for you, and distribute the
157
- configuration when you're ready, sending it everywhere it needs to go with a
94
+ version: '3.9'
95
+ description: Configurability is a unified, non-intrusive, assume-nothing configuration
96
+ system for Ruby. It lets you keep the configuration for multiple objects in a single
97
+ config file, load the file when it's convenient for you, and distribute the
98
+ configuration when you're ready, sending it everywhere it needs to go with a
158
99
  single action.
159
100
  email:
160
- - ged@FaerieMUD.org
101
+ - ged@faeriemud.org
161
102
  - mahlon@martini.nu
162
- executables:
163
- - configurability
103
+ executables: []
164
104
  extensions: []
165
- extra_rdoc_files:
166
- - History.md
167
- - Manifest.txt
168
- - README.md
105
+ extra_rdoc_files: []
169
106
  files:
170
107
  - ChangeLog
171
108
  - History.md
@@ -173,7 +110,6 @@ files:
173
110
  - Manifest.txt
174
111
  - README.md
175
112
  - Rakefile
176
- - bin/configurability
177
113
  - examples/basicconfig.rb
178
114
  - examples/config.yml
179
115
  - examples/readme.rb
@@ -186,31 +122,33 @@ files:
186
122
  - spec/configurability/deferred_config_spec.rb
187
123
  - spec/configurability_spec.rb
188
124
  - spec/helpers.rb
189
- homepage: http://deveiate.org/projects/configurability
125
+ homepage: https://configur.ability.guide/
190
126
  licenses:
191
127
  - BSD-3-Clause
192
- metadata: {}
193
- post_install_message:
194
- rdoc_options:
195
- - "--main"
196
- - README.md
128
+ metadata:
129
+ homepage_uri: https://configur.ability.guide/
130
+ documentation_uri: http://deveiate.org/code/configurability
131
+ changelog_uri: http://deveiate.org/code/configurability/History_md.html
132
+ source_uri: https://hg.sr.ht/~ged/Configurability
133
+ bug_tracker_uri: https://todo.sr.ht/~ged/Configurability
134
+ post_install_message:
135
+ rdoc_options: []
197
136
  require_paths:
198
137
  - lib
199
138
  required_ruby_version: !ruby/object:Gem::Requirement
200
139
  requirements:
201
140
  - - ">="
202
141
  - !ruby/object:Gem::Version
203
- version: 2.2.0
142
+ version: '2.5'
204
143
  required_rubygems_version: !ruby/object:Gem::Requirement
205
144
  requirements:
206
145
  - - ">="
207
146
  - !ruby/object:Gem::Version
208
147
  version: '0'
209
148
  requirements: []
210
- rubyforge_project:
211
- rubygems_version: 2.6.8
212
- signing_key:
149
+ rubygems_version: 3.2.3
150
+ signing_key:
213
151
  specification_version: 4
214
152
  summary: Configurability is a unified, non-intrusive, assume-nothing configuration
215
- system for Ruby
153
+ system for Ruby.
216
154
  test_files: []