autoconfig 1.0.0 → 1.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.
Files changed (2) hide show
  1. data/lib/autoconfig.rb +119 -90
  2. metadata +3 -3
@@ -3,122 +3,151 @@ require 'yaml'
3
3
  require 'erb'
4
4
  require 'set'
5
5
 
6
- module StringCamelize
7
- # Taken straight from active support inflector.rb, line 161
8
- def camelize(first_letter_in_uppercase = true)
9
- if first_letter_in_uppercase
10
- to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
11
- else
12
- first + camelize(self)[1..-1]
13
- end
14
- end
15
- end
16
- String.send(:include, StringCamelize) unless String.instance_methods.include?("camelize")
17
6
 
18
- class AutoConfig
7
+ module AutoConfig
19
8
  REQUIRED = :REQUIRED
20
9
  YAML.add_builtin_type( 'REQUIRED' ){ REQUIRED }
21
10
 
22
- class << self
23
- def root
24
- rails_root = (rails? && (Rails.root || File.expand_path('../', ENV['BUNDLE_GEMFILE'])))
25
- ENV['AUTOCONFIG_ROOT'] || ENV['APP_ROOT'] || rails_root || Dir.pwd
26
- end
27
-
28
- def pattern
29
- ENV['AUTOCONFIG_PATTERN'] || 'config/*.yml'
30
- end
31
-
32
- def path
33
- ENV['AUTOCONFIG_PATH'] || File.expand_path(pattern, root)
11
+ module StringCamelize
12
+ # Taken straight from active support inflector.rb, line 161
13
+ def camelize(first_letter_in_uppercase = true)
14
+ if first_letter_in_uppercase
15
+ to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
16
+ else
17
+ first + camelize(self)[1..-1]
18
+ end
34
19
  end
35
-
36
- def environment
37
- ENV['AUTOCONFIG_ENV'] || ENV['APP_ENV'] || (rails? && Rails.env) || 'development'
20
+ end
21
+ String.send(:include, StringCamelize) unless String.instance_methods.include?("camelize")
22
+
23
+ class OpenStruct < ::OpenStruct
24
+ def method_missing(mid, *args) # :nodoc:
25
+ mname = mid.id2name
26
+ len = args.length
27
+ if mname.chomp!('=')
28
+ if len != 1
29
+ raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
30
+ end
31
+ modifiable[new_ostruct_member(mname)] = args[0]
32
+ elsif len == 0 && @table.key?( mid )
33
+ @table[mid]
34
+ else
35
+ raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
36
+ end
38
37
  end
38
+ end
39
39
 
40
- def rails?
41
- Object::const_defined? "Rails"
42
- end
40
+ class Base
41
+ class << self
42
+ def root
43
+ rails_root = (rails? && (Rails.root || File.expand_path('../', ENV['BUNDLE_GEMFILE'])))
44
+ ENV['AUTOCONFIG_ROOT'] || ENV['APP_ROOT'] || rails_root || Dir.pwd
45
+ end
43
46
 
44
- def ignored_filenames
45
- names = ENV['AUTOCONFIG_IGNORE'] ? "database|" + ENV['AUTOCONFIG_IGNORE'].gsub(/\s/,'|') : 'database'
46
- Regexp.new(names)
47
- end
47
+ def pattern
48
+ ENV['AUTOCONFIG_PATTERN'] || 'config/*.yml'
49
+ end
48
50
 
49
- def reload
50
- wipe
51
- files = Dir.glob(path)
52
- begin
53
- old_verbose, $VERBOSE = $VERBOSE, nil
51
+ def path
52
+ ENV['AUTOCONFIG_PATH'] || File.expand_path(pattern, root)
53
+ end
54
54
 
55
- files.each do |file|
56
- name = File.basename(file, '.yml')
57
- next if name.match(ignored_filenames)
55
+ def environment
56
+ ENV['AUTOCONFIG_ENV'] || ENV['APP_ENV'] || (rails? && Rails.env) || 'development'
57
+ end
58
58
 
59
- constant_name = "#{name}Config".gsub('-','_').camelize
60
- yaml_config = YAML::load(ERB.new(IO.read(file)).result)
59
+ def rails?
60
+ Object::const_defined? "Rails"
61
+ end
61
62
 
