mguymon-figaro 0.7.0.1

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,6 @@
1
+ /.bundle
2
+ /Gemfile.lock
3
+ /coverage
4
+ /gemfiles/*.gemfile.lock
5
+ /pkg
6
+ /tmp
@@ -0,0 +1,19 @@
1
+ before_script:
2
+ - unset RAILS_ENV
3
+ - unset RACK_ENV
4
+ branches: master
5
+ gemfile:
6
+ - gemfiles/rails30.gemfile
7
+ - gemfiles/rails31.gemfile
8
+ - gemfiles/rails32.gemfile
9
+ - gemfiles/rails40.gemfile
10
+ language: ruby
11
+ matrix:
12
+ include:
13
+ - gemfile: Gemfile
14
+ rvm: 2.0.0
15
+ env: COVERAGE=1
16
+ rvm:
17
+ - 1.9.3
18
+ - 2.0.0
19
+ script: rspec
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rails", ">= 3.0.3", "< 5"
6
+
7
+ group :test do
8
+ gem "aruba", "~> 0.5"
9
+ gem "coveralls", "~> 0.7", require: false
10
+ gem "rake", "~> 10.1"
11
+ gem "rspec", "~> 2.14"
12
+ gem "sqlite3", "~> 1.3"
13
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Steve Richert
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,139 @@
1
+ # Figaro
2
+ [![Gem Version](https://badge.fury.io/rb/figaro.png)](http://badge.fury.io/rb/figaro)
3
+ [![Build Status](https://travis-ci.org/laserlemon/figaro.png?branch=master)](https://travis-ci.org/laserlemon/figaro)
4
+ [![Code Climate](https://codeclimate.com/github/laserlemon/figaro.png)](https://codeclimate.com/github/laserlemon/figaro)
5
+ [![Coverage Status](https://coveralls.io/repos/laserlemon/figaro/badge.png?branch=master)](https://coveralls.io/r/laserlemon/figaro)
6
+ [![Dependency Status](https://gemnasium.com/laserlemon/figaro.png)](https://gemnasium.com/laserlemon/figaro)
7
+
8
+ Simple Rails app configuration
9
+
10
+ ## What is this for?
11
+
12
+ Figaro is for configuring Rails (3 and 4) apps, especially open source Rails apps.
13
+
14
+ Open sourcing a Rails app can be a little tricky when it comes to sensitive configuration information like [Pusher](http://pusher.com/) or [Stripe](https://stripe.com/) credentials. You don't want to check private credentials into the repo but what other choice is there?
15
+
16
+ Figaro provides a clean and simple way to configure your app and keep the private stuff… private.
17
+
18
+ ## How does it work?
19
+
20
+ There are a few similar solutions out there, and a lot of homegrown attempts. Most namespace your configuration under a `Config` (or similar) namespace. That's fine, but there's already a place to describe the application environment… `ENV`!
21
+
22
+ `ENV` is a collection of simple string key/value pairs and it works just great for application configuration.
23
+
24
+ As an added bonus, this is exactly how apps on [Heroku](http://www.heroku.com/) are configured. So if you configure your Rails app using `ENV`, you're already set to deploy to Heroku.
25
+
26
+ ## Give me an example.
27
+
28
+ Okay. Add Figaro to your Gemfile and run the `bundle` command to install it:
29
+
30
+ ```ruby
31
+ gem "figaro"
32
+ ```
33
+
34
+ Next up, use the generator provided by Figaro:
35
+
36
+ ```bash
37
+ rails generate figaro:install
38
+ ```
39
+
40
+ This creates a commented `config/application.yml` file and ignores it in your `.gitignore`. Add your own configuration to this file and you're done!
41
+
42
+ Your configuration will be available as key/value pairs in `ENV`. For example, here's `config/initializers/pusher.rb`:
43
+
44
+ ```ruby
45
+ Pusher.app_id = ENV["PUSHER_APP_ID"]
46
+ Pusher.key = ENV["PUSHER_KEY"]
47
+ Pusher.secret = ENV["PUSHER_SECRET"]
48
+ ```
49
+
50
+ In addition, you can access these same configuration values through Figaro itself:
51
+
52
+ ```ruby
53
+ Pusher.app_id = Figaro.env.pusher_app_id
54
+ Pusher.key = Figaro.env.pusher_key
55
+ Pusher.secret = Figaro.env.pusher_secret
56
+ ```
57
+
58
+ But wait… I thought configuration via constant was bad! Well, this is different. Rather than storing a _copy_ of `ENV` internally, `Figaro.env` passes directly through to `ENV`, making it just like using `ENV` itself. So why two approaches? Having your configurations available via method calls makes it easy to stub them out in tests. Either way is fine. The choice is yours!
59
+
60
+ If your app requires Rails-environment-specific configuration, you can also namespace your configuration under a key for `Rails.env`.
61
+
62
+ ```yaml
63
+ HELLO: world
64
+ development:
65
+ HELLO: developers
66
+ production:
67
+ HELLO: users
68
+ ```
69
+
70
+
71
+ In this case, `ENV["HELLO"]` will produce `"developers"` in development, `"users"` in production and `"world"` otherwise.
72
+
73
+ **NOTE:** Figaro uses Rails' standard hooks to initialize. Unfortunately, this hook apparently occurs after `database.yml` is read. Because of this issue, environment variables created in `application.yml` don't work inside `database.yml`.
74
+
75
+
76
+ ## How does it work with Heroku?
77
+
78
+ Heroku's beautifully simple application configuration was the [inspiration](http://laserlemon.com/blog/2011/03/08/heroku-friendly-application-configuration/) for Figaro.
79
+
80
+ Typically, to configure your application `ENV` on Heroku, you would do the following from the command line using the `heroku` gem:
81
+
82
+ ```bash
83
+ heroku config:add PUSHER_APP_ID=8926
84
+ heroku config:add PUSHER_KEY=0463644d89a340ff1132
85
+ heroku config:add PUSHER_SECRET=0eadfd9847769f94367b
86
+ heroku config:add STRIPE_API_KEY=jHXKPPE0dUW84xJNYzn6CdWM2JfrCbPE
87
+ heroku config:add STRIPE_PUBLIC_KEY=pk_HHtUKJwlN7USCT6nE5jiXgoduiNl3
88
+ ```
89
+
90
+ But Figaro provides a rake task to do just that! Just run:
91
+
92
+ ```bash
93
+ rake figaro:heroku
94
+ ```
95
+
96
+ Optionally, you can pass in the name of the Heroku app:
97
+
98
+ ```bash
99
+ rake figaro:heroku[my-awesome-app]
100
+ ```
101
+
102
+ Additionally, if `RAILS_ENV` is configured on your Heroku server, Figaro will use that environment automatically in determining your proper configuration.
103
+
104
+ ## What if I'm not using Heroku?
105
+
106
+ No problem. Just add `config/application.yml` to your production app on the server.
107
+
108
+ ## This sucks. How can I make it better?
109
+
110
+ 1. Fork it.
111
+ 2. Make it better.
112
+ 3. Send me a pull request.
113
+
114
+ ## Does Figaro have a mascot?
115
+
116
+ Yes.
117
+
118
+ [![Figaro](http://images2.wikia.nocookie.net/__cb20100628192722/disney/images/5/53/Pinocchio-pinocchio-4947890-960-720.jpg "Figaro's mascot: Figaro")](http://en.wikipedia.org/wiki/Figaro_(Disney\))
119
+
120
+ ## Thank you!
121
+
122
+ Figaro is made possible by the continued contributions and insights from kind-hearted developers everywhere. Just to name a few:
123
+
124
+ * [@ersatzryan](https://github.com/ersatzryan)
125
+ * [@robertjwhitney](https://github.com/robertjwhitney)
126
+ * [@maxwell](https://github.com/maxwell)
127
+ * [@GuilhermeSimoes](https://github.com/GuilhermeSimoes)
128
+ * [@mikeycgto](https://github.com/mikeycgto)
129
+ * [@subosito](https://github.com/subosito)
130
+ * [@srushti](https://github.com/srushti)
131
+ * [@ptyagi16](https://github.com/ptyagi16)
132
+ * [@jspradlin](https://github.com/jspradlin)
133
+ * [@hadifarnoud](https://github.com/hadifarnoud)
134
+ * [@eloyesp](https://github.com/eloyesp)
135
+ * [@etuya-ix](https://github.com/etuya-ix)
136
+ * [@MarkDBlackwell](https://github.com/MarkDBlackwell)
137
+ * [@HALapeno](https://github.com/HALapeno)
138
+ * [@severin](https://github.com/severin)
139
+ * [@sethvargo](https://github.com/sethvargo)
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = "mguymon-figaro"
5
+ gem.version = "0.7.0.1"
6
+
7
+ gem.author = "Steve Richert"
8
+ gem.email = "steve.richert@gmail.com"
9
+ gem.summary = "Simple Rails app configuration"
10
+ gem.description = "Simple, Heroku-friendly Rails app configuration using ENV and a single YAML file"
11
+ gem.homepage = "https://github.com/laserlemon/figaro"
12
+ gem.license = "MIT"
13
+
14
+ gem.add_dependency "bundler", "~> 1.0"
15
+ gem.add_dependency "rails", ">= 3", "< 5"
16
+
17
+ gem.files = `git ls-files`.split($\)
18
+ gem.test_files = gem.files.grep(/^(features|spec)/)
19
+ gem.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "rails", "~> 3.0.2"
6
+
7
+ group :test do
8
+ gem "aruba", "~> 0.5"
9
+ gem "rspec", "~> 2.14"
10
+ gem "sqlite3", "~> 1.3"
11
+ end
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "rails", "~> 3.1.0"
6
+
7
+ group :test do
8
+ gem "aruba", "~> 0.5"
9
+ gem "rspec", "~> 2.14"
10
+ gem "sqlite3", "~> 1.3"
11
+ end
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "rails", "~> 3.2.0"
6
+
7
+ group :test do
8
+ gem "aruba", "~> 0.5"
9
+ gem "rspec", "~> 2.14"
10
+ gem "sqlite3", "~> 1.3"
11
+ end
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "rails", "~> 4.0.0"
6
+
7
+ group :test do
8
+ gem "aruba", "~> 0.5"
9
+ gem "rspec", "~> 2.14"
10
+ gem "sqlite3", "~> 1.3"
11
+ end
@@ -0,0 +1,26 @@
1
+ require "figaro/application"
2
+ require "figaro/env"
3
+ require "figaro/rails"
4
+ require "figaro/tasks"
5
+
6
+ module Figaro
7
+ extend self
8
+
9
+ attr_writer :backend, :application
10
+
11
+ def env
12
+ Figaro::ENV
13
+ end
14
+
15
+ def backend
16
+ @backend ||= Figaro::Rails::Application
17
+ end
18
+
19
+ def application
20
+ @application ||= backend.new
21
+ end
22
+
23
+ def load
24
+ application.load
25
+ end
26
+ end
@@ -0,0 +1,77 @@
1
+ require "erb"
2
+ require "yaml"
3
+
4
+ require "figaro/error"
5
+
6
+ module Figaro
7
+ class Application
8
+ FIGARO_ENV_PREFIX = "FIGARO_"
9
+
10
+ attr_writer :path, :environment
11
+
12
+ def initialize(options = {})
13
+ @path = options[:path]
14
+ @environment = options[:environment]
15
+ end
16
+
17
+ def path
18
+ (@path || default_path).to_s
19
+ end
20
+
21
+ def environment
22
+ (@environment || default_environment).to_s
23
+ end
24
+
25
+ def configuration
26
+ global_configuration.merge(environment_configuration)
27
+ end
28
+
29
+ def load
30
+ configuration.each do |key, value|
31
+ set(key, value) unless skip?(key)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def default_path
38
+ raise NotImplementedError
39
+ end
40
+
41
+ def default_environment
42
+ raise NotImplementedError
43
+ end
44
+
45
+ def raw_configuration
46
+ (@parsed ||= Hash.new { |hash, path| hash[path] = parse(path) })[path]
47
+ end
48
+
49
+ def parse(path)
50
+ File.exist?(path) && YAML.load(ERB.new(File.read(path)).result) || {}
51
+ end
52
+
53
+ def global_configuration
54
+ raw_configuration.reject { |_, value| value.is_a?(Hash) }
55
+ end
56
+
57
+ def environment_configuration
58
+ raw_configuration.fetch(environment) { {} }
59
+ end
60
+
61
+ def set(key, value)
62
+ non_string_configuration!(key) unless key.is_a?(String)
63
+ non_string_configuration!(value) unless value.is_a?(String)
64
+
65
+ ::ENV[key.to_s] = value.to_s
66
+ ::ENV[FIGARO_ENV_PREFIX + key.to_s] = value.to_s
67
+ end
68
+
69
+ def skip?(key)
70
+ ::ENV.key?(key.to_s) && !::ENV.key?(FIGARO_ENV_PREFIX + key.to_s)
71
+ end
72
+
73
+ def non_string_configuration!(value)
74
+ warn "WARNING: Use strings for Figaro configuration. #{value.inspect} was converted to #{value.to_s.inspect}."
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,37 @@
1
+ module Figaro
2
+ module ENV
3
+ extend self
4
+
5
+ def respond_to?(method, *)
6
+ key, punctuation = extract_key_from_method(method)
7
+
8
+ case punctuation
9
+ when "!" then ::ENV.keys.any? { |k| k.upcase == key } || super
10
+ when "?", nil then true
11
+ else super
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def method_missing(method, *)
18
+ key, punctuation = extract_key_from_method(method)
19
+ _, value = ::ENV.detect { |k, _| k.upcase == key }
20
+
21
+ case punctuation
22
+ when "!" then value || missing_key!(key)
23
+ when "?" then !!value
24
+ when nil then value
25
+ else super
26
+ end
27
+ end
28
+
29
+ def extract_key_from_method(method)
30
+ method.to_s.upcase.match(/^(.+?)([!?=])?$/).captures
31
+ end
32
+
33
+ def missing_key!(key)
34
+ raise MissingKey.new("Missing required Figaro configuration key #{key.inspect}.")
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ module Figaro
2
+ class Error < StandardError; end
3
+
4
+ class RailsNotInitialized < Error; end
5
+ class MissingKey < Error; end
6
+ end
@@ -0,0 +1,9 @@
1
+ begin
2
+ require "rails"
3
+ rescue LoadError
4
+ end
5
+
6
+ if defined?(::Rails)
7
+ require "figaro/rails/application"
8
+ require "figaro/rails/railtie"
9
+ end