merb_app_config 1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+