configliere 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.textile CHANGED
@@ -1,3 +1,14 @@
1
+ h2. Version 0.4.7
2
+
3
+ * can now load JSON
4
+ * updated specs to run on Windows
5
+ * Only accepts things that are to_sym'bolizable as keys
6
+ * pings rdoc.info on commit
7
+
8
+ h2. Version 0.4.6
9
+
10
+ Unwittingly moved DeepHash's alias_method(:merge,:update) *above* the redefinition of update, and so made merge be quietly broken. Fixed, and many more specs added.
11
+
1
12
  h2. Version 0.4.5
2
13
 
3
14
  * can now ask for @has_definition?(:my_param)@ or @has_definition?(:my_param, :description)@.
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem 'json'
4
+
3
5
  # Add dependencies to develop your gem here.
4
6
  # Include everything needed to run rake, tests, features, etc.
5
7
  group :development do
data/Gemfile.lock CHANGED
@@ -9,6 +9,7 @@ GEM
9
9
  bundler (~> 1.0.0)
10
10
  git (>= 1.2.5)
11
11
  rake
12
+ json (1.5.1)
12
13
  rake (0.8.7)
13
14
  rcov (0.9.9)
14
15
  reek (1.2.8)
@@ -43,6 +44,7 @@ DEPENDENCIES
43
44
  bundler (~> 1.0.12)
44
45
  highline (>= 1.5.2)
45
46
  jeweler (~> 1.5.2)
47
+ json
46
48
  rcov (>= 0.9.9)
47
49
  reek
48
50
  roodi
data/README.textile CHANGED
@@ -180,7 +180,7 @@ h2. Command-line parameters
180
180
 
181
181
  <pre>
182
182
  # Head back
183
- time_machine --delorean.power_source='1.21 gigawatt lightning strike' --dest_time=11-05-1985
183
+ time_machine --delorean.power_source='1.21 jiggawatt lightning strike' --dest_time=11-05-1985
184
184
  # (in the time_machine script:)
185
185
  Settings.use(:commandline)
