env_config 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in env_config.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # EnvConfig
2
+
3
+ Simple configuration management with environment variables.
4
+
5
+ Inspired by how Heroku uses environment variables for configs, EnvConfig
6
+ is a no-magic gem for defining configs in yaml, and loading them into
7
+ environment variables.
8
+
9
+ ### Features
10
+
11
+ * application.yml can be templated with erb.
12
+ * arbitrary namespaced configuration. e.g. development, qa:mac, integration/aws/ci.
13
+ * heroku friendly.
14
+ * small library, no additional dependencies
15
+
16
+ ### Installation
17
+
18
+ Install the gem, and initialize the configuation yaml and configuration loader.
19
+
20
+ gem install env_config
21
+
22
+ # if using Rails
23
+ rake env_config:init
24
+
25
+ # otherwise
26
+ env_config init
27
+
28
+ ### Example
29
+
30
+ First we define the configs we want in a yaml file:
31
+
32
+ # Each key value pair in this file will be read by EnvConfig and set to an
33
+ # environment variable. If an environment variable already exists, then it is
34
+ # not overridden by default. See EnvConfig.configure for more options.
35
+
36
+ # shared variables
37
+ common: &common
38
+ env_config1: 'config1_value'
39
+ env_config2: <%= "you can use erb" %>
40
+
41
+ # environment specifc variables
42
+ development:
43
+ <<: *common
44
+ env_config1: 'config1_override'
45
+
46
+ test:
47
+ <<: *common
48
+
49
+ # If your app is deployed on Heroku, then production Heroku values will
50
+ # override these settings because existing variables are not overridden by
51
+ # default. See also: http://devcenter.heroku.com/articles/config-vars
52
+ production:
53
+ <<: *common
54
+
55
+ Then in config/initializers/env_config.rb
56
+
57
+ EnvConfig.configure do |config|
58
+ # yaml to read default config variables
59
+ config.config_path = 'config/application.yml'
60
+
61
+ # Whether to override a variable that's already defined in an environment
62
+ # variable. Keep to false if using Heroku.
63
+ config.override_env = false
64
+
65
+ # Namespace config values
66
+ # For example, to namespace by platform and rails environment
67
+ #
68
+ # config.namespace_by = "{RbConfig::CONFIG['host_os']}/#{Rails.env}"
69
+ #
70
+ # Then in your config/application.yml, you can nest your config by the
71
+ # namepaces.
72
+ #
73
+ # darwin11.0.0:
74
+ # development:
75
+ # var_name: "mac development specific value"
76
+ #
77
+ config.namespace_by = Rails.env
78
+
79
+ # Delimiter to split namespaces by when finding scoped config
80
+ config.namespace_delimiter = '/'
81
+ end
82
+
83
+ # This actually sets the variables into ENV
84
+ EnvConfig.set!
85
+
86
+ From here, you can access any of your variables via ENV:
87
+
88
+ ENV['my_config_name']
89
+
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << ["lib", "test"]
7
+ t.test_files = FileList['test/*_test.rb']
8
+ t.verbose = true
9
+ end
data/bin/env_config ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'env_config'
4
+
5
+ unless ARGV.size == 1
6
+ puts "Simple configuration management with environment variables"
7
+ puts ""
8
+ puts "Run 'env_config init' to initialize configuration yaml and loader."
9
+ puts "Please visit https://github.com/jch/env_config for more details."
10
+ puts ""
11
+ puts "Example:"
12
+ puts ""
13
+ puts "env_config init config/application.yml config/initializers/env_config.rb"
14
+ puts ""
15
+ exit 1
16
+ end
17
+
18
+ # TODO: gross that defaults are duplicated here. Ideally would just run
19
+ # rake env_config:init config_path=... loader_path=...
20
+ config_path = ARGV[1] || 'config/application.yml'
21
+ loader_path = ARGV[2] || 'config/initializers/env_config.rb'
22
+
23
+ EnvConfig.init!(config_path, loader_path)
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/env_config/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jerry Cheung"]
6
+ gem.email = ["jch@whatcodecraves.com"]
7
+ gem.description = "Simple configuration management with environment variables"
8
+ gem.summary = <<-SUM
9
+ Inspired by how Heroku uses environment variables for configs, EnvConfig
10
+ is a no-magic gem for defining configs in yaml, and loading them into
11
+ environment variables.
12
+ SUM
13
+ gem.homepage = "https://github.com/jch/env_config"
14
+
15
+ gem.executables = %w(env_config)
16
+ gem.files = `git ls-files`.split("\n")
17
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ gem.name = "env_config"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = EnvConfig::VERSION
21
+
22
+ gem.add_development_dependency "fstest"
23
+ end
data/env_config.rb ADDED
@@ -0,0 +1,23 @@
1
+ EnvConfig.configure do |config|
2
+ # yaml to read default config variables
3
+ config.config_path = /Users/jch/projects/beerpad/env_config/test/tmp/config_dir/loader.yml
4
+
5
+ # Whether to override a variable that's already defined in an environment
6
+ # variable. Keep to false if using Heroku.
7
+ config.override_env = false
8
+
9
+ # Namespace config values
10
+ # for deeper nesting, separate with '/'.
11
+ # For example, to namespace by platform and rails environment
12
+ #
13
+ # config.namespace_by = "{RbConfig::CONFIG['host_os']}/#{Rails.env}"
14
+ #
15
+ # Then in your config/application.yml, you can nest your config by the
16
+ # namepaces.
17
+ #
18
+ # darwin11.0.0:
19
+ # development:
20
+ # var_name: "mac development specific value"
21
+ #
22
+ config.namespace_by = ""
23
+ end
@@ -0,0 +1,37 @@
1
+ module EnvConfig
2
+ class Config
3
+ # yaml to read default config variables
4
+ # Defaults to config/application.yml
5
+ attr_accessor :config_path
6
+
7
+ # Whether to override a variable that's already defined in an environment
8
+ # variable.
9
+ # Defaults to false
10
+ attr_accessor :override_env
11
+
12
+ # string to split namespace_by with. defaults to '/'
13
+ attr_accessor :namespace_delimiter
14
+
15
+ # Namespace config values
16
+ # Defaults to ""
17
+ # For deeper nesting, separate with '/'.
18
+ # For example, to namespace by platform and rails environment
19
+ #
20
+ # config.namespace_by = "{RbConfig::CONFIG['host_os']}/#{Rails.env}"
21
+ #
22
+ # Then in your config/application.yml, you can nest your config by the
23
+ # namepaces.
24
+ #
25
+ # darwin11.0.0:
26
+ # development:
27
+ # var_name: "mac development specific value"
28
+ #
29
+ attr_accessor :namespace_by
30
+ def initialize
31
+ @config_path = "config/application.yml"
32
+ @override_env = false
33
+ @namespace_by = nil
34
+ @namespace_delimiter = "/"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module EnvConfig
2
+ VERSION = "0.1.0"
3
+ end
data/lib/env_config.rb ADDED
@@ -0,0 +1,64 @@
1
+ require "env_config/version"
2
+ require "erb"
3
+ require "pathname"
4
+ require "yaml"
5
+ require "env_config/config"
6
+ require 'rake'
7
+ load 'tasks/env_config.rake'
8
+
9
+ module EnvConfig
10
+ extend self
11
+
12
+ # EnvConfig::Config object
13
+ attr_accessor :config
14
+
15
+ # Creates a new EnvConfig::Config object and yields to block
16
+ # returns config object
17
+ def configure
18
+ @config ||= Config.new
19
+ yield @config if block_given?
20
+ @config
21
+ end
22
+
23
+ # After #configure, this method sets all scoped variables into environment
24
+ # variables
25
+ def set!(options = {})
26
+ options[:scoped] ||= find_scoped_config
27
+ options[:config] ||= @config
28
+ options[:scoped].each do |key, value|
29
+ ENV[key] = value if config.override_env
30
+ ENV[key] ||= value
31
+ end
32
+ end
33
+
34
+ # Creates initial application.yml and loader. See env_config.rake
35
+ def init!(config_path, loader_path)
36
+ require 'rake'
37
+ load 'tasks/env_config.rake'
38
+ Rake::Task['env_config:init'].invoke(config_path, loader_path)
39
+ end
40
+
41
+ private
42
+
43
+ # iterate through namespaces until we have the scoped config we want
44
+ def find_scoped_config
45
+ # evalute config yaml through erb
46
+ template = Pathname.new(config.config_path).read
47
+ template_result = ERB.new(template).result(binding)
48
+ yaml = YAML::load(template_result)
49
+
50
+ return yaml if (config.namespace_by == '' || config.namespace_by.nil?)
51
+
52
+ config.namespace_by.split(config.namespace_delimiter).inject(yaml) do |y, scope|
53
+ begin
54
+ y[scope]
55
+ rescue
56
+ # namespace config doesn't match up w/ application yaml
57
+ raise ArgumentError.new("Couldn't find namespace #{scope} within #{config.config_path}")
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ # Initialize default config
64
+ EnvConfig.configure
@@ -0,0 +1,44 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'erb'
4
+
5
+ namespace :env_config do
6
+ desc <<-DOC
7
+ Generate initial config/application.yml config file. config_path defaults
8
+ to 'config/application.yml'.
9
+ DOC
10
+ task :init, :config_path, :loader_path, :rails do |t, args|
11
+ args.with_defaults({
12
+ :rails => defined?(Rails),
13
+ :config_path => 'config/application.yml',
14
+ :loader_path => defined?(Rails) ?
15
+ 'config/initializers/env_config.rb' :
16
+ 'env_config.rb'
17
+ })
18
+
19
+ config_path = Pathname.new(args[:config_path])
20
+ loader_path = Pathname.new(args[:loader_path])
21
+ [config_path, loader_path].each {|path| path.dirname.mkpath}
22
+
23
+ # generate template files. too heavy to use thor
24
+ # output to config_path and loader_path
25
+ template_path = Pathname.new File.expand_path('../../../templates', __FILE__)
26
+
27
+ # write default config
28
+ unless config_path.exist?
29
+ template = template_path + ((args[:rails] ? "rails." : "") + "application.yml")
30
+ FileUtils.cp(template, config_path)
31
+ end
32
+
33
+ # write default loader
34
+ unless loader_path.exist?
35
+ template = template_path + ((args[:rails] ? "rails." : "") + "env_config.rb.erb")
36
+ loader_path.open('w') do |f|
37
+ f.write(ERB.new(template.read).result(binding))
38
+ end
39
+ end
40
+
41
+ puts "Successfully added config files."
42
+ puts "Take a look at #{config_path} and #{loader_path} for customization"
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ # Each key value pair in this file will be read by EnvConfig and set to an
2
+ # environment variable. If an environment variable already exists, then it is
3
+ # not overridden by default. See EnvConfig.configure for more options.
4
+
5
+
6
+ env_config: 'config1_value'
7
+ erb_config: <%= "you can use erb" %>
@@ -0,0 +1,29 @@
1
+ EnvConfig.configure do |config|
2
+ # yaml to read default config variables
3
+ config.config_path = "<%= config_path %>"
4
+
5
+ # Whether to override a variable that's already defined in an environment
6
+ # variable. Keep to false if using Heroku.
7
+ config.override_env = false
8
+
9
+ # Namespace config values
10
+ # for deeper nesting, separate with '/'.
11
+ # For example, to namespace by platform and rails environment
12
+ #
13
+ # config.namespace_by = "{RbConfig::CONFIG['host_os']}/#{Rails.env}"
14
+ #
15
+ # Then in your config/application.yml, you can nest your config by the
16
+ # namepaces.
17
+ #
18
+ # darwin11.0.0:
19
+ # development:
20
+ # var_name: "mac development specific value"
21
+ #
22
+ config.namespace_by = nil
23
+
24
+ # Delimiter to split namespaces by when finding scoped config
25
+ config.namespace_delimiter = '/'
26
+ end
27
+
28
+ # This actually sets the variables into ENV
29
+ EnvConfig.set!
@@ -0,0 +1,22 @@
1
+ # Each key value pair in this file will be read by EnvConfig and set to an
2
+ # environment variable. If an environment variable already exists, then it is
3
+ # not overridden by default. See EnvConfig.configure for more options.
4
+
5
+ # shared variables
6
+ common: &common
7
+ env_config1: 'config1_value'
8
+ env_config2: <%= "you can use erb" %>
9
+
10
+ # environment specifc variables
11
+ development:
12
+ <<: *common
13
+ env_config1: 'config1_override'
14
+
15
+ test:
16
+ <<: *common
17
+
18
+ # If your app is deployed on Heroku, then production Heroku values will
19
+ # override these settings because existing variables are not overridden by
20
+ # default. See also: http://devcenter.heroku.com/articles/config-vars
21
+ production:
22
+ <<: *common
@@ -0,0 +1,29 @@
1
+ EnvConfig.configure do |config|
2
+ # yaml to read default config variables
3
+ config.config_path = "<%= config_path %>"
4
+
5
+ # Whether to override a variable that's already defined in an environment
6
+ # variable. Keep to false if using Heroku.
7
+ config.override_env = false
8
+
9
+ # Namespace config values
10
+ # for deeper nesting, separate with '/'.
11
+ # For example, to namespace by platform and rails environment
12
+ #
13
+ # config.namespace_by = "{RbConfig::CONFIG['host_os']}/#{Rails.env}"
14
+ #
15
+ # Then in your config/application.yml, you can nest your config by the
16
+ # namepaces.
17
+ #
18
+ # darwin11.0.0:
19
+ # development:
20
+ # var_name: "mac development specific value"
21
+ #
22
+ config.namespace_by = Rails.env
23
+
24
+ # Delimiter to split namespaces by when finding scoped config
25
+ config.namespace_delimiter = '/'
26
+ end
27
+
28
+ # This actually sets the variables into ENV
29
+ EnvConfig.set!
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class ConfigTest < Test::Unit::TestCase
4
+ def test_defaults
5
+ config = EnvConfig::Config.new
6
+ assert_equal "config/application.yml", config.config_path
7
+ assert_equal false, config.override_env
8
+ assert_equal nil, config.namespace_by
9
+ assert_equal '/', config.namespace_delimiter
10
+ end
11
+ end
@@ -0,0 +1,73 @@
1
+ require 'test_helper'
2
+
3
+ class EnvConfigTest < Test::Unit::TestCase
4
+ def setup
5
+ EnvConfig.config = nil
6
+ @config = EnvConfig.configure
7
+ ENV.delete_if { true }
8
+ end
9
+
10
+ def test_default_configure
11
+ assert_not_nil @config
12
+ end
13
+
14
+ def test_configure_yields_same_config
15
+ EnvConfig.configure do |new_config|
16
+ assert_equal @config, new_config
17
+ end
18
+ end
19
+
20
+ def test_flat_app_config
21
+ EnvConfig.configure do |c|
22
+ c.config_path = fixture_path('flat.yml')
23
+ c.namespace_by = ''
24
+ end
25
+ scoped = EnvConfig.send(:find_scoped_config)
26
+ assert_equal 2, scoped.keys.size
27
+ assert_equal 'NYC', scoped['city']
28
+ assert_equal 'NY', scoped['state']
29
+ end
30
+
31
+ def test_scoped_app_config
32
+ EnvConfig.configure do |c|
33
+ c.config_path = fixture_path('nested.yml')
34
+ c.namespace_by = 'foo:bar'
35
+ c.namespace_delimiter = ':'
36
+ end
37
+ scoped = EnvConfig.send(:find_scoped_config)
38
+ assert_equal 2, scoped.keys.size
39
+ assert_equal 'Sam Adams', scoped['beer']
40
+ assert_equal 'PopEyes', scoped['dinner']
41
+ end
42
+
43
+ def test_invalid_scope
44
+ EnvConfig.configure do |c|
45
+ c.config_path = fixture_path('flat.yml')
46
+ c.namespace_by = 'foo:bar'
47
+ c.namespace_delimiter = ':'
48
+ end
49
+ assert_raises(ArgumentError) do
50
+ EnvConfig.send(:find_scoped_config)
51
+ end
52
+ end
53
+
54
+ def test_set_environment_no_override
55
+ ENV['city'] = "Austin"
56
+ EnvConfig.configure do |c|
57
+ c.config_path = fixture_path('flat.yml')
58
+ c.override_env = false
59
+ end
60
+ EnvConfig.set!
61
+ assert_equal 'Austin', ENV['city']
62
+ end
63
+
64
+ def test_set_environment_override
65
+ ENV['city'] = "Berkeley"
66
+ EnvConfig.configure do |c|
67
+ c.config_path = fixture_path('flat.yml')
68
+ c.override_env = true
69
+ end
70
+ EnvConfig.set!
71
+ assert_equal 'NYC', ENV['city']
72
+ end
73
+ end
@@ -0,0 +1,2 @@
1
+ city: 'NYC'
2
+ state: 'NY'
@@ -0,0 +1,4 @@
1
+ foo:
2
+ bar:
3
+ beer: 'Sam Adams'
4
+ dinner: 'PopEyes'
data/test/rake_test.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+ require 'pathname'
3
+ require 'fstest'
4
+
5
+ class RakeTest < Test::Unit::TestCase
6
+ include FSTest
7
+
8
+ def setup
9
+ temp_dir = Pathname.new File.expand_path('../tmp', __FILE__)
10
+ temp_dir.rmtree rescue nil
11
+ temp_dir.mkpath
12
+ @config_path = temp_dir + 'config_dir/config.yml'
13
+ @loader_path = temp_dir + 'app_dir/loader.rb'
14
+ Rake::Task['env_config:init'].reenable # rake tasks only run once
15
+ end
16
+
17
+ def test_init_normal
18
+ capture_io { Rake::Task['env_config:init'].invoke(@config_path, @loader_path, false) }
19
+ assert_file @config_path, /erb_config/
20
+ assert_file @loader_path, /config.namespace_by = nil/, /EnvConfig.set!/, Regexp.new("config.config_path = \"#{@config_path}\"")
21
+ end
22
+
23
+ def test_init_rails
24
+ capture_io { Rake::Task['env_config:init'].invoke(@config_path, @loader_path, true) }
25
+ assert_file @config_path, /development/
26
+ assert_file @loader_path, /config.namespace_by = Rails.env/, /EnvConfig.set!/, Regexp.new("config.config_path = \"#{@config_path}\"")
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'env_config'
3
+
4
+ class Test::Unit::TestCase
5
+ def fixture_path(filename)
6
+ Pathname.new File.expand_path("../fixtures/#{filename}", __FILE__)
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: env_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jerry Cheung
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-23 00:00:00.000000000 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fstest
17
+ requirement: &70268031170440 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *70268031170440
26
+ description: Simple configuration management with environment variables
27
+ email:
28
+ - jch@whatcodecraves.com
29
+ executables:
30
+ - env_config
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - Gemfile
36
+ - README.md
37
+ - Rakefile
38
+ - bin/env_config
39
+ - env_config.gemspec
40
+ - env_config.rb
41
+ - lib/env_config.rb
42
+ - lib/env_config/config.rb
43
+ - lib/env_config/version.rb
44
+ - lib/tasks/env_config.rake
45
+ - templates/application.yml
46
+ - templates/env_config.rb.erb
47
+ - templates/rails.application.yml
48
+ - templates/rails.env_config.rb.erb
49
+ - test/config_test.rb
50
+ - test/env_config_test.rb
51
+ - test/fixtures/flat.yml
52
+ - test/fixtures/nested.yml
53
+ - test/rake_test.rb
54
+ - test/test_helper.rb
55
+ has_rdoc: true
56
+ homepage: https://github.com/jch/env_config
57
+ licenses: []
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.6.2
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: Inspired by how Heroku uses environment variables for configs, EnvConfig is
80
+ a no-magic gem for defining configs in yaml, and loading them into environment variables.
81
+ test_files:
82
+ - test/config_test.rb
83
+ - test/env_config_test.rb
84
+ - test/fixtures/flat.yml
85
+ - test/fixtures/nested.yml
86
+ - test/rake_test.rb
87
+ - test/test_helper.rb