env_config 0.1.0

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