appconfig 0.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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,12 @@
1
+ .DS_Store
2
+ **/.DS_Store
3
+ pkg
4
+ doc
5
+ rdoc
6
+ coverage
7
+ *.swp
8
+ *.tmproj
9
+ tmtags
10
+ *~
11
+ \#*
12
+ .\#*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [name of plugin creator]
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.
@@ -0,0 +1,93 @@
1
+ AppConfig
2
+ =========
3
+
4
+
5
+ ______ ____ ___
6
+ /\ _ \ /\ _`\ /'___\ __
7
+ \ \ \L\ \ _____ _____\ \ \/\_\ ___ ___ /\ \__//\_\ __
8
+ \ \ __ \/\ '__`\/\ '__`\ \ \/_/_ / __`\/' _ `\ \ ,__\/\ \ /'_ `\
9
+ \ \ \/\ \ \ \L\ \ \ \L\ \ \ \L\ \\ \L\ \\ \/\ \ \ \_/\ \ \/\ \L\ \
10
+ \ \_\ \_\ \ ,__/\ \ ,__/\ \____/ \____/ \_\ \_\ \_\ \ \_\ \____ \
11
+ \/_/\/_/\ \ \/ \ \ \/ \/___/ \/___/ \/_/\/_/\/_/ \/_/\/___L\ \
12
+ \ \_\ \ \_\ /\____/
13
+ \/_/ \/_/ \_/__/
14
+
15
+
16
+ *AppConfig* does pretty much what [all](http://github.com/cjbottaro/app_config) [the](http://github.com/stephencelis/app) [other](http://github.com/merbjedi/app_config) [great](http://github.com/oshuma/app_config) application configuration plugins do, but requires even less configuration (I know, how meta). It reads your config from YAML files, supports nested options, and automatically reloads your changes in `development` mode.
17
+
18
+ It also has a README with cool ASCII art in it.
19
+
20
+ Install
21
+ =======
22
+
23
+ Rails 2.x
24
+ -------
25
+
26
+ Put this in your `environment.rb`:
27
+
28
+ config.gem 'appconfig'
29
+
30
+ That's it.
31
+
32
+ Rails 3
33
+ -------
34
+
35
+ Add this to your `Gemfile`:
36
+
37
+ gem 'appconfig', :require => 'app_config'
38
+
39
+ That's it.
40
+
41
+ Usage
42
+ =======
43
+
44
+ By default AppConfig will try to read config options from `config/appconfig.defaults.yml` and `*.appconfig.yml`.
45
+
46
+ # sample appconfig.defaults.yml
47
+
48
+ admins:
49
+
50
+ tisho:
51
+ full_name: Tisho Georgiev
52
+ email: tihomir.georgiev@gmail.com
53
+
54
+ josh:
55
+ full_name: Joshua Krall
56
+ email: josh@transfs.com
57
+
58
+ Inside your Rails app, you can access your configuration options using the `AppConfig` object.
59
+
60
+ @admin_name = AppConfig.admins.tisho.full_name
61
+
62
+ Since *AppConfig's* storage mechanism is something like the lovechild of `HashWithIndifferentAccess` and `OpenStruct`, you can access your configuration in a bunch of different ways.
63
+
64
+ AppConfig.admins.tisho
65
+ AppConfig[:admins].tisho
66
+ AppConfig[:admins][:tisho]
67
+ AppConfig['admins']['tisho']
68
+ AppConfig['admins'][:tisho]
69
+
70
+ You get the idea.
71
+
72
+ If you're prefer the `OpenStruct` methodized syntax for accessing configuration options, you can optionally provide a fallback value for an option that may not exist.
73
+
74
+ AppConfig.option_that_doesnt_exist('fallback') #=> 'fallback'
75
+
76
+ Reloading
77
+ -------
78
+
79
+ When running your app in your `development` environment, *AppConfig* reloads on every request. It does that by using Rails's `ActionController::Dispatcher.to_prepare` hook.
80
+
81
+ If you need to reload your configuration manually, you can run:
82
+
83
+ AppConfig.reload!
84
+
85
+ Found a bug?
86
+ =======
87
+
88
+ By all means, drop us a line. Or better yet, fork the project, fix the bug and send us a pull request. We'll thank you for it.
89
+
90
+ License
91
+ =======
92
+
93
+ Copyright (c) 2010 Joshua Krall & Tisho Georgiev, released under the MIT license
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require File.dirname(__FILE__) + "/lib/app_config/version.rb"
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "appconfig"
9
+ gem.version = AppConfig::VERSION::STRING
10
+ gem.summary = %Q{Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file.}
11
+ gem.description = %Q{Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file. Supports multiple configuration files, nested configuration groups and fallback options.}
12
+ gem.email = "tihomir.georgiev@gmail.com"
13
+ gem.homepage = "http://github.com/tisho/appconfig"
14
+ gem.authors = ["Tisho Georgiev", "Joshua Krall"]
15
+ gem.add_development_dependency "rspec", ">= 1.2.9"
16
+ gem.add_development_dependency "rails", ">= 2.3"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "appconfig #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{appconfig}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tisho Georgiev", "Joshua Krall"]
12
+ s.date = %q{2010-03-25}
13
+ s.description = %q{Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file. Supports multiple configuration files, nested configuration groups and fallback options.}
14
+ s.email = %q{tihomir.georgiev@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "appconfig.gemspec",
26
+ "init.rb",
27
+ "lib/app_config.rb",
28
+ "lib/app_config/accessor_proxy.rb",
29
+ "lib/app_config/base.rb",
30
+ "lib/app_config/railtie.rb",
31
+ "lib/app_config/version.rb",
32
+ "rails/init.rb",
33
+ "spec/app_config_spec.rb",
34
+ "spec/fixtures/appconfig.defaults.yml",
35
+ "spec/fixtures/overrides.appconfig.yml",
36
+ "spec/spec.opts",
37
+ "spec/spec_helper.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/tisho/appconfig}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.6}
43
+ s.summary = %q{Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file.}
44
+ s.test_files = [
45
+ "spec/app_config_spec.rb",
46
+ "spec/spec_helper.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
55
+ s.add_development_dependency(%q<rails>, [">= 2.3"])
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
58
+ s.add_dependency(%q<rails>, [">= 2.3"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
62
+ s.add_dependency(%q<rails>, [">= 2.3"])
63
+ end
64
+ end
65
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'app_config'
@@ -0,0 +1,4 @@
1
+ require 'app_config/version'
2
+ require 'app_config/accessor_proxy'
3
+ require 'app_config/base'
4
+ require 'app_config/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
@@ -0,0 +1,36 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/hash'
3
+
4
+ module AppConfig
5
+ # Support nested hash accessors, so you could do AppConfig.stylesheet_expansions.standard
6
+ class AccessorProxy < HashWithIndifferentAccess
7
+ def method_missing(method, *args, &block)
8
+ if self[method]
9
+ return AccessorProxy.new(self[method]) if self[method].is_a?(Hash)
10
+ self[method]
11
+ else
12
+ begin
13
+ super
14
+ rescue NoMethodError => e
15
+ # return default "value if nil" if one is provided
16
+ if args.size == 1
17
+ args.first
18
+ else
19
+ raise e
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def convert_value(value)
26
+ case value
27
+ when Hash
28
+ AccessorProxy.new(value.with_indifferent_access)
29
+ when Array
30
+ value.collect { |e| e.is_a?(Hash) ? AccessorProxy.new(e.with_indifferent_access) : e }
31
+ else
32
+ value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+
4
+ module AppConfig
5
+ mattr_accessor :config_files_path, :default_config_file_path
6
+
7
+ class << self
8
+ def reload!
9
+ set_default_paths if config_files_path.nil?
10
+ @@config = AccessorProxy.new(load_config_file(default_config_file_path))
11
+
12
+ config_files.each do |config_file|
13
+ @@config.merge!(load_config_file(config_file))
14
+ end
15
+ end
16
+
17
+ def [](key)
18
+ return @@config[key]
19
+ end
20
+
21
+ def config_files
22
+ Dir[config_files_path.join('*appconfig.yml').to_s]
23
+ end
24
+
25
+ def get(key)
26
+ return AppConfig[key]
27
+ end
28
+
29
+ def load_config_file(file_path)
30
+ YAML::load(ERB.new((IO.read(file_path))).result).symbolize_keys
31
+ rescue Errno::ENOENT
32
+ {}
33
+ end
34
+
35
+ def set_default_paths
36
+ self.config_files_path = ::Rails.root.join('config')
37
+ self.default_config_file_path = self.config_files_path.join('appconfig.defaults.yml')
38
+ end
39
+
40
+ def method_missing(method, *args, &block)
41
+ @@config.send method, *args, &block
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,10 @@
1
+ module AppConfig
2
+ class Railtie < Rails::Railtie
3
+ railtie_name :app_config
4
+
5
+ initializer :load_app_config, :before => :load_application_initializers do |app|
6
+ end
7
+
8
+ config.to_prepare { ::AppConfig.reload! }
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module AppConfig
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # I know using rails/init.rb is deprecated, but it seems to be the only way to
2
+ # get Rails 2.x to actually treat the gem as a plugin and not a lazy-loadable library.
3
+ # The checks are there just in case Rails 3 ever decides to pick it up.
4
+
5
+ require 'app_config'
6
+ if defined?(Rails) && Rails::VERSION::MAJOR == 2
7
+ ::AppConfig.reload!
8
+ ::ActionController::Dispatcher.to_prepare { ::AppConfig.reload! }
9
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppConfig do
4
+ before(:all) do
5
+ silence_warnings do
6
+ AppConfig.config_files_path = Pathname.new(File.join(File.dirname(__FILE__), 'fixtures'))
7
+ AppConfig.default_config_file_path = AppConfig.config_files_path.join('appconfig.defaults.yml')
8
+ end
9
+ end
10
+
11
+ before(:each) do
12
+ AppConfig.reload!
13
+ end
14
+
15
+ it 'should always load default config file first' do
16
+ # assume there are no other config files
17
+ AppConfig.stub!(:config_files).and_return([])
18
+ AppConfig.reload!
19
+
20
+ {
21
+ %{AppConfig.domain} => 'unknown.com',
22
+ %{AppConfig.admin.name} => 'John Smith',
23
+ %{AppConfig.admin.email} => 'john.smith@unknown.com'
24
+ }.each_pair do |property, expected_value|
25
+ eval(property).should == expected_value
26
+ end
27
+ end
28
+
29
+ it 'should override the default config with whatever is in *.appconfig.yml' do
30
+ AppConfig.domain.should == 'stillunknown.com'
31
+ end
32
+
33
+ context 'when accessing first-level config keys' do
34
+ it 'should allow struct-like access to config keys' do
35
+ AppConfig.search_engines.should == %w{google.com yahoo.com bing.com}
36
+ end
37
+
38
+ it 'should allow hash-like access to config keys' do
39
+ AppConfig[:search_engines].should == %w{google.com yahoo.com bing.com}
40
+ AppConfig['search_engines'].should == %w{google.com yahoo.com bing.com}
41
+ end
42
+ end
43
+
44
+ context 'when accessing deeply nested config keys' do
45
+ it 'should allow struct-like access to config keys' do
46
+ AppConfig.admin.name.should == 'John Smith'
47
+ end
48
+
49
+ it 'should allow hash-like access to config keys' do
50
+ AppConfig[:admin][:name].should == 'John Smith'
51
+ AppConfig['admin']['name'].should == 'John Smith'
52
+ end
53
+
54
+ it 'should allow you to mix hash-like and struct-like syntax when accessing deeply nested config keys' do
55
+ AppConfig[:admin].name.should == 'John Smith'
56
+ AppConfig['admin'].name.should == 'John Smith'
57
+ AppConfig.admin[:name].should == 'John Smith'
58
+ AppConfig.admin['name'].should == 'John Smith'
59
+ end
60
+ end
61
+
62
+ it 'should behave like a hash' do
63
+ AppConfig.keys.should include(*%w{admin search_engines domain})
64
+ end
65
+
66
+ it 'should allow you to pass an optional "value if key not found" parameter when using struct-like syntax' do
67
+ AppConfig.nonexistant_key('fallback').should == 'fallback'
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ admin:
2
+ name: John Smith
3
+ email: john.smith@unknown.com
4
+
5
+ domain: unknown.com
6
+
7
+ search_engines:
8
+ - google.com
9
+ - yahoo.com
10
+ - bing.com
@@ -0,0 +1 @@
1
+ domain: stillunknown.com
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'active_support'
5
+ require 'active_support/core_ext/kernel/reporting'
6
+
7
+ require 'app_config'
8
+ require 'spec'
9
+ require 'spec/autorun'
10
+
11
+ Spec::Runner.configure do |config|
12
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appconfig
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Tisho Georgiev
13
+ - Joshua Krall
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-03-25 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 2
31
+ - 9
32
+ version: 1.2.9
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rails
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 2
44
+ - 3
45
+ version: "2.3"
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file. Supports multiple configuration files, nested configuration groups and fallback options.
49
+ email: tihomir.georgiev@gmail.com
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files:
55
+ - LICENSE
56
+ - README.md
57
+ files:
58
+ - .document
59
+ - .gitignore
60
+ - LICENSE
61
+ - README.md
62
+ - Rakefile
63
+ - appconfig.gemspec
64
+ - init.rb
65
+ - lib/app_config.rb
66
+ - lib/app_config/accessor_proxy.rb
67
+ - lib/app_config/base.rb
68
+ - lib/app_config/railtie.rb
69
+ - lib/app_config/version.rb
70
+ - rails/init.rb
71
+ - spec/app_config_spec.rb
72
+ - spec/fixtures/appconfig.defaults.yml
73
+ - spec/fixtures/overrides.appconfig.yml
74
+ - spec/spec.opts
75
+ - spec/spec_helper.rb
76
+ has_rdoc: true
77
+ homepage: http://github.com/tisho/appconfig
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --charset=UTF-8
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ requirements: []
100
+
101
+ rubyforge_project:
102
+ rubygems_version: 1.3.6
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Provides an OpenStruct/Hash-like syntax for accessing your app's configuration options, loaded from a YAML file.
106
+ test_files:
107
+ - spec/app_config_spec.rb
108
+ - spec/spec_helper.rb