merb_app_config 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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jacques Crocker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,90 @@
1
+ == Summary
2
+ Application level configuration.
3
+
4
+ == Author
5
+ Jacques Crocker
6
+ Modified from Original Project (AppConfig by Christopher J. Bottaro)
7
+
8
+ === Compatibility
9
+ Rails 2.1/2.2 and Merb 1.0
10
+
11
+ === Accessing the AppConfig object
12
+ After installing this plugin, the AppConfig object will be global available. Entries are accessed via object member notation:
13
+ AppConfig.my_config_entry
14
+ Nested entries are supported:
15
+ AppConfig.my_section.some_entry
16
+
17
+ === Common config file
18
+ Config entries are compiled from
19
+ config/app_config.yml
20
+ config/app_config/settings.yml
21
+ config/app_config/#{environment}.yml
22
+ config/environments/#{environment}.yml
23
+ config/app_config/assets.yml
24
+ config/app_config/stylesheets.yml
25
+ config/app_config/javascripts.yml
26
+
27
+ settings defined in files that are lower in the list override settings higher
28
+
29
+ === Reloading config files
30
+ You can reload the AppConfig from file at any time by running AppConfig.reload!
31
+
32
+ === Environment specific config files
33
+ You can have environment specific config files. Environment specific config entries take precedence over common config entries.
34
+
35
+ Example development environment config file:
36
+ RAILS_ROOT/config/environments/development.yml
37
+
38
+ Example production environment config file:
39
+ RAILS_ROOT/config/environments/production.yml
40
+
41
+ === Embedded Ruby (ERB)
42
+ Embedded Ruby is allowed in the configuration files. See examples below.
43
+
44
+ === Accessing Configuration Settings
45
+ Consider the two following config files.
46
+
47
+ RAILS_ROOT/config/app_config.yml:
48
+ size: 1
49
+ server: google.com
50
+
51
+ RAILS_ROOT/config/environments/development.yml:
52
+ size: 2
53
+ computed: <%= 1 + 2 + 3 %>
54
+ section:
55
+ size: 3
56
+ servers: [ {name: yahoo.com}, {name: amazon.com} ]
57
+
58
+ Notice that the environment specific config entries overwrite the common entries.
59
+ AppConfig.size -> 2
60
+ AppConfig.server -> google.com
61
+
62
+ Notice the embedded Ruby.
63
+ AppConfig.computed -> 6
64
+
65
+ Notice that object member notation is maintained even in nested entries.
66
+ AppConfig.section.size -> 3
67
+
68
+ Notice array notation and object member notation is maintained.
69
+ AppConfig.section.servers[0].name -> yahoo.com
70
+ AppConfig.section.servers[1].name -> amazon.com
71
+
72
+
73
+ ==== Managing Asset Files with AppConfig
74
+ Defining stylesheets: and/or javascripts: keys will allow you to easily manage lists of assets via config
75
+
76
+ javascripts:
77
+ - application.js
78
+ - prototype_scriptaculous:
79
+ - prototype.js
80
+ - scriptaculous/effects.js
81
+ - base:
82
+ - libraries/*.js
83
+
84
+ All * file paths will be expanded out into a full list of files.
85
+
86
+ To add these javascripts to your layout just run
87
+
88
+ <%= javascripts_from_config %>
89
+
90
+ This will group the assets by key in order to use the built in Bundling
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ require 'merb-core'
5
+ require 'merb-core/tasks/merb'
6
+
7
+ GEM_NAME = "merb_app_config"
8
+ GEM_VERSION = "1.0"
9
+ AUTHOR = "Jacques Crocker"
10
+ EMAIL = "merbjedi@gmail.com"
11
+ HOMEPAGE = "http://www.merbjedi.com/"
12
+ SUMMARY = "Merb plugin that provides easy to use Application Configurations via YAML"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.rubyforge_project = 'merb'
16
+ s.name = GEM_NAME
17
+ s.version = GEM_VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.has_rdoc = true
20
+ s.extra_rdoc_files = ["README", "LICENSE"]
21
+ s.summary = SUMMARY
22
+ s.description = s.summary
23
+ s.author = AUTHOR
24
+ s.email = EMAIL
25
+ s.homepage = HOMEPAGE
26
+ s.add_dependency('merb', '>= 1.0')
27
+ s.add_dependency('merb-assets', '>= 1.0')
28
+ s.require_path = 'lib'
29
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{lib,spec}/**/*")
30
+ end
31
+
32
+ Rake::GemPackageTask.new(spec) do |pkg|
33
+ pkg.gem_spec = spec
34
+ end
35
+
36
+ desc "install the plugin as a gem"
37
+ task :install do
38
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
39
+ end
40
+
41
+ desc "Uninstall the gem"
42
+ task :uninstall do
43
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
44
+ end
45
+
46
+ desc "Create a gemspec file"
47
+ task :gemspec do
48
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
49
+ file.puts spec.to_ruby
50
+ end
51
+ end
52
+
53
+ require 'lib/merbtasks'
@@ -0,0 +1,132 @@
1
+ require 'ostruct'
2
+ require 'yaml'
3
+ require 'erb'
4
+
5
+ module ApplicationConfig
6
+ # == Summary
7
+ # This is API documentation, NOT documentation on how to use this plugin. For that, see the README.
8
+ class ConfigBuilder
9
+ @@load_paths = []
10
+ @@expand_keys = []
11
+ @@root_path = ""
12
+
13
+ # Create a config object (OpenStruct) from a yaml file. If a second yaml file is given, then the sections of that file will overwrite the sections
14
+ # if the first file if they exist in the first file.
15
+ def self.load_files(options = {})
16
+ config = OpenStruct.new
17
+
18
+ @@load_paths = [options[:paths]].flatten.compact.uniq
19
+ @@expand_keys = [options[:expand_keys]].flatten.compact.uniq
20
+ @@root_path = options[:root_path]
21
+
22
+ # add singleton method to our AppConfig that reloads its settings from the load_paths options
23
+ def config.reload!
24
+ conf = {}
25
+ ConfigBuilder.load_paths.to_a.each do |path|
26
+ file_conf = YAML.load(ERB.new(IO.read(path)).result) if path and File.exists?(path)
27
+ conf.merge!(file_conf) if file_conf
28
+ end
29
+
30
+ # expand the javascripts config to handle *.* paths
31
+ ConfigBuilder.expand_keys.to_a.each do |expand_path|
32
+ expand_path = expand_path.to_s
33
+ if conf[expand_path]
34
+ conf[expand_path] = ApplicationConfig::ConfigBuilder.expand(conf[expand_path], "#{ConfigBuilder.root_path}/public/#{expand_path}")
35
+ end
36
+ end
37
+
38
+ # load all the new values into the openstruct
39
+ marshal_load(ApplicationConfig::ConfigBuilder.convert(conf).marshal_dump)
40
+
41
+ return self
42
+ end
43
+
44
+ config.reload!
45
+ return config
46
+ end
47
+
48
+ def self.load_paths
49
+ @@load_paths
50
+ end
51
+
52
+ def self.expand_keys
53
+ @@expand_keys
54
+ end
55
+
56
+ def self.root_path
57
+ @@root_path
58
+ end
59
+
60
+ # Recursively converts Hashes to OpenStructs (including Hashes inside Arrays)
61
+ def self.convert(h) #:nodoc:
62
+ s = OpenStruct.new
63
+ h.each do |k, v|
64
+ s.new_ostruct_member(k)
65
+ if v.is_a?(Hash)
66
+ s.send( (k+'=').to_sym, convert(v))
67
+ elsif v.is_a?(Array)
68
+ converted_array = v.collect { |e| e.instance_of?(Hash) ? convert(e) : e }
69
+ s.send("#{k}=".to_sym, converted_array)
70
+ else
71
+ s.send("#{k}=".to_sym, v)
72
+ end
73
+ end
74
+ s
75
+ end
76
+
77
+ # expand a config val
78
+ def self.expand(config, base_path)
79
+ case config.class.to_s
80
+ when "Hash"
81
+ return expand_hash(config, base_path)
82
+ when "Array"
83
+ return expand_array(config, base_path)
84
+ when "String"
85
+ return expand_string(config, base_path)
86
+ end
87
+ return config
88
+ end
89
+
90
+ # expand a string and returns a list
91
+ def self.expand_string(config, base_path)
92
+ # puts "Expanding String: #{config.inspect}"
93
+ if config.include?("*")
94
+ results = Dir["#{base_path}/#{config}"].map{|i| i.to_s.gsub("#{base_path}/", "") }
95
+
96
+ # puts "EXPANDED PATH: #{base_path}/#{config}"
97
+ # puts results.inspect
98
+ return results
99
+ else
100
+ return config
101
+ end
102
+ end
103
+
104
+ # expand a hash by cycling throw all the hash values
105
+ def self.expand_hash(config, base_path)
106
+ # puts "Expanding Hash: #{config.inspect}"
107
+ new_config = {}
108
+ config.each do |key, val|
109
+ new_config[key] = expand(val, base_path)
110
+ end
111
+ return new_config
112
+ end
113
+
114
+ # expand an array by cycling through all the values
115
+ def self.expand_array(config, base_path)
116
+ # puts "Expanding Array: #{config.inspect}"
117
+ new_config = []
118
+ config.each do |val|
119
+ new_val = expand(val, base_path)
120
+ if new_val.is_a?(Array)
121
+ new_val.each do |inner|
122
+ new_config << inner
123
+ end
124
+ else
125
+ new_config << new_val
126
+ end
127
+ end
128
+ return new_config.uniq
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,71 @@
1
+ module ApplicationConfig
2
+ module ViewHelpers
3
+ def javascripts_from_config(options = {})
4
+ html = ""
5
+ if defined?(AppConfig) and AppConfig.javascripts
6
+ AppConfig.javascripts.each do |javascript|
7
+ if javascript.is_a?(OpenStruct)
8
+ javascript = javascript.marshal_dump
9
+ end
10
+
11
+ if javascript.is_a? Hash
12
+ javascript.each do |key, val|
13
+ args = [val].flatten
14
+ args = args.map{|s| s.gsub("javascripts/", AppConfig.javascript_path)} if AppConfig.javascript_path
15
+ if defined?(Merb)
16
+ args << options.merge(:bundle => key.to_sym)
17
+ html << js_include_tag(*args)
18
+ elsif defined?(Rails)
19
+ args << options.merge(:cache => key.to_s)
20
+ html << javascript_include_tag(*args)
21
+ end
22
+ html << "\n"
23
+ end
24
+ else
25
+ args = [javascript].flatten
26
+ args = args.map{|s| s.gsub("javascripts/", AppConfig.javascript_path)} if AppConfig.javascript_path
27
+ args << options
28
+ if defined?(Merb)
29
+ html << js_include_tag(*args)
30
+ elsif defined?(Rails)
31
+ html << javascript_include_tag(*args)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ return html
37
+ end
38
+
39
+ def stylesheets_from_config(options = {})
40
+ html = ""
41
+ if defined?(AppConfig) and AppConfig.stylesheets
42
+ AppConfig.stylesheets.each do |stylesheet|
43
+ if stylesheet.is_a?(OpenStruct)
44
+ stylesheet = stylesheet.marshal_dump
45
+ end
46
+
47
+ if stylesheet.is_a? Hash
48
+ stylesheet.each do |key, val|
49
+ args = [val].flatten
50
+ args = args.map{|s| s.gsub("stylesheets/", AppConfig.stylesheet_path)} if AppConfig.stylesheet_path
51
+ if defined?(Merb)
52
+ args << options.merge(:bundle => key.to_sym)
53
+ html << css_include_tag(*args)
54
+ elsif defined?(Rails)
55
+ args << options.merge(:cache => key.to_s)
56
+ html << stylesheet_link_tag(*args)
57
+ end
58
+ end
59
+ else
60
+ args = [stylesheet].flatten
61
+ args = args.map{|s| s.gsub("stylesheets/", AppConfig.stylesheet_path)} if AppConfig.stylesheet_path
62
+ args << options
63
+ html << stylesheet_link_tag(*args)
64
+ end
65
+ html << "\n"
66
+ end
67
+ end
68
+ return html
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,47 @@
1
+ require 'application_config/config_builder'
2
+ require 'application_config/view_helpers'
3
+
4
+ # make sure we're running inside Merb
5
+ if defined?(Merb::Plugins)
6
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
7
+ Merb::Plugins.config[:app_config] = {
8
+ :auto_reload => false,
9
+ :view_helpers => true,
10
+ :paths => [
11
+ "#{Merb.root}/config/app_config.yml",
12
+ "#{Merb.root}/config/app_config/settings.yml",
13
+ "#{Merb.root}/config/app_config/#{Merb.env}.yml",
14
+ "#{Merb.root}/config/environments/#{Merb.env}.yml",
15
+ "#{Merb.root}/config/assets.yml",
16
+ "#{Merb.root}/config/javascripts.yml",
17
+ "#{Merb.root}/config/stylesheets.yml"
18
+ ]
19
+ }
20
+
21
+ Merb::BootLoader.before_app_loads do
22
+ if defined?(::AppConfig)
23
+ AppConfig.reload!
24
+ else
25
+ ::AppConfig = ApplicationConfig::ConfigBuilder.load_files(
26
+ :paths => Merb::Plugins.config[:app_config][:paths].to_a,
27
+ :expand_keys => [:javascripts, :stylesheets],
28
+ :root_path => Merb.root
29
+ )
30
+ end
31
+
32
+ if Merb::Plugins.config[:app_config][:view_helpers]
33
+ Merb::Controller.send(:include, ApplicationConfig::ViewHelpers)
34
+ end
35
+ end
36
+
37
+ Merb::BootLoader.after_app_loads do
38
+ if Merb::Plugins.config[:app_config][:auto_reload]
39
+ Merb.logger.info "[AppConfig] Auto reloading AppConfig on *every request*."
40
+ Merb.logger.info "[AppConfig] Set via Merb::Plugins.config[:app_config][:auto_reload]"
41
+
42
+ Merb::Controller.before Proc.new{ AppConfig.reload! }
43
+ end
44
+ end
45
+
46
+ Merb::Plugins.add_rakefiles "merbtasks"
47
+ end
data/lib/merbtasks.rb ADDED
@@ -0,0 +1,17 @@
1
+ namespace :app_config do
2
+ desc "Create a blank config/app_config.yml file"
3
+ task :init do
4
+ puts "Setting up AppConfig files..."
5
+ `mkdir -p config/app_config`
6
+
7
+ ["config/app_config.yml",
8
+ "config/app_config/development.yml",
9
+ "config/app_config/production.yml"
10
+ ].each do |path|
11
+ `touch #{path}`
12
+ puts "Created: #{path}"
13
+ end
14
+ puts "Complete!"
15
+ puts "Add key/value pairs to your yaml file,\nthen access them in your Merb project via AppConfig.[key]"
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb_app_config
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - Jacques Crocker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-23 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: merb-assets
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "1.0"
34
+ version:
35
+ description: Merb plugin that provides easy to use Application Configurations via YAML
36
+ email: merbjedi@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ - LICENSE
44
+ files:
45
+ - LICENSE
46
+ - README
47
+ - Rakefile
48
+ - lib/application_config
49
+ - lib/application_config/config_builder.rb
50
+ - lib/application_config/view_helpers.rb
51
+ - lib/merb_app_config.rb
52
+ - lib/merbtasks.rb
53
+ has_rdoc: true
54
+ homepage: http://www.merbjedi.com/
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project: merb
75
+ rubygems_version: 1.3.1
76
+ signing_key:
77
+ specification_version: 2
78
+ summary: Merb plugin that provides easy to use Application Configurations via YAML
79
+ test_files: []
80
+