186
186
  Settings.resolve!
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.6
1
+ 0.4.7
data/configliere.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{configliere}
8
- s.version = "0.4.6"
8
+ s.version = "0.4.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["infochimps", "mrflip"]
12
- s.date = %q{2011-05-21}
12
+ s.date = %q{2011-06-28}
13
13
  s.description = %q{ You've got a script. It's got some settings. Some settings are for this module, some are for that module. Most of them don't change. Except on your laptop, where the paths are different. Or when you're in production mode. Or when you're testing from the command line.
14
14
 
15
15
  "" So, Consigliere of mine, I think you should tell your Don what everyone knows. "" -- Don Corleone
@@ -108,6 +108,7 @@ Configliere manage settings from many sources: static constants, simple config f
108
108
  s.specification_version = 3
109
109
 
110
110
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
111
+ s.add_runtime_dependency(%q<json>, [">= 0"])
111
112
  s.add_development_dependency(%q<bundler>, ["~> 1.0.12"])
112
113
  s.add_development_dependency(%q<yard>, ["~> 0.6.7"])
113
114
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
@@ -116,6 +117,7 @@ Configliere manage settings from many sources: static constants, simple config f
116
117
  s.add_development_dependency(%q<RedCloth>, [">= 0"])
117
118
  s.add_development_dependency(%q<highline>, [">= 1.5.2"])
118
119
  else
120
+ s.add_dependency(%q<json>, [">= 0"])
119
121
  s.add_dependency(%q<bundler>, ["~> 1.0.12"])
120
122
  s.add_dependency(%q<yard>, ["~> 0.6.7"])
121
123
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
@@ -125,6 +127,7 @@ Configliere manage settings from many sources: static constants, simple config f
125
127
  s.add_dependency(%q<highline>, [">= 1.5.2"])
126
128
  end
127
129
  else
130
+ s.add_dependency(%q<json>, [">= 0"])
128
131
  s.add_dependency(%q<bundler>, ["~> 1.0.12"])
129
132
  s.add_dependency(%q<yard>, ["~> 0.6.7"])
130
133
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
@@ -29,7 +29,7 @@ module Configliere
29
29
  end
30
30
 
31
31
  def command_info
32
- commands[command_name]
32
+ commands[command_name] if command_name
33
33
  end
34
34
 
35
35
  def resolve!
@@ -30,7 +30,11 @@ module Configliere
30
30
  if filename.is_a?(Symbol) then raise Configliere::DeprecatedError, "Loading from a default config file is no longer provided" ; end
31
31
  filename = expand_filename(filename)
32
32
  begin
33
- read_yaml(File.open(filename), options)
33
+ case filetype(filename)
34
+ when 'json' then read_json(File.open(filename), options)
35
+ when 'yaml' then read_yaml(File.open(filename), options)
36
+ else read_yaml(File.open(filename), options)
37
+ end
34
38
  rescue Errno::ENOENT => e
35
39
  warn "Loading empty configliere settings file #{filename}"
36
40
  end
@@ -38,6 +42,7 @@ module Configliere
38
42
  end
39
43
 
40
44
  def read_yaml yaml_str, options={}
45
+ require 'yaml'
41
46
  new_data = YAML.load(yaml_str) || {}
42
47
  # Extract the :env (production/development/etc)
43
48
  if options[:env]
@@ -47,6 +52,19 @@ module Configliere
47
52
  self
48
53
  end
49
54
 
55
+ #
56
+ # we depend on you to require some sort of JSON
57
+ #
58
+ def read_json json_str, options={}
59
+ new_data = JSON.load(json_str) || {}
60
+ # Extract the :env (production/development/etc)
61
+ if options[:env]
62
+ new_data = new_data[options[:env]] || {}
63
+ end
64
+ deep_merge! new_data
65
+ self
66
+ end
67
+
50
68
  # save to disk.
51
69
  # * file is in YAML format, as a hash of handle => param_hash pairs
52
70
  # * filename defaults to Configliere::DEFAULT_CONFIG_FILE (~/.configliere, probably)
@@ -59,6 +77,11 @@ module Configliere
59
77
 
60
78
  protected
61
79
 
80
+ def filetype filename
81
+ filename =~ /\.([^\.]+)$/ ;
82
+ $1
83
+ end
84
+
62
85
  def expand_filename filename
63
86
  if filename.to_s.include?('/')
64
87
  File.expand_path(filename)
@@ -265,21 +265,21 @@ class DeepHash < Hash
265
265
  # Merge hashes recursively.
266
266
  # Nothing special happens to array values
267
267
  #
268
- # x = { :subhash => { 1 => :val_from_x, 222 => :only_in_x, 333 => :only_in_x }, :scalar => :scalar_from_x}
269
- # y = { :subhash => { 1 => :val_from_y, 999 => :only_in_y }, :scalar => :scalar_from_y }
268
+ # x = { :subhash => { :a => :val_from_x, :b => :only_in_x, :c => :only_in_x }, :scalar => :scalar_from_x}
269
+ # y = { :subhash => { :a => :val_from_y, :d => :only_in_y }, :scalar => :scalar_from_y }
270
270
  # x.deep_merge y
271
- # => {:subhash=>{1=>:val_from_y, 222=>:only_in_x, 333=>:only_in_x, 999=>:only_in_y}, :scalar=>:scalar_from_y}
271
+ # => {:subhash=>{:a=>:val_from_y, :b=>:only_in_x, :c=>:only_in_x, :d=>:only_in_y}, :scalar=>:scalar_from_y}
272
272
  # y.deep_merge x
273
- # => {:subhash=>{1=>:val_from_x, 222=>:only_in_x, 333=>:only_in_x, 999=>:only_in_y}, :scalar=>:scalar_from_x}
273
+ # => {:subhash=>{:a=>:val_from_x, :b=>:only_in_x, :c=>:only_in_x, :d=>:only_in_y}, :scalar=>:scalar_from_x}
274
274
  #
275
275
  # Nil values always lose.
276
276
  #
277
- # x = {:subhash=>{:nil_in_x=>nil, 1=>:val1,}, :nil_in_x=>nil}
277
+ # x = {:subhash=>{:nil_in_x=>nil, a=>:val_a}, :nil_in_x=>nil}
278
278
  # y = {:subhash=>{:nil_in_x=>5}, :nil_in_x=>5}
279
279
  # y.deep_merge x
280
- # => {:subhash=>{1=>:val1, :nil_in_x=>5}, :nil_in_x=>5}
280
+ # => {:subhash=>{:a=>:val_a, :nil_in_x=>5}, :nil_in_x=>5}
281
281
  # x.deep_merge y
282
- # => {:subhash=>{1=>:val1, :nil_in_x=>5}, :nil_in_x=>5}
282
+ # => {:subhash=>{:a=>:val_a, :nil_in_x=>5}, :nil_in_x=>5}
283
283
  #
284
284
  def deep_merge hsh2
285
285
  merge hsh2, &DeepHash::DEEP_MERGER
@@ -293,11 +293,11 @@ class DeepHash < Hash
293
293
  #
294
294
  # Treat hash as tree of hashes:
295
295
  #
296
- # x = { 1 => :val, :subhash => { 1 => :val1 } }
296
+ # x = { :a => :val, :subhash => { :b => :val_b } }
297
297
  # x.deep_set(:subhash, :cat, :hat)
298
- # # => { 1 => :val, :subhash => { 1 => :val1, :cat => :hat } }
299
- # x.deep_set(:subhash, 1, :newval)
300
- # # => { 1 => :val, :subhash => { 1 => :newval, :cat => :hat } }
298
+ # # => { :a => :val, :subhash => { :b => :val_b, :cat => :hat } }
299
+ # x.deep_set(:subhash, :b, :newval)
300
+ # # => { :a => :val, :subhash => { :b => :newval, :cat => :hat } }
301
301
  #
302
302
  #
303
303
  def deep_set *args
@@ -316,14 +316,14 @@ class DeepHash < Hash
316
316
  #
317
317
  # Treat hash as tree of hashes:
318
318
  #
319
- # x = { 1 => :val, :subhash => { 1 => :val1 } }
320
- # x.deep_get(:subhash, 1)
321
- # # => :val
322
- # x.deep_get(:subhash, 2)
319
+ # x = { :a => :val_a, :subhash => { :b => :val_b } }
320
+ # x.deep_get(:a)
321
+ # # => :val_a
322
+ # x.deep_get(:subhash, :c)
323
323
  # # => nil
324
- # x.deep_get(:subhash, 2, 3)
324
+ # x.deep_get(:subhash, :c, :f)
325
325
  # # => nil
326
- # x.deep_get(:subhash, 2)
326
+ # x.deep_get(:subhash, :b)
327
327
  # # => nil
328
328
  #
329
329
  def deep_get *args
@@ -337,15 +337,15 @@ class DeepHash < Hash
337
337
  #
338
338
  # Treat hash as tree of hashes:
339
339
  #
340
- # x = { 1 => :val, :subhash => { 1 => :val1, 2 => :val2 } }
341
- # x.deep_delete(:subhash, 1)
340
+ # x = { :a => :val, :subhash => { :a => :val1, :b => :val2 } }
341
+ # x.deep_delete(:subhash, :a)
342
342
  # #=> :val
343
343
  # x
344
- # #=> { 1 => :val, :subhash => { 2 => :val2 } }
344
+ # #=> { :a => :val, :subhash => { :b => :val2 } }
345
345
  #
346
346
  def deep_delete *args
347
- last_key = args.pop
348
- last_hsh = args.empty? ? self : (deep_get(*args)||{})
347
+ last_key = args.pop # key to delete
348
+ last_hsh = args.empty? ? self : (deep_get(*args)||{}) # hsh containing that key
349
349
  last_hsh.delete(last_key)
350
350
  end
351
351
 
@@ -359,9 +359,9 @@ protected
359
359
  # @private
360
360
  def convert_key(attr)
361
361
  case
362
- when attr.to_s.include?('.') then attr.to_s.split(".").map{|sub_attr| sub_attr.to_sym }
363
- when attr.is_a?(String) then attr.to_sym
364
- else attr
362
+ when attr.to_s.include?('.') then attr.to_s.split(".").map{|sub_attr| sub_attr.to_sym }
363
+ when attr.is_a?(Array) then attr.map{|sub_attr| sub_attr.to_sym }
364
+ else attr.to_sym
365
365
  end
366
366
  end
367
367
 
@@ -10,7 +10,7 @@ describe Configliere::ConfigFile do
10
10
  @config.should respond_to(:read)
11
11
  end
12
12
 
13
- describe 'loading a config file' do
13
+ describe 'loading a yaml config file' do
14
14
  before do
15
15
  @fake_file = '{ :my_param: val_from_file }'
16
16
  end
@@ -47,6 +47,44 @@ describe Configliere::ConfigFile do
47
47
  end
48
48
  end
49
49
 
50
+ describe 'loading a json config file' do
51
+ before do
52
+ require 'json'
53
+ @fake_file = '{"my_param":"val_from_file"}'
54
+ end
55
+
56
+ describe 'successfully' do
57
+ it 'with an absolute pathname uses it directly' do
58
+ File.should_receive(:open).with(%r{/fake/path.json}).and_return(@fake_file)
59
+ @config.read '/fake/path.json'
60
+ end
61
+ it 'with a simple filename, references it to the default config dir' do
62
+ File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.json')).and_return(@fake_file)
63
+ @config.read 'file.json'
64
+ end
65
+ it 'returns the config object for chaining' do
66
+ File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.json')).and_return(@fake_file)
67
+ @config.defaults :also_a_param => true
68
+ @config.read('file.json').should == { :my_param => 'val_from_file', :also_a_param => true }
69
+ end
70
+ after do
71
+ @config[:my_param].should == 'val_from_file'
72
+ end
73
+ end
74
+
75
+ it 'no longer provides a default config file' do
76
+ lambda{ @config.read(:my_settings) }.should raise_error(Configliere::DeprecatedError)
77
+ defined?(Configliere::DEFAULT_CONFIG_FILE).should_not be_true
78
+ end
79
+
80
+ it 'warns but does not fail if the file is missing' do
81
+ @config = Configliere::Param.new
82
+ File.stub(:open).and_raise(Errno::ENOENT)
83
+ @config.should_receive(:warn).with("Loading empty configliere settings file #{Configliere::DEFAULT_CONFIG_DIR}/nonexistent_file.json")
84
+ @config.read('nonexistent_file.json').should == {}
85
+ end
86
+ end
87
+
50
88
  describe '#read_yaml' do
51
89
  before do
52
90
  @config.merge! :reload => :whatever
@@ -107,7 +145,7 @@ describe Configliere::ConfigFile do
107
145
  it 'and ensures the directory exists' do
108
146
  fake_file = StringIO.new('', 'w')
109
147
  File.stub!(:open).with(%r{/fake/path.yaml}, 'w').and_yield(fake_file)
110
- FileUtils.should_receive(:mkdir_p).with('/fake')
148
+ FileUtils.should_receive(:mkdir_p).with(%r{/fake})
111
149
  @config.save! '/fake/path.yaml'
112
150
  end
113
151
  end
@@ -81,6 +81,13 @@ describe DeepHash do
81
81
  deep_hash[:hash] = { :sym_key => "is buggy in Ruby 1.8.6" }
82
82
  deep_hash[:hash].should be_an_instance_of(DeepHash)
83
83
  end
84
+
85
+ it "only accepts #to_sym'bolizable things as keys" do
86
+ lambda{ @deep_hash[1] = 'hi' }.should raise_error(NoMethodError, /undefined method `to_sym'/)
87
+ lambda{ @deep_hash[{ :a => :b }] = 'hi' }.should raise_error(NoMethodError, /undefined method `to_sym'/)
88
+ lambda{ @deep_hash[Object.new] = 'hi' }.should raise_error(NoMethodError, /undefined method `to_sym'/)
89
+ lambda{ @deep_hash[:a] = 'hi' }.should_not raise_error
90
+ end
84
91
  end
85
92
 
86
93
  describe '#[]' do
@@ -96,6 +103,12 @@ describe DeepHash do
96
103
  else lambda{ @deep_hash['hat.cat'] }.should raise_error(NoMethodError, 'undefined method `[]\' for :cat:Symbol') end
97
104
  @deep_hash.should == hsh # shouldn't change from reading (specifically, shouldn't autovivify)
98
105
  end
106
+
107
+ it "only accepts #to_sym'bolizable things as keys" do
108
+ lambda{ @deep_hash[1] }.should raise_error(NoMethodError, /undefined method `to_sym'/)
109
+ lambda{ @deep_hash[{ :a => :b }] }.should raise_error(NoMethodError, /undefined method `to_sym'/)
110
+ lambda{ @deep_hash[Object.new] }.should raise_error(NoMethodError, /undefined method `to_sym'/)
111
+ end
99
112
  end
100
113
 
101
114
  def arrays_should_be_equal arr1, arr2
@@ -122,25 +135,25 @@ describe DeepHash do
122
135
 
123
136
  describe '#compact' do
124
137
  it 'removes nils but not empties or falsehoods' do
125
- DeepHash.new({ 1 => nil }).compact.should == {}
126
- DeepHash.new({ 1 => nil, 2 => false, 3 => {}, 4 => "", :remains => true }).compact!.should == { 2 => false, 3 => {}, 4 => "", :remains => true }
138
+ DeepHash.new({ :a => nil }).compact.should == {}
139
+ DeepHash.new({ :a => nil, :b => false, :c => {}, :d => "", :remains => true }).compact.should == { :b => false, :c => {}, :d => "", :remains => true }
127
140
  end
128
141
 
129
142
  it 'leaves original alone' do
130
- deep_hash = DeepHash.new({ 1 => nil, :remains => true })
143
+ deep_hash = DeepHash.new({ :a => nil, :remains => true })
131
144
  deep_hash.compact.should == { :remains => true }
132
- deep_hash.should == { 1 => nil, :remains => true }
145
+ deep_hash.should == { :a => nil, :remains => true }
133
146
  end
134
147
  end
135
148
 
136
149
  describe '#compact!' do
137
150
  it 'removes nils but not empties or falsehoods' do
138
- DeepHash.new({ 1 => nil}).compact!.should == {}
139
- DeepHash.new({ 1 => nil, 2 => false, 3 => {}, 4 => "", :remains => true }).compact!.should == { 2 => false, 3 => {}, 4 => "", :remains => true }
151
+ DeepHash.new({ :a => nil}).compact!.should == {}
152
+ DeepHash.new({ :a => nil, :b => false, :c => {}, :d => "", :remains => true }).compact!.should == { :b => false, :c => {}, :d => "", :remains => true }
140
153
  end
141
154
 
142
155
  it 'modifies in-place' do
143
- deep_hash = DeepHash.new({ 1 => nil, :remains => true })
156
+ deep_hash = DeepHash.new({ :a => nil, :remains => true })
144
157
  deep_hash.compact!.should == { :remains => true }
145
158
  deep_hash.should == { :remains => true }
146
159
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: configliere
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.4.6
5
+ version: 0.4.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - infochimps
@@ -11,12 +11,23 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-05-21 00:00:00 -05:00
14
+ date: 2011-06-28 00:00:00 -05:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
- name: bundler
18
+ name: json
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: *id001
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: &id002 !ruby/object:Gem::Requirement
20
31
  none: false
21
32
  requirements:
22
33
  - - ~>
@@ -24,10 +35,10 @@ dependencies:
24
35
  version: 1.0.12
25
36
  type: :development
26
37
  prerelease: false
27
- version_requirements: *id001
38
+ version_requirements: *id002
28
39
  - !ruby/object:Gem::Dependency
29
40
  name: yard
30
- requirement: &id002 !ruby/object:Gem::Requirement
41
+ requirement: &id003 !ruby/object:Gem::Requirement
31
42
  none: false
32
43
  requirements:
33
44
  - - ~>
@@ -35,10 +46,10 @@ dependencies:
35
46
  version: 0.6.7
36
47
  type: :development
37
48
  prerelease: false
38
- version_requirements: *id002
49
+ version_requirements: *id003
39
50
  - !ruby/object:Gem::Dependency
40
51
  name: jeweler
41
- requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirement: &id004 !ruby/object:Gem::Requirement
42
53
  none: false
43
54
  requirements:
44
55
  - - ~>
@@ -46,10 +57,10 @@ dependencies:
46
57
  version: 1.5.2
47
58
  type: :development
48
59
  prerelease: false
49
- version_requirements: *id003
60
+ version_requirements: *id004
50
61
  - !ruby/object:Gem::Dependency
51
62
  name: rspec
52
- requirement: &id004 !ruby/object:Gem::Requirement
63
+ requirement: &id005 !ruby/object:Gem::Requirement
53
64
  none: false
54
65
  requirements:
55
66
  - - ~>
@@ -57,10 +68,10 @@ dependencies:
57
68
  version: 2.5.0
58
69
  type: :development
59
70
  prerelease: false
60
- version_requirements: *id004
71
+ version_requirements: *id005
61
72
  - !ruby/object:Gem::Dependency
62
73
  name: spork
63
- requirement: &id005 !ruby/object:Gem::Requirement
74
+ requirement: &id006 !ruby/object:Gem::Requirement
64
75
  none: false
65
76
  requirements:
66
77
  - - ~>
@@ -68,10 +79,10 @@ dependencies:
68
79
  version: 0.9.0.rc5
69
80
  type: :development
70
81
  prerelease: false
71
- version_requirements: *id005
82
+ version_requirements: *id006
72
83
  - !ruby/object:Gem::Dependency
73
84
  name: RedCloth
74
- requirement: &id006 !ruby/object:Gem::Requirement
85
+ requirement: &id007 !ruby/object:Gem::Requirement
75
86
  none: false
76
87
  requirements:
77
88
  - - ">="
@@ -79,10 +90,10 @@ dependencies:
79
90
  version: "0"
80
91
  type: :development
81
92
  prerelease: false
82
- version_requirements: *id006
93
+ version_requirements: *id007
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: highline
85
- requirement: &id007 !ruby/object:Gem::Requirement
96
+ requirement: &id008 !ruby/object:Gem::Requirement
86
97
  none: false
87
98
  requirements:
88
99
  - - ">="
@@ -90,7 +101,7 @@ dependencies:
90
101
  version: 1.5.2
91
102
  type: :development
92
103
  prerelease: false
93
- version_requirements: *id007
104
+ version_requirements: *id008
94
105
  description: " You've got a script. It's got some settings. Some settings are for this module, some are for that module. Most of them don't change. Except on your laptop, where the paths are different. Or when you're in production mode. Or when you're testing from the command line.\n\n \"\" So, Consigliere of mine, I think you should tell your Don what everyone knows. \"\" -- Don Corleone\n\n\
95
106
  Configliere manage settings from many sources: static constants, simple config files, environment variables, commandline options, straight ruby. You don't have to predefine anything, but you can ask configliere to type-convert, require, document or password-obscure any of its fields. Modules can define config settings independently of each other and the main program.\n"
96
107
  email: coders@infochimps.org
@@ -174,7 +185,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
174
185
  requirements:
175
186
  - - ">="
176
187
  - !ruby/object:Gem::Version
177
- hash: 213250075244557737
188
+ hash: -3025764887803996140
178
189
  segments:
179
190
  - 0
180
191
  version: "0"