mguymon-figaro 0.7.0.1

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