app 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc ADDED
@@ -0,0 +1,46 @@
1
+ === 0.2.2 / 2009-04-17
2
+
3
+ * 2 minor enhancements
4
+
5
+ * Remember to better ensure immutability.
6
+ * Include "README.rdoc" in gemspec.
7
+
8
+
9
+ === 0.2.1 / 2009-04-17
10
+
11
+ * 1 minor enhancement
12
+
13
+ * Configuration files no longer require scoping to environments.
14
+
15
+
16
+ === 0.2.0 / 2009-04-17
17
+
18
+ * 2 major enhancements
19
+
20
+ * Option to modular configuration files (from "config/app/**/*.yml").
21
+ * App.name is now App.to_s (overriding the name is cool, but dangerous).
22
+
23
+ * 1 minor enhancement
24
+
25
+ * Removed superfluous "init" and "uninstall" files (handle load errors more
26
+ gracefully in "app", and let "script/destroy" do its thing).
27
+
28
+ === 0.1.2 / 2009-04-02
29
+
30
+ * 1 minor enhancement
31
+
32
+ * Change README.txt to README.rdoc in gem specification.
33
+
34
+
35
+ === 0.1.1 / 2009-04-02
36
+
37
+ * 1 major enhancement
38
+
39
+ * Gemified!
40
+
41
+
42
+ === 0.1.0 / 2009-04-02
43
+
44
+ * 1 major enhancement
45
+
46
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,12 @@
1
+ History.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ generators/app_config/app_config_generator.rb
6
+ generators/app_config/templates/app.yml
7
+ install.rb
8
+ lib/app.rb
9
+ test/app_test.rb
10
+ test/fixtures/app/authenticate/basic/config.yml
11
+ test/fixtures/app/authenticate.yml
12
+ test/fixtures/app.yml
data/README.rdoc ADDED
@@ -0,0 +1,136 @@
1
+ = App
2
+
3
+ http://github.com/stephencelis/app
4
+
5
+
6
+ == DESCRIPTION
7
+
8
+ Move the config out of your app, and into App.
9
+
10
+ Sure, it's been done before, and others will do it again, but this is my way,
11
+ and I like it.
12
+
13
+
14
+ == FEATURES/PROBLEMS
15
+
16
+ * Easy, environmentally-friendly configuration access.
17
+
18
+
19
+ For mutability, try acts_as_singleton or KVC:
20
+
21
+ * http://github.com/stephencelis/acts_as_singleton
22
+ * http://github.com/stephencelis/kvc
23
+
24
+
25
+ == SYNOPSIS
26
+
27
+ App looks for and loads configuration from "config/app.yml", providing a
28
+ namespaced API for access.
29
+
30
+ App.config # => {"apis"=>{"flickr"=>{ ... }}
31
+
32
+
33
+ Sugar is always sweeter:
34
+
35
+ App.config("apis", "flickr") # => App.config["apis"]["flickr"]
36
+
37
+
38
+ Who doesn't like sugar?
39
+
40
+ App["apis", "flickr"]
41
+
42
+
43
+ Sugar, sugar, sugar.
44
+
45
+ App.apis("flickr")
46
+
47
+
48
+ Let's not overdo it, though. <tt>App.apis.flickr</tt> just doesn't look right.
49
+
50
+
51
+ == REQUIREMENTS
52
+
53
+ * Rails 2.3.2 or greater.
54
+
55
+
56
+ == INSTALL
57
+
58
+ === With a template:
59
+
60
+ In existing projects:
61
+
62
+ % rake rails:template LOCATION=http://gist.github.com/97629.txt
63
+
64
+
65
+ For new projects:
66
+
67
+ % rails newapp -m http://gist.github.com/97629.txt
68
+
69
+
70
+ === Or as a gem:
71
+
72
+ Configure:
73
+
74
+ # config/environment.rb
75
+ config.gem "stephencelis-app", :lib => "app",
76
+ :source => "http://gems.github.com",
77
+ :version => ">= 0.2.2"
78
+
79
+ And install:
80
+
81
+ % sudo rake gems:install
82
+
83
+
84
+ === Or as a plugin:
85
+
86
+ Install:
87
+
88
+ % script/plugin install git://github.com/stephencelis/app.git
89
+
90
+
91
+ Or submodule:
92
+
93
+ % git submodule add git://github.com/stephencelis/app.git vendor/plugins/app
94
+
95
+
96
+ === Finally, generate:
97
+
98
+ % script/generate app_config
99
+
100
+
101
+ If your "app.yml" gets out of hand, modularize, like in this heavy-handed
102
+ example:
103
+
104
+ % script/generate app_config apis/twitter
105
+ create config/app/apis
106
+ create config/app/apis/twitter.yml # Configure me!
107
+
108
+
109
+ Namespaces avoid collisions:
110
+
111
+ App::Apis::Twitter.username
112
+
113
+
114
+ == LICENSE
115
+
116
+ (The MIT License)
117
+
118
+ (c) 2009-* Stephen Celis, stephen@stephencelis.com.
119
+
120
+ Permission is hereby granted, free of charge, to any person obtaining a copy
121
+ of this software and associated documentation files (the "Software"), to deal
122
+ in the Software without restriction, including without limitation the rights
123
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
124
+ copies of the Software, and to permit persons to whom the Software is
125
+ furnished to do so, subject to the following conditions:
126
+
127
+ The above copyright notice and this permission notice shall be included in all
128
+ copies or substantial portions of the Software.
129
+
130
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
131
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
132
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
133
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
134
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
135
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
136
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the app plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the app plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'App'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README.rdoc')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1,32 @@
1
+ class AppConfigGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ if ARGV.empty?
5
+ if File.exist? Rails.root.join("config", "app.yml")
6
+ show_banner
7
+ else
8
+ m.file "app.yml", "config/app.yml"
9
+ end
10
+ else
11
+ ARGV.each do |arg|
12
+ path = "config/app/#{arg.underscore}"
13
+ m.directory File.dirname(path)
14
+ m.file "app.yml", "#{path}.yml"
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def show_banner
23
+ puts "App: you already have an app.yml!"
24
+ puts
25
+ puts " Remember to pass arguments to generate new configurations:"
26
+ puts " script/generate app_config apis/twitter"
27
+ puts
28
+ puts " Generates:"
29
+ puts " config/app/apis"
30
+ puts " config/app/apis/twitter.yml"
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ # An app config, provided by App: http://github.com/stephencelis/app
2
+ ---
3
+ development: &development
4
+ loaded_at: <%= Time.zone.now.iso8601 %>
5
+ apis:
6
+ braintree:
7
+ :login: testapi
8
+ :password: password1
9
+
10
+ test:
11
+ <<: *development
12
+
13
+ production:
14
+ loaded_at: <%= Time.zone.now.iso8601 %>
15
+ apis:
16
+ braintree:
17
+ :login: testapi
18
+ :password: password1
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ $stdout.puts 'Run `script/generate app_config` to generate "config/app.yml".'
data/lib/app.rb ADDED
@@ -0,0 +1,73 @@
1
+ # App is your app.
2
+ #
3
+ # What would your app be without it? Still an app, but without App.
4
+ module App
5
+ VERSION = "0.2.2"
6
+
7
+ @@config = {} # Initialize.
8
+ class << self
9
+ # Returns the application configuration hash, as defined in
10
+ # "config/app.yml".
11
+ #
12
+ # Follows args through the hash tree. E.g.:
13
+ #
14
+ # App.config("apis", "flickr") # => config_hash["apis"]["flickr"]
15
+ #
16
+ # <tt>App.config</tt> is aliased to <tt>App.[]</tt>, so shorten things up:
17
+ #
18
+ # App["apis", "flickr"]
19
+ #
20
+ # Or rely on +method_missing+ to make it even shorter (and sweeter):
21
+ #
22
+ # App.apis("flickr")
23
+ def config(*args)
24
+ @@config if args.empty?
25
+ args.inject(@@config) { |config, arg| config[arg] }
26
+ end
27
+ alias [] config
28
+
29
+ def inspect
30
+ "#<#{name}: #{config.inspect}>"
31
+ end
32
+
33
+ private
34
+
35
+ def method_missing(method, *args)
36
+ self[method.to_s, *args] || self[method, *args]
37
+ end
38
+ end
39
+
40
+ begin
41
+ raw = File.read Rails.root.join("config", "#{name.underscore}.yml")
42
+ all = YAML.load ERB.new(raw).result
43
+ @@config = all[Rails.env] || all
44
+ @@config.freeze
45
+ rescue Errno::ENOENT => e
46
+ puts '** App: no file "config/app.yml". Run `script/generate app_config`.'
47
+ end
48
+ end
49
+
50
+ unless __FILE__ == "(eval)"
51
+ module App
52
+ class << self
53
+ # Returns the name of the web application.
54
+ def to_s
55
+ File.basename Rails.root
56
+ end
57
+ end
58
+ end
59
+
60
+ # Iterate through other App configs and namespace them.
61
+ Dir[Rails.root.join("config", "app", "**/*.yml")].sort.each do |config|
62
+ name = config.gsub(/#{Rails.root.join("config")}\/|\.yml/) {}.classify
63
+
64
+ # Recognize all parents.
65
+ line = name.split "::"
66
+ line.inject line.shift do |parentage, descendant|
67
+ eval "module #{parentage}; end"
68
+ "#{parentage}::#{descendant}"
69
+ end
70
+
71
+ eval File.read(__FILE__).sub("module App", "module #{name}")
72
+ end
73
+ end
data/test/app_test.rb ADDED
@@ -0,0 +1,64 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'active_support'
4
+ require 'active_support/test_case'
5
+ require 'mocha'
6
+ require 'erb'
7
+
8
+ # Mock!
9
+ module Rails
10
+ def self.root
11
+ self
12
+ end
13
+ def self.join(*args)
14
+ args.shift # No "config" dir, OK?
15
+ File.expand_path File.join(File.dirname(__FILE__), "fixtures", *args)
16
+ end
17
+ def self.env
18
+ "development"
19
+ end
20
+ end
21
+
22
+ # And load!
23
+ require 'app'
24
+
25
+ class AppTest < ActiveSupport::TestCase
26
+ test "should access many ways" do
27
+ assert_equal "Welcome!", App.config["welcome_message"]
28
+ assert_equal "Welcome!", App.config("welcome_message")
29
+ assert_equal "Welcome!", App["welcome_message"]
30
+ assert_equal "Welcome!", App.welcome_message
31
+
32
+ assert_equal "testapi", App.config["apis"]["braintree"][:login]
33
+ assert_equal "testapi", App.config("apis", "braintree", :login)
34
+ assert_equal "testapi", App["apis", "braintree", :login]
35
+ assert_equal "testapi", App.apis("braintree", :login)
36
+ end
37
+
38
+ test "should parse ERB" do
39
+ assert_instance_of Time, App.loaded_at
40
+ end
41
+
42
+ test "should accept boolean keys" do
43
+ assert !App.process_payments?
44
+ end
45
+
46
+ test "should infer App.name" do
47
+ File.stubs(:basename).returns "root"
48
+ assert_equal "root", App.to_s
49
+ end
50
+
51
+ test "should namespace configs" do
52
+ assert_instance_of Module, App::Authenticate
53
+ assert_equal "frobozz", App::Authenticate["Stephen"]
54
+ end
55
+
56
+ test "should nest multiple levels of configs" do
57
+ assert_instance_of Module, App::Authenticate::Basic::Config
58
+ assert_equal :basic, App::Authenticate::Basic::Config.authentication_type
59
+ end
60
+
61
+ test "should be frozen" do
62
+ assert_raise(TypeError) { App.config["loaded_at"] = Time.now }
63
+ end
64
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ development:
3
+ loaded_at: <%= Time.now.iso8601 %>
4
+ welcome_message: Welcome!
5
+ process_payments?: false
6
+ apis:
7
+ braintree:
8
+ :login: testapi
9
+ :password: password1
@@ -0,0 +1,4 @@
1
+ ---
2
+ development:
3
+ Stephen: frobozz
4
+ housemd: God
@@ -0,0 +1,2 @@
1
+ ---
2
+ authentication_type: :basic
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: app
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Celis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-17 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.12.0
24
+ version:
25
+ description: Move the config out of your app, and into App. Sure, it's been done before, and others will do it again, but this is my way, and I like it.
26
+ email:
27
+ - stephen@stephencelis.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.rdoc
34
+ - Manifest.txt
35
+ - README.rdoc
36
+ files:
37
+ - History.rdoc
38
+ - Manifest.txt
39
+ - README.rdoc
40
+ - Rakefile
41
+ - generators/app_config/app_config_generator.rb
42
+ - generators/app_config/templates/app.yml
43
+ - install.rb
44
+ - lib/app.rb
45
+ - test/app_test.rb
46
+ - test/fixtures/app/authenticate/basic/config.yml
47
+ - test/fixtures/app/authenticate.yml
48
+ - test/fixtures/app.yml
49
+ has_rdoc: true
50
+ homepage: http://github.com/stephencelis/app
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --main
56
+ - README.rdoc
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: app
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Move the config out of your app, and into App
78
+ test_files: []
79
+