figaro 0.7.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.gitignore +1 -1
- data/.travis.yml +23 -18
- data/CHANGELOG.md +98 -0
- data/CONTRIBUTING.md +48 -0
- data/Gemfile +4 -6
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +184 -61
- data/Rakefile +1 -12
- data/bin/figaro +5 -0
- data/doc/title.png +0 -0
- data/figaro.gemspec +9 -5
- data/gemfiles/rails30.gemfile +3 -4
- data/gemfiles/rails31.gemfile +3 -4
- data/gemfiles/rails32.gemfile +3 -4
- data/gemfiles/rails40.gemfile +3 -7
- data/gemfiles/rails41.gemfile +11 -0
- data/lib/figaro.rb +16 -29
- data/lib/figaro/application.rb +91 -0
- data/lib/figaro/cli.rb +24 -0
- data/lib/figaro/cli/heroku_set.rb +29 -0
- data/lib/figaro/cli/task.rb +27 -0
- data/lib/figaro/env.rb +36 -7
- data/lib/figaro/error.rb +12 -0
- data/lib/figaro/rails.rb +9 -0
- data/lib/figaro/rails/application.rb +21 -0
- data/lib/figaro/rails/railtie.rb +9 -0
- data/lib/figaro/{tasks.rake → rails/tasks.rake} +0 -0
- data/lib/generators/figaro/install/install_generator.rb +1 -1
- data/lib/generators/figaro/install/templates/application.yml +10 -6
- data/spec/figaro/application_spec.rb +258 -0
- data/spec/figaro/cli/heroku_set_spec.rb +62 -0
- data/spec/figaro/env_spec.rb +167 -35
- data/spec/figaro/rails/application_spec.rb +43 -0
- data/spec/figaro_spec.rb +74 -36
- data/spec/rails_spec.rb +66 -0
- data/spec/spec_helper.rb +6 -3
- data/spec/support/aruba.rb +19 -0
- data/spec/support/bin/heroku +5 -0
- data/spec/support/command_helpers.rb +17 -0
- data/spec/support/command_interceptor.rb +33 -0
- data/spec/support/random.rb +3 -0
- data/spec/support/reset.rb +13 -0
- metadata +88 -44
- data/features/rails.feature +0 -97
- data/features/step_definitions/bundler_steps.rb +0 -7
- data/features/step_definitions/common_steps.rb +0 -19
- data/features/step_definitions/rails_steps.rb +0 -12
- data/features/support/aruba.rb +0 -12
- data/features/support/env.rb +0 -8
- data/lib/figaro/railtie.rb +0 -16
- data/lib/figaro/tasks.rb +0 -28
- data/spec/figaro/tasks_spec.rb +0 -71
- data/spec/support/rake.rb +0 -11
data/Rakefile
CHANGED
@@ -1,17 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
-
require "cucumber/rake/task"
|
4
3
|
|
5
4
|
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
Cucumber::Rake::Task.new(:cucumber)
|
7
5
|
|
8
|
-
task :
|
9
|
-
|
10
|
-
if ENV["COVERAGE"]
|
11
|
-
Rake::Task[:default].enhance do
|
12
|
-
require "simplecov"
|
13
|
-
require "coveralls"
|
14
|
-
|
15
|
-
Coveralls::SimpleCov::Formatter.new.format(SimpleCov.result)
|
16
|
-
end
|
17
|
-
end
|
6
|
+
task default: :spec
|
data/bin/figaro
ADDED
data/doc/title.png
ADDED
Binary file
|
data/figaro.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "figaro"
|
5
|
-
gem.version = "0.
|
5
|
+
gem.version = "1.0.0.rc1"
|
6
6
|
|
7
7
|
gem.author = "Steve Richert"
|
8
8
|
gem.email = "steve.richert@gmail.com"
|
@@ -11,10 +11,14 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.homepage = "https://github.com/laserlemon/figaro"
|
12
12
|
gem.license = "MIT"
|
13
13
|
|
14
|
-
gem.add_dependency "bundler", "~> 1.0"
|
15
14
|
gem.add_dependency "rails", ">= 3", "< 5"
|
15
|
+
gem.add_dependency "thor", "~> 0.14"
|
16
16
|
|
17
|
-
gem.
|
18
|
-
gem.
|
19
|
-
|
17
|
+
gem.add_development_dependency "bundler", "~> 1.5"
|
18
|
+
gem.add_development_dependency "rake", "~> 10.1"
|
19
|
+
|
20
|
+
gem.files = `git ls-files`.split($\)
|
21
|
+
gem.test_files = gem.files.grep(/^spec/)
|
22
|
+
|
23
|
+
gem.executables << "figaro"
|
20
24
|
end
|
data/gemfiles/rails30.gemfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gemspec :
|
3
|
+
gemspec path: "../"
|
4
4
|
|
5
5
|
gem "rails", "~> 3.0.2"
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
gem "aruba", "~> 0.5"
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "rspec", "~> 2.13"
|
9
|
+
gem "rspec", "~> 2.14"
|
10
|
+
gem "sqlite3", "~> 1.3"
|
12
11
|
end
|
data/gemfiles/rails31.gemfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gemspec :
|
3
|
+
gemspec path: "../"
|
4
4
|
|
5
5
|
gem "rails", "~> 3.1.0"
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
gem "aruba", "~> 0.5"
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "rspec", "~> 2.13"
|
9
|
+
gem "rspec", "~> 2.14"
|
10
|
+
gem "sqlite3", "~> 1.3"
|
12
11
|
end
|
data/gemfiles/rails32.gemfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gemspec :
|
3
|
+
gemspec path: "../"
|
4
4
|
|
5
5
|
gem "rails", "~> 3.2.0"
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
gem "aruba", "~> 0.5"
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "rspec", "~> 2.13"
|
9
|
+
gem "rspec", "~> 2.14"
|
10
|
+
gem "sqlite3", "~> 1.3"
|
12
11
|
end
|
data/gemfiles/rails40.gemfile
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gemspec :
|
3
|
+
gemspec path: "../"
|
4
4
|
|
5
5
|
gem "rails", "~> 4.0.0"
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
gem "aruba", "~> 0.5"
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "json", "~> 1.7.7"
|
12
|
-
gem "rake", "~> 10.0"
|
13
|
-
gem "rspec", "~> 2.13"
|
14
|
-
gem "simplecov", "~> 0.7", :require => false
|
9
|
+
gem "rspec", "~> 2.14"
|
10
|
+
gem "sqlite3", "~> 1.3"
|
15
11
|
end
|
data/lib/figaro.rb
CHANGED
@@ -1,45 +1,32 @@
|
|
1
|
-
require "
|
1
|
+
require "figaro/error"
|
2
2
|
require "figaro/env"
|
3
|
-
require "figaro/
|
4
|
-
require "figaro/tasks"
|
3
|
+
require "figaro/application"
|
5
4
|
|
6
5
|
module Figaro
|
7
6
|
extend self
|
8
7
|
|
9
|
-
|
10
|
-
env(custom_environment).map { |key, value|
|
11
|
-
"#{key}=#{Shellwords.escape(value)}"
|
12
|
-
}.sort.join(" ")
|
13
|
-
end
|
14
|
-
|
15
|
-
def env(custom_environment = nil)
|
16
|
-
environment = (custom_environment || self.environment).to_s
|
17
|
-
Figaro::Env.from(stringify(flatten(raw).merge(raw.fetch(environment, {}))))
|
18
|
-
end
|
8
|
+
attr_writer :adapter, :application
|
19
9
|
|
20
|
-
def
|
21
|
-
|
10
|
+
def env
|
11
|
+
Figaro::ENV
|
22
12
|
end
|
23
13
|
|
24
|
-
def
|
25
|
-
@
|
14
|
+
def adapter
|
15
|
+
@adapter ||= Figaro::Application
|
26
16
|
end
|
27
17
|
|
28
|
-
def
|
29
|
-
@
|
18
|
+
def application
|
19
|
+
@application ||= adapter.new
|
30
20
|
end
|
31
21
|
|
32
|
-
def
|
33
|
-
|
22
|
+
def load
|
23
|
+
application.load
|
34
24
|
end
|
35
25
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
hash.reject { |_, v| Hash === v }
|
40
|
-
end
|
41
|
-
|
42
|
-
def stringify(hash)
|
43
|
-
hash.inject({}) { |h, (k, v)| h[k.to_s] = v.nil? ? nil : v.to_s; h }
|
26
|
+
def require(*keys)
|
27
|
+
missing_keys = keys.flatten - ::ENV.keys
|
28
|
+
raise MissingKeys.new(missing_keys) if missing_keys.any?
|
44
29
|
end
|
45
30
|
end
|
31
|
+
|
32
|
+
require "figaro/rails"
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
module Figaro
|
5
|
+
class Application
|
6
|
+
FIGARO_ENV_PREFIX = "_FIGARO_"
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options.inject({}) { |m, (k, v)| m[k.to_sym] = v; m }
|
12
|
+
end
|
13
|
+
|
14
|
+
def path
|
15
|
+
@options.fetch(:path) { default_path }.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def path=(path)
|
19
|
+
@options[:path] = path
|
20
|
+
end
|
21
|
+
|
22
|
+
def environment
|
23
|
+
environment = @options.fetch(:environment) { default_environment }
|
24
|
+
environment.nil? ? nil : environment.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def environment=(environment)
|
28
|
+
@options[:environment] = environment
|
29
|
+
end
|
30
|
+
|
31
|
+
def configuration
|
32
|
+
global_configuration.merge(environment_configuration)
|
33
|
+
end
|
34
|
+
|
35
|
+
def load
|
36
|
+
each do |key, value|
|
37
|
+
skip?(key) ? key_skipped!(key) : set(key, value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def each(&block)
|
42
|
+
configuration.each(&block)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def default_path
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_environment
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def raw_configuration
|
56
|
+
(@parsed ||= Hash.new { |hash, path| hash[path] = parse(path) })[path]
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse(path)
|
60
|
+
File.exist?(path) && YAML.load(ERB.new(File.read(path)).result) || {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def global_configuration
|
64
|
+
raw_configuration.reject { |_, value| value.is_a?(Hash) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def environment_configuration
|
68
|
+
raw_configuration.fetch(environment) { {} }
|
69
|
+
end
|
70
|
+
|
71
|
+
def set(key, value)
|
72
|
+
non_string_configuration!(key) unless key.is_a?(String)
|
73
|
+
non_string_configuration!(value) unless value.is_a?(String) || value.nil?
|
74
|
+
|
75
|
+
::ENV[key.to_s] = value.nil? ? nil : value.to_s
|
76
|
+
::ENV[FIGARO_ENV_PREFIX + key.to_s] = value.nil? ? nil: value.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def skip?(key)
|
80
|
+
::ENV.key?(key.to_s) && !::ENV.key?(FIGARO_ENV_PREFIX + key.to_s)
|
81
|
+
end
|
82
|
+
|
83
|
+
def non_string_configuration!(value)
|
84
|
+
warn "WARNING: Use strings for Figaro configuration. #{value.inspect} was converted to #{value.to_s.inspect}."
|
85
|
+
end
|
86
|
+
|
87
|
+
def key_skipped!(key)
|
88
|
+
warn "WARNING: Skipping key #{key.inspect}. Already set in ENV."
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/figaro/cli.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
require "figaro/cli/heroku_set"
|
4
|
+
|
5
|
+
module Figaro
|
6
|
+
class CLI < Thor
|
7
|
+
desc "heroku:set", "Send Figaro configuration to Heroku"
|
8
|
+
|
9
|
+
method_option "app",
|
10
|
+
aliases: ["-a"],
|
11
|
+
desc: "Specify a Heroku app"
|
12
|
+
method_option "environment",
|
13
|
+
aliases: ["-e"],
|
14
|
+
desc: "Specify an application environment"
|
15
|
+
method_option "path",
|
16
|
+
aliases: ["-p"],
|
17
|
+
default: "config/application.yml",
|
18
|
+
desc: "Specify a configuration file path"
|
19
|
+
|
20
|
+
define_method "heroku:set" do
|
21
|
+
HerokuSet.run(options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "figaro/cli/task"
|
2
|
+
|
3
|
+
module Figaro
|
4
|
+
class CLI < Thor
|
5
|
+
class HerokuSet < Task
|
6
|
+
def run
|
7
|
+
system(configuration, command)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def command
|
13
|
+
"heroku config:set #{vars} #{for_app}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def for_app
|
17
|
+
options[:app] ? "--app=#{options[:app]}" : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def vars
|
21
|
+
configuration.keys.map { |k| var(k) }.join(" ")
|
22
|
+
end
|
23
|
+
|
24
|
+
def var(key)
|
25
|
+
Gem.win_platform? ? %(#{key}="%#{key}%") : %(#{key}="$#{key}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "figaro/application"
|
2
|
+
|
3
|
+
module Figaro
|
4
|
+
class CLI < Thor
|
5
|
+
class Task
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def self.run(options = {})
|
9
|
+
new(options).run
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def configuration
|
19
|
+
application.configuration
|
20
|
+
end
|
21
|
+
|
22
|
+
def application
|
23
|
+
@application ||= Figaro::Application.new(options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/figaro/env.rb
CHANGED
@@ -1,16 +1,45 @@
|
|
1
1
|
module Figaro
|
2
|
-
|
3
|
-
|
4
|
-
|
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 has_key?(key) || super
|
10
|
+
when "?", nil then true
|
11
|
+
else super
|
12
|
+
end
|
5
13
|
end
|
6
14
|
|
15
|
+
private
|
16
|
+
|
7
17
|
def method_missing(method, *)
|
8
|
-
|
9
|
-
|
18
|
+
key, punctuation = extract_key_from_method(method)
|
19
|
+
|
20
|
+
case punctuation
|
21
|
+
when "!" then send(key) || missing_key!(key)
|
22
|
+
when "?" then !!send(key)
|
23
|
+
when nil then get_value(key)
|
24
|
+
else super
|
25
|
+
end
|
10
26
|
end
|
11
27
|
|
12
|
-
def
|
13
|
-
|
28
|
+
def extract_key_from_method(method)
|
29
|
+
method.to_s.downcase.match(/^(.+?)([!?=])?$/).captures
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_key?(key)
|
33
|
+
::ENV.any? { |k, _| k.downcase == key }
|
34
|
+
end
|
35
|
+
|
36
|
+
def missing_key!(key)
|
37
|
+
raise MissingKey.new("Missing required Figaro configuration key #{key.inspect}.")
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_value(key)
|
41
|
+
_, value = ::ENV.detect { |k, _| k.downcase == key }
|
42
|
+
value
|
14
43
|
end
|
15
44
|
end
|
16
45
|
end
|
data/lib/figaro/error.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Figaro
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
class RailsNotInitialized < Error; end
|
5
|
+
class MissingKey < Error; end
|
6
|
+
|
7
|
+
class MissingKeys < Error
|
8
|
+
def initialize(keys)
|
9
|
+
super("Missing required configuration keys: #{keys.inspect}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|