configuration_loader 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,47 @@
1
+ = Configuration Files Loader
2
+
3
+ Configuration Files Loader can be used as a gem or a Rails plugin to load various config files.
4
+
5
+ It finds config file fragments in a Rails config directory and in config directories of plugins and dependent gems. It then tries to merge them in the following order: gem<-plugin<-application. This allows overrides of global (gem/plugin) configs by individual applications. The supported types for merging are String, Hash, and Array. It caches the content of files by default. ConfigurationLoader is RoR environment aware and provides a shortcut ('load_section') to load a section of a config file corresponding to RAILS_ENV. It is being used in another method provided by ConfigurationLoader - 'load_db_config'. It loads a section from 'config/database.yml' providing a convenient method for placing secondary DB entries in a code as seen here:
6
+
7
+ establish_connection ConfigurationLoader.load_db_config['secondary_db']
8
+
9
+ See the 'DRYing Up Configuration Files' post in our team blog http://revolutiononrails.blogspot.com/2007/03/drying-up-configuration-files.html for additional details.
10
+
11
+
12
+ == Setup
13
+
14
+ === Installation
15
+
16
+ To install Configuration Files Loader as a gem:
17
+
18
+ Get the gem file from the project page (http://rubyforge.org/projects/config-loader) and install it
19
+
20
+ To install as a Rails plugin:
21
+
22
+ ruby script/plugin install svn://rubyforge.org/var/svn/config-loader/trunk/vendor/plugins/configuration_loader
23
+
24
+
25
+ === Usage
26
+
27
+ require 'configuration_loader'
28
+
29
+ ConfigurationLoader.load_db_config # gets the RAILS_ENV section from database.yml
30
+
31
+ ConfigurationLoader.load('cfg.yml') # loads a YAML-processed config file
32
+
33
+ ConfigurationLoader.load('cfg.yml', :erb => true) # loads a ERB+YAML-processed config file
34
+
35
+ ConfigurationLoader.load('cfg.yml', :section => RAILS_ENV) # loads a current RAILS_ENV section from a YAML-processed config file
36
+
37
+ ConfigLoader.load('cfg.yml', :cache => false) # loads an uncached copy YAML-processed config file
38
+
39
+
40
+ == License
41
+
42
+ Configuration Files Loader is released under the MIT license.
43
+
44
+
45
+ == Support
46
+
47
+ The RubyForge home page is http://rubyforge.org/projects/config-loader
@@ -0,0 +1,183 @@
1
+ # Configuration Files Loader can be used as a gem or a Rails plugin to load config files.
2
+ #
3
+ # It finds config file fragments in a rails config directory and in config directories of plugins and dependent gems.
4
+ # It then tries to merge them in order gem<-plugin<-application thus allowing overrides of global (gem/plugin) configs by individual applications.
5
+ # The supported types for merging are String, Hash, and Array.
6
+ #
7
+ # It caches the content of files by default.
8
+ #
9
+ # ConfigurationLoader is RoR environment aware and provides a short-cut 'load_section' to load a section of a config file corresponding to RAILS_ENV.
10
+ # It is being used in another method provided by ConfigurationLoader - load_db_config.
11
+ # It loads a section from 'config/database.yml' providing a convenience method for getting secondary DB entries in a code like this:
12
+ #
13
+ # establish_connection ConfigurationLoader.load_db_config['secondary_db']
14
+ #
15
+ # See the 'DRYing Up Configuration Files' post in our team blog http://revolutiononrails.blogspot.com/2007/03/drying-up-configuration-files.html
16
+ # for additional details.
17
+ #
18
+ #
19
+ # == Usage
20
+ #
21
+ # require 'configuration_loader'
22
+ #
23
+ # ConfigurationLoader.load_db_config # gets the RAILS_ENV section from database.yml
24
+ #
25
+ # ConfigurationLoader.load('cfg.yml') # loads a YAML-processed config file
26
+ #
27
+ # ConfigurationLoader.load('cfg.yml', :erb => true) # loads a ERB+YAML-processed config file
28
+ #
29
+ # ConfigurationLoader.load('cfg.yml', :section => RAILS_ENV) # loads a current RAILS_ENV section from a YAML-processed config file
30
+ #
31
+ # ConfigLoader.load('cfg.yml', :cache => false) # loads an uncached copy YAML-processed config file
32
+ #
33
+ class ConfigurationLoader
34
+
35
+ require 'yaml'
36
+ require 'erb'
37
+ require 'pp'
38
+
39
+ class << self
40
+
41
+ @@cached = {}
42
+
43
+ # Finds files with a provided file name, loads and processes them. The +options+ control the processing:
44
+ # :erb => true -- runs the file through ERB before YAML-processing (DEFAULT: false)
45
+ # :section => 'section_name' -- loads a specific section of the file (like 'development' for 'database.yml') (DEFAULT: nil)
46
+ # :merge => false -- returns an arrary of processed resulted without trying to merge them into a single entry (DEFAULT: true)
47
+ # :cache => false -- returns a non-cached copy (DEFAULT: true)
48
+ def load(file, supplied_options = {})
49
+ options = default_options.merge(supplied_options)
50
+ res = load_file(file, options)
51
+ res = sections(res, options[:section]) if options[:section]
52
+ res = merge(res) if options[:merge]
53
+ res
54
+ end
55
+
56
+ # A convenience method for loading the current RAILS_ENV section of the Rails DB config file
57
+ def load_db_config(section = default_section)
58
+ load('database.yml', :section => section)
59
+ end
60
+
61
+ # Empties the cached entry[es] thus forcing to reload from a file system next time
62
+ def refresh!(key = :everything)
63
+ case key
64
+ when :everything then
65
+ @@cached = {}
66
+ else
67
+ @@cached.delete(:__configs__)
68
+ @@cached.delete(key)
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def default_options
75
+ {
76
+ :erb => false,
77
+ :section => nil,
78
+ :merge => true,
79
+ :cache => true
80
+ }
81
+ end
82
+
83
+ def load_file(file, options)
84
+ cache(options[:cache])[file] ||= load_yaml_file(file, options)
85
+ end
86
+
87
+ def sections(configs, section)
88
+ configs.empty? ? nil : collect_sections(configs, section)
89
+ end
90
+
91
+ def collect_sections(configs, section)
92
+ configs.inject([]) do |config_sections, config|
93
+ config_sections << config[section] if (config.respond_to?('[]') && config[section])
94
+ config_sections
95
+ end
96
+ end
97
+
98
+ def default_section
99
+ (defined?(RAILS_ENV) && RAILS_ENV) || 'development'
100
+ end
101
+
102
+ def file_path(path, file)
103
+ File.join(path, file)
104
+ end
105
+
106
+ def cache(use_cache)
107
+ use_cache ? @@cached : {}
108
+ end
109
+
110
+ def config_files(use_cache)
111
+ cache(use_cache)[:__configs__] ||= begin
112
+ (load_pathes("/gems/") + load_pathes("vendor/plugins/") + app_root).uniq.inject([]) do |configs, path|
113
+ debug("Component: #{ path }")
114
+ config = File.join(path, 'config')
115
+ if File.exist?(config)
116
+ configs << config
117
+ debug('Has config')
118
+ else
119
+ debug('No config')
120
+ end
121
+ configs
122
+ end
123
+ end
124
+ end
125
+
126
+ def app_root
127
+ path = defined?(CONFIG_LOADER_ROOT) ? CONFIG_LOADER_ROOT : RAILS_ROOT
128
+ [ File.expand_path(path) ]
129
+ end
130
+
131
+ def load_pathes(pattern)
132
+ $:.grep(%r{#{ pattern }}).collect { |path| File.expand_path(path[%r{.*#{ pattern }[^/]+}]) }
133
+ end
134
+
135
+ def load_yaml_file(file_name, options)
136
+ config_files(options[:cache]).inject([]) do |loaded, config_path|
137
+ file = file_path(config_path, file_name)
138
+ debug("Probing #{ file }")
139
+ if File.exist?(file)
140
+ loaded << YAML.load(file_loader(file, options))
141
+ debug('Found')
142
+ else
143
+ debug('Not found')
144
+ end
145
+ loaded
146
+ end
147
+
148
+ end
149
+
150
+ def file_loader(file, options)
151
+ res = IO.read(file)
152
+ res = ERB.new(res).result if options[:erb]
153
+ res
154
+ end
155
+
156
+ def merge(values)
157
+
158
+ debug('Merging configs:') { pp values }
159
+
160
+ case
161
+ when all_are?(values, Hash) then
162
+ values.inject({}) { |c, v| c.merge(v) }
163
+ when all_are?(values, Array) then
164
+ values.inject([]) { |c, v| c + v }
165
+ else
166
+ values.last
167
+ end
168
+
169
+ end
170
+
171
+ def all_are?(values, type)
172
+ values.all? { |v| v.is_a?(type) }
173
+ end
174
+
175
+ def debug(msg)
176
+ if ENV['CONFIG_LOADER_DEBUG']
177
+ puts "CONFIG_LOADER: #{ msg }"
178
+ yield if block_given?
179
+ end
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,110 @@
1
+ require File.dirname(__FILE__) + '/../lib/configuration_loader'
2
+ require 'test/unit'
3
+
4
+ class ConfigurationLoaderTest < Test::Unit::TestCase
5
+
6
+ ::CONFIG_LOADER_ROOT = File.join(File.dirname(__FILE__), 'configs')
7
+
8
+ ['vendor/plugins', 'gems'].each do |dir|
9
+ Dir["#{ CONFIG_LOADER_ROOT }/#{ dir }/*"].each { |path| $: << path }
10
+ end
11
+
12
+ def test_default_db_config
13
+ cfg = ConfigurationLoader.load_db_config
14
+ assert_not_equal Hash.new, cfg
15
+ assert cfg['loaded']
16
+ end
17
+
18
+ def test_db_config_section
19
+ cfg = ConfigurationLoader.load_db_config('test')
20
+ assert_not_equal Hash.new, cfg
21
+ assert_equal 'app_db', cfg['db']
22
+ assert cfg['app_db']
23
+ assert cfg['plugin_db']
24
+ assert cfg['gem_db']
25
+ end
26
+
27
+ def test_db_config_unknown_section
28
+ cfg = ConfigurationLoader.load_db_config('unknown')
29
+ assert_equal Hash.new, cfg
30
+ end
31
+
32
+ def test_merging_config
33
+ cfg = ConfigurationLoader.load('cfg.yml')
34
+ assert cfg['hash']['app']
35
+ assert_nil cfg['hash']['plugin']
36
+ assert_nil cfg['hash']['gem']
37
+ assert_equal [ "app_one", "app_two" ], cfg['array']
38
+ end
39
+
40
+ def test_merging_hash
41
+ cfg = ConfigurationLoader.load('cfg.yml', :section => 'hash')
42
+ assert_equal 'app', cfg['global'], 'App takes the precedence among app, plugin, and gem'
43
+ assert_equal 'plugin', cfg['component'], 'Plugin takes the precedence between plugin and gem'
44
+ assert cfg['app']
45
+ assert cfg['plugin']
46
+ assert cfg['gem']
47
+ end
48
+
49
+ def test_merging_array
50
+ cfg = ConfigurationLoader.load('cfg.yml', :section => 'array')
51
+ ["app_one", "app_two", "plugin_one", "plugin_two", "gem_one", "gem_two"].each { |e| assert cfg.include?(e) }
52
+ end
53
+
54
+ def test_merging_string
55
+ cfg = ConfigurationLoader.load('cfg.yml', :section => 'string')
56
+ assert_equal 'app', cfg
57
+ end
58
+
59
+ def test_no_merging
60
+ cfg = ConfigurationLoader.load('cfg.yml', :section => 'string', :merge => false)
61
+ ["app", "plugin", "gem"].each { |e| assert cfg.include?(e) }
62
+ end
63
+
64
+ def test_erb_processing
65
+ cfg = ConfigurationLoader.load('cfg.yml')
66
+ assert_equal '<%= 1 %>', cfg['erb']
67
+ erb = ConfigurationLoader.load('cfg.yml', :erb => true, :cache => false)
68
+ assert_equal 1, erb['erb']
69
+ end
70
+
71
+ def test_no_caching
72
+
73
+ cfg = ConfigurationLoader.load('cfg.yml')
74
+ assert_nil cfg['optional']
75
+
76
+ add_optional_gem
77
+
78
+ cached = ConfigurationLoader.load('cfg.yml')
79
+ assert_nil cached['optional'], "Still nil since cached"
80
+
81
+ fresh = ConfigurationLoader.load('cfg.yml', :cache => false)
82
+ assert fresh['optional']
83
+
84
+ end
85
+
86
+ def test_refresh
87
+
88
+ assert_equal Hash.new, ConfigurationLoader.load('optional.yml')
89
+ cfg = ConfigurationLoader.load('cfg.yml')
90
+ assert_nil cfg['optional']
91
+
92
+ add_optional_gem
93
+ ConfigurationLoader.refresh!('cfg.yml')
94
+
95
+ fresh = ConfigurationLoader.load('cfg.yml', :cache => false)
96
+ assert fresh['optional']
97
+ assert_equal Hash.new, ConfigurationLoader.load('optional.yml'), 'Was not refreshed'
98
+
99
+ ConfigurationLoader.refresh!
100
+ assert ConfigurationLoader.load('optional.yml')['loaded']
101
+
102
+ end
103
+
104
+ private
105
+
106
+ def add_optional_gem
107
+ $: << "#{ CONFIG_LOADER_ROOT }/optional_config/gems/optional_gem"
108
+ end
109
+
110
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: configuration_loader
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-03-16 00:00:00 -04:00
8
+ summary: Configuration files loader
9
+ require_paths:
10
+ - lib
11
+ email: rails-trunk@revolution.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - RHG Team
31
+ files:
32
+ - lib/configuration_loader.rb
33
+ - README
34
+ test_files:
35
+ - test/configuration_loader_test.rb
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+