62
- @ordered_stanza_labels[constant_name] = []
63
- @ordered_stanza_labels[constant_name] << 'defaults' if yaml_config.key? 'defaults'
64
- @ordered_stanza_labels[constant_name] += yaml_config.keys.grep(/^defaults\[.*#{environment}/).sort_by{ |a| a.count(',') }
65
- @ordered_stanza_labels[constant_name] << environment if yaml_config.key? environment
63
+ def ignored_filenames
64
+ names = ENV['AUTOCONFIG_IGNORE'] ? "database|" + ENV['AUTOCONFIG_IGNORE'].gsub(/\s/,'|') : 'database'
65
+ Regexp.new(names)
66
+ end
66
67
 
67
- config = @ordered_stanza_labels[constant_name].inject({}) do |acc, label|
68
- deep_merge(acc,yaml_config[label])
68
+ def reload
69
+ wipe
70
+ files = Dir.glob(path)
71
+ begin
72
+ old_verbose, $VERBOSE = $VERBOSE, nil
73
+
74
+ files.each do |file|
75
+ name = File.basename(file, '.yml')
76
+ next if name.match(ignored_filenames)
77
+
78
+ constant_name = "#{name}Config".gsub('-','_').camelize
79
+ begin
80
+ yaml_config = YAML::load(ERB.new(IO.read(file)).result)
81
+
82
+ @ordered_stanza_labels[constant_name] = []
83
+ @ordered_stanza_labels[constant_name] << 'defaults' if yaml_config.key? 'defaults'
84
+ @ordered_stanza_labels[constant_name] += yaml_config.keys.grep(/^defaults\[.*#{environment}/).sort_by{ |a| a.count(',') }
85
+ @ordered_stanza_labels[constant_name] << environment if yaml_config.key? environment
86
+
87
+ config = @ordered_stanza_labels[constant_name].inject({}) do |acc, label|
88
+ deep_merge(acc,yaml_config[label])
89
+ end
90
+
91
+ ensure_requirements_met_and_ostructify!(config, constant_name )
92
+
93
+ Object::const_set(constant_name.intern, OpenStruct.new(config))
94
+ rescue StandardError => e
95
+ @errors << <<-ERROR
96
+ Error reading file #{file} into #{constant_name}.
97
+ #{$!.inspect}
98
+ #{$@}
99
+ You can skip it by adding it to AUTOCONFIG_IGNORE.
100
+ ERROR
101
+ end
69
102
  end
70
103
 
71
- ensure_requirements_met_and_ostructify!(config, constant_name )
104
+ raise @errors.to_a.join( "\n" ) unless @errors.empty?
72
105
 
73
- Object::const_set(constant_name.intern, OpenStruct.new(config))
106
+ ensure
107
+ $VERBOSE = old_verbose
74
108
  end
75
-
76
- raise @errors.to_a.join( "\n" ) unless @errors.empty?
77
-
78
- ensure
79
- $VERBOSE = old_verbose
80
109
  end
81
- end
82
110
 
83
- private
84
- # unsets created constants
85
- def wipe
86
- unless @ordered_stanza_labels.nil?
87
- @ordered_stanza_labels.keys.each{|const| Object::const_set(const.intern, nil) }
111
+ private
112
+ # unsets created constants
113
+ def wipe
114
+ unless @ordered_stanza_labels.nil?
115
+ @ordered_stanza_labels.keys.each{|const| Object::const_set(const.intern, nil) }
116
+ end
117
+ @ordered_stanza_labels = {}
118
+ @errors = Set.new
88
119
  end
89
- @ordered_stanza_labels = {}
90
- @errors = Set.new
91
- end
92
120
 
93
- # merges two hashes with nested hashes if present
94
- def deep_merge( hash1, hash2 )
95
- hash1 = hash1.dup
96
- ( hash1.keys + hash2.keys ).each do | key |
97
- if hash1.key?( key ) && hash2.key?( key ) &&
98
- hash1[key].is_a?( Hash ) && hash2[key].is_a?( Hash )
99
- hash1[key] = deep_merge( hash1[key], hash2[key] )
100
- elsif hash2.key?( key )
101
- hash1[key] = hash2[key]
121
+ # merges two hashes with nested hashes if present
122
+ def deep_merge( hash1, hash2 )
123
+ hash1 = hash1.dup
124
+ ( hash1.keys + hash2.keys ).each do | key |
125
+ if hash1.key?( key ) && hash2.key?( key ) &&
126
+ hash1[key].is_a?( Hash ) && hash2[key].is_a?( Hash )
127
+ hash1[key] = deep_merge( hash1[key], hash2[key] )
128
+ elsif hash2.key?( key )
129
+ hash1[key] = hash2[key]
130
+ end
102
131
  end
132
+ hash1
103
133
  end
104
- hash1
105
- end
106
- # Mutator method that does two things:
107
- # * checks if any of the keys were required and not set. Upon finding
108
- # it adds key to the error set
109
- # * recursively sets open structs for deep hashes
110
- def ensure_requirements_met_and_ostructify!( hash, path )
111
- hash.each do | key, value |
112
- case
113
- when value.respond_to?( :keys ) && value.respond_to?( :values )
114
- ensure_requirements_met_and_ostructify!( value, path + '.' + key )
115
- when value == REQUIRED
116
- @errors << "#{path}.#{key} is REQUIRED"
134
+ # Mutator method that does two things:
135
+ # * checks if any of the keys were required and not set. Upon finding
136
+ # it adds key to the error set
137
+ # * recursively sets open structs for deep hashes
138
+ def ensure_requirements_met_and_ostructify!( hash, path )
139
+ hash.each do | key, value |
140
+ case
141
+ when value.respond_to?( :keys ) && value.respond_to?( :values )
142
+ ensure_requirements_met_and_ostructify!( value, path + '.' + key )
143
+ when value == REQUIRED
144
+ @errors << "#{path}.#{key} is REQUIRED"
145
+ end
146
+ hash[key] = OpenStruct.new(value) if value.is_a?( Hash )
117
147
  end
118
- hash[key] = OpenStruct.new(value) if value.is_a?( Hash )
119
148
  end
120
149
  end
121
150
  end
122
151
  end
123
152
 
124
- AutoConfig.reload
153
+ AutoConfig::Base.reload
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoconfig
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 0
10
- version: 1.0.0
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - tjbladez