autoconfig 1.1.0 → 2.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.
- data/README.markdown +8 -5
- data/lib/autoconfig.rb +21 -79
- metadata +32 -42
data/README.markdown
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
!!!plain
|
2
|
-
|
2
|
+
_ ____
|
3
3
|
| | / __/
|
4
4
|
__ _ _ _| |_ ___ ___ ___ _ __ | |_ _ __ _
|
5
5
|
/ _` | | | | __|/ _ \ / __|/ _ \| '_ \| _| |/ _` |
|
@@ -10,9 +10,11 @@
|
|
10
10
|
|
11
11
|
## What is it
|
12
12
|
|
13
|
-
|
13
|
+
`autoconfig` in an automated way to create flexible configuration structures.
|
14
|
+
|
15
|
+
Since version 2.0.0 `autoconfig` relies on [heirarchical_config](https://rubygems.org/gems/hierarchical_config) for the strategy for configuring an application in a static, declarative, robust, and intuitive way.
|
14
16
|
|
15
|
-
##
|
17
|
+
## Usage
|
16
18
|
|
17
19
|
1. require 'autoconfig'
|
18
20
|
2. profit!
|
@@ -30,8 +32,8 @@ Lets say you have application.yml in your config folder:
|
|
30
32
|
web:
|
31
33
|
hostname: "the.production.com"
|
32
34
|
|
33
|
-
After requiring 'autoconfig' you should expect ApplicationConfig structure that will contain all the information.
|
34
|
-
ApplicationConfig.web.hostname call will return
|
35
|
+
After requiring 'autoconfig' you should expect `ApplicationConfig` structure that will contain all the information.
|
36
|
+
In production environment `ApplicationConfig.web.hostname` call will return `the.production.com`.
|
35
37
|
|
36
38
|
## Advance Example
|
37
39
|
|
@@ -66,6 +68,7 @@ Check it out under test/config/one
|
|
66
68
|
three: five
|
67
69
|
|
68
70
|
Autoconfig can support:
|
71
|
+
|
69
72
|
* specifying which keys are required via !REQUIRED yaml type
|
70
73
|
* environment specific defaults shared across some environments
|
71
74
|
* deep nested structures
|
data/lib/autoconfig.rb
CHANGED
@@ -1,13 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
require 'yaml'
|
3
|
-
require 'erb'
|
4
|
-
require 'set'
|
5
|
-
|
1
|
+
require 'hierarchical_config'
|
6
2
|
|
7
3
|
module AutoConfig
|
8
|
-
REQUIRED = :REQUIRED
|
9
|
-
YAML.add_builtin_type( 'REQUIRED' ){ REQUIRED }
|
10
|
-
|
11
4
|
module StringCamelize
|
12
5
|
# Taken straight from active support inflector.rb, line 161
|
13
6
|
def camelize(first_letter_in_uppercase = true)
|
@@ -20,23 +13,6 @@ module AutoConfig
|
|
20
13
|
end
|
21
14
|
String.send(:include, StringCamelize) unless String.instance_methods.include?("camelize")
|
22
15
|
|
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
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
16
|
class Base
|
41
17
|
class << self
|
42
18
|
def root
|
@@ -45,11 +21,11 @@ module AutoConfig
|
|
45
21
|
end
|
46
22
|
|
47
23
|
def pattern
|
48
|
-
ENV['AUTOCONFIG_PATTERN'] || '
|
24
|
+
ENV['AUTOCONFIG_PATTERN'] || '*.yml'
|
49
25
|
end
|
50
26
|
|
51
27
|
def path
|
52
|
-
ENV['AUTOCONFIG_PATH'] || File.expand_path(
|
28
|
+
ENV['AUTOCONFIG_PATH'] || File.expand_path('config',root)
|
53
29
|
end
|
54
30
|
|
55
31
|
def environment
|
@@ -65,32 +41,26 @@ module AutoConfig
|
|
65
41
|
Regexp.new(names)
|
66
42
|
end
|
67
43
|
|
68
|
-
def
|
44
|
+
def load(name)
|
45
|
+
HierarchicalConfig.load_config( name, path, environment )
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def autoload
|
69
50
|
wipe
|
70
|
-
files = Dir.glob(path)
|
51
|
+
files = Dir.glob(File.join(path,pattern))
|
71
52
|
begin
|
72
53
|
old_verbose, $VERBOSE = $VERBOSE, nil
|
73
54
|
|
74
55
|
files.each do |file|
|
75
|
-
name = File.basename(file,
|
76
|
-
next if name.match(ignored_filenames)
|
56
|
+
name = File.basename(file, pattern.gsub('*',''))
|
57
|
+
next if name.match(ignored_filenames) || name.match(/-overrides/)
|
77
58
|
|
78
|
-
constant_name = "#{name}Config".gsub('-','_').camelize
|
59
|
+
constant_name = "#{name}Config".gsub('-','_').camelize.intern
|
79
60
|
begin
|
80
|
-
|
81
|
-
|
82
|
-
@
|
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))
|
61
|
+
Object::const_set(constant_name, load(name))
|
62
|
+
@autoset_constants ||= Set.new
|
63
|
+
@autoset_constants << constant_name
|
94
64
|
rescue StandardError => e
|
95
65
|
@errors << <<-ERROR
|
96
66
|
Error reading file #{file} into #{constant_name}.
|
@@ -108,46 +78,18 @@ module AutoConfig
|
|
108
78
|
end
|
109
79
|
end
|
110
80
|
|
81
|
+
alias :reload :autoload
|
82
|
+
|
111
83
|
private
|
84
|
+
|
112
85
|
# unsets created constants
|
113
86
|
def wipe
|
114
|
-
unless @
|
115
|
-
@
|
87
|
+
unless @autoset_constants.nil?
|
88
|
+
@autoset_constants.each{|const| Object::const_set(const, nil) }
|
116
89
|
end
|
117
|
-
@ordered_stanza_labels = {}
|
118
90
|
@errors = Set.new
|
119
91
|
end
|
120
92
|
|
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
|
131
|
-
end
|
132
|
-
hash1
|
133
|
-
end
|
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 )
|
147
|
-
end
|
148
|
-
end
|
149
93
|
end
|
150
94
|
end
|
151
95
|
end
|
152
|
-
|
153
|
-
AutoConfig::Base.reload
|
metadata
CHANGED
@@ -1,69 +1,59 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoconfig
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '2.0'
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 1.1.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- tjbladez
|
14
9
|
- timgaleckas
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
13
|
+
date: 2011-10-12 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hierarchical_config
|
17
|
+
requirement: &70155900128960 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70155900128960
|
26
|
+
description: Automated way to create flexible configuration structures representing
|
27
|
+
your YAML configuration
|
24
28
|
email: nick@tjbladez.com, tim@galeckas.com
|
25
29
|
executables: []
|
26
|
-
|
27
30
|
extensions: []
|
28
|
-
|
29
31
|
extra_rdoc_files: []
|
30
|
-
|
31
|
-
files:
|
32
|
+
files:
|
32
33
|
- lib/autoconfig.rb
|
33
34
|
- README.markdown
|
34
|
-
has_rdoc: false
|
35
35
|
homepage: http://github.com/tjbladez/autoconfig
|
36
36
|
licenses: []
|
37
|
-
|
38
37
|
post_install_message: Forget about loading your yaml configuration
|
39
38
|
rdoc_options: []
|
40
|
-
|
41
|
-
require_paths:
|
39
|
+
require_paths:
|
42
40
|
- lib
|
43
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
42
|
none: false
|
45
|
-
requirements:
|
46
|
-
- -
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
|
49
|
-
|
50
|
-
- 0
|
51
|
-
version: "0"
|
52
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
48
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
|
58
|
-
segments:
|
59
|
-
- 0
|
60
|
-
version: "0"
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
61
53
|
requirements: []
|
62
|
-
|
63
54
|
rubyforge_project:
|
64
|
-
rubygems_version: 1.
|
55
|
+
rubygems_version: 1.8.10
|
65
56
|
signing_key:
|
66
57
|
specification_version: 3
|
67
58
|
summary: Automagically creates Config structures from your config/*.yml files
|
68
59
|
test_files: []
|
69
|
-
|