app 0.2.2

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/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
+