env-conf 0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9df5435035857289037f37777072719bbf03be22
4
+ data.tar.gz: ac4f1828b1977324d88817f0cb0e66d761e16c18
5
+ SHA512:
6
+ metadata.gz: 7cfa1abae140f8a877dc8ee1ef51989b8b342a02a0269e66042b8db80cec4d6d7eef253f94c7aeb7915cc40bc2e677bde86189b2a64ce3d919a55beb9cc9a11d
7
+ data.tar.gz: 7a9830f7ea6a82972cd738e62fe2f41addb0941dd2517fed19e6302be5d79f9990efed6f5bdfb3aa3240428c6d5281377a2d27f30dca7a060f3dfdedf62449d7
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in env-conf.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Chris Continanza
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.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # env-conf
2
+ ## a better `Config`
3
+
4
+ Provides a better way to configure the application than simply pulling
5
+ strings from `ENV`.
6
+
7
+ #### defaults
8
+
9
+ ```ruby
10
+ Config[:foo]
11
+ # => nil
12
+
13
+ Config.default(:foo, 'bar')
14
+ Config[:foo]
15
+ # => 'bar'
16
+ Config['FOO']
17
+ # => 'bar'
18
+ ```
19
+
20
+ #### type casts
21
+
22
+ Returns `nil` when undefined, otherwise casts to indicated type.
23
+
24
+ ```ruby
25
+ Config.int(:max_connections)
26
+ ```
27
+
28
+ ## Installation
29
+
30
+ Add this line to your application's Gemfile:
31
+
32
+ ```ruby
33
+ gem 'env-conf'
34
+ ```
35
+
36
+ And then execute:
37
+
38
+ $ bundle
39
+
40
+ Or install it yourself as:
41
+
42
+ $ gem install env-conf
43
+
44
+ ## Usage
45
+
46
+ ```ruby
47
+ require 'env-conf'
48
+
49
+ Config[:foo]
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it ( https://github.com/[my-github-username]/env-conf/fork )
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList['test/*_test.rb']
8
+ t.verbose = true
9
+ end
10
+
11
+ task default: :test
data/env-conf.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'env-conf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "env-conf"
8
+ spec.version = Config::VERSION
9
+ spec.authors = ["Chris Continanza"]
10
+ spec.email = ["christopher.continanza@gmail.com"]
11
+ spec.summary = %q{Use ENV vars for Configuration}
12
+ spec.description = %q{Follwing 12-factor principles, we use the ENV vars for configuration.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest"
24
+ end
@@ -0,0 +1,6 @@
1
+ # Unset Ruby's deprecated Config class to make room for ours
2
+ Object.send(:remove_const, :Config) if defined?(Config)
3
+
4
+ module Config
5
+ VERSION = '0.0.1'
6
+ end
data/lib/env-conf.rb ADDED
@@ -0,0 +1,169 @@
1
+ require_relative './env-conf/version'
2
+
3
+ module Config
4
+ @@defaults = {}
5
+
6
+ # Get a Config value
7
+ #
8
+ # This is the preferred and uniform way to access config vars because
9
+ # defaults are included in the lookup
10
+ #
11
+ # Uses defaults if available. Converts upper-case ENV var names
12
+ # to lower-case default names.
13
+ #
14
+ # Order of precedence is:
15
+ # 1) app's local ENV
16
+ # 2) default values
17
+ #
18
+ # Config[:foo] == nil
19
+ #
20
+ # Config.default(:foo, 'bar')
21
+ # Config[:foo] == 'bar'
22
+ #
23
+ # ENV['FOO'] = 'baz'
24
+ # Config[:foo] == 'baz'
25
+ #
26
+ # @param key [Symbol] The lower-case name of the ENV value
27
+ # @return [String] The value of the ENV value or default.
28
+ def self.[](name)
29
+ var_name = name.to_s.upcase
30
+ default_name = name.to_s.downcase.to_sym
31
+ ENV[var_name] || @@defaults[default_name]
32
+ end
33
+
34
+ # Reset defaults values
35
+ def self.reset!
36
+ @@defaults = {}
37
+ end
38
+
39
+ # An environment variable.
40
+ #
41
+ # @param name [String] The name of the environment variable to fetch a
42
+ # value for.
43
+ # @return [String] The value of the environment variable or nil if no
44
+ # match is available.
45
+ def self.env(name)
46
+ self[name]
47
+ end
48
+
49
+ # Set a default
50
+ # Defaults are supplied when accessing via Config[:varname]
51
+ #
52
+ # @param key [Symbol/String] The lower-case name of the default
53
+ # @return [String] The value of the default
54
+ def self.default(key, value)
55
+ @@defaults[key.to_s.downcase.to_sym] = value
56
+ end
57
+
58
+ # Get all the defaults
59
+ # @return [Hash] The current set of defaults
60
+ def self.defaults
61
+ @@defaults
62
+ end
63
+
64
+ # An environment variable.
65
+ #
66
+ # @param name [String] The name of the environment variable to fetch a
67
+ # value for.
68
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
69
+ # @return [String] The value of the environment variable.
70
+ def self.env!(name)
71
+ self[name] || raise("missing #{name}")
72
+ end
73
+
74
+ # The `RACK_ENV` environment variable is used to determine whether the
75
+ # service is in production mode or not.
76
+ #
77
+ # @return [Bool] True if the service is in production mode.
78
+ def self.production?
79
+ self['RACK_ENV'] == 'production'
80
+ end
81
+
82
+ # The `RACK_ENV` environment variable is used to determine whether the
83
+ # service is in test mode or not.
84
+ #
85
+ # @return [Bool] True if the service is in test mode.
86
+ def self.test?
87
+ self['RACK_ENV'] == 'test'
88
+ end
89
+
90
+ # The `APP_NAME` env var is used to identify which codebase is
91
+ # running in librato. This usually matches the name of the repository.
92
+ #
93
+ # @return [String] The name of the app
94
+ def self.app_name
95
+ env("APP_NAME")
96
+ end
97
+
98
+ # The `APP_DEPLOY` env var is used to identify which deploy of the codebase is
99
+ # running in librato. This usually matches the name of the environment such
100
+ # as local, production, staging, etc.
101
+ #
102
+ # @return [String] The deploy/environment of the app
103
+ def self.app_deploy
104
+ env("APP_DEPLOY")
105
+ end
106
+
107
+ # The port to listen on for web requests.
108
+ #
109
+ # @return [Fixnum] The port to listen on for web requests.
110
+ def self.port
111
+ env!("PORT").to_i
112
+ end
113
+
114
+ # The database URL from the environment.
115
+ #
116
+ # @param kind [String] Optionally, the leading name of `*_DATABASE_URL`
117
+ # environment variable. Defaults to `DATABASE_URL`.
118
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
119
+ def self.database_url(kind = '')
120
+ kind = "#{kind}_".upcase unless kind.empty?
121
+ env!("#{kind}DATABASE_URL")
122
+ end
123
+
124
+ # An environment variable converted to a Fixnum.
125
+ #
126
+ # @param name [String] The name of the environment variable to fetch a
127
+ # Fixnum for.
128
+ # @return [Fixnum] The number or nil if the value couldn't be coerced to a
129
+ # Fixnum.
130
+ def self.int(name)
131
+ self[name] && self[name].to_i
132
+ end
133
+
134
+ # Comma-separated words converted to an array.
135
+ #
136
+ # @param name [String] The name of the environment variable to fetch an
137
+ # array for.
138
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
139
+ # @return [Array] An array of values.
140
+ def self.array(name)
141
+ env(name).to_s.split(',')
142
+ end
143
+
144
+ # An environment variable converted to a bool.
145
+ #
146
+ # @param name [String] The name of the environment variable to fetch a
147
+ # boolean for.
148
+ # @return [bool] True if the value is `true`, otherwise false.
149
+ def self.bool?(name)
150
+ self[name] == true || self[name] == 'true'
151
+ end
152
+
153
+ # An environment variable converted to a time.
154
+ #
155
+ # @param name [String|Symbol] The name of the environment variable to fetch a
156
+ # boolean for.
157
+ # @return [Time] Time if the value is parseable, otherwise false.
158
+ def self.time(name)
159
+ self[name] && Time.parse(self[name])
160
+ end
161
+
162
+ # An environment variable converted to a URI.
163
+ #
164
+ # @param name [String|Symbol] The name of the environment variable.
165
+ # @return [URI] URI if the value is parseable, otherwise false.
166
+ def self.uri(name)
167
+ self[name] && URI.parse(self[name])
168
+ end
169
+ end
@@ -0,0 +1,216 @@
1
+ # note: this would all go in a test/helper if we had
2
+ # more than one test file
3
+ require 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+
7
+ require 'env-conf'
8
+
9
+ module EnvironmentHelpers
10
+ # Override an environment variable in the current test.
11
+ def set_env(key, value)
12
+ overrides[key] = ENV[key] unless overrides.has_key?(key)
13
+ ENV[key] = value
14
+ end
15
+
16
+ # Restore the environment back to its state before tests ran.
17
+ def teardown
18
+ overrides.each { |key, value| ENV[key] = value }
19
+ super
20
+ end
21
+
22
+ private
23
+ # The overridden environment variables to restore when the test finishes.
24
+ def overrides
25
+ @overrides ||= {}
26
+ end
27
+ end
28
+
29
+ # end note
30
+
31
+ class ConfigTest < Minitest::Test
32
+ include EnvironmentHelpers
33
+
34
+ def teardown
35
+ super
36
+ Config.reset!
37
+ end
38
+
39
+ # Config.env returns the value matching the specified environment
40
+ # variable name.
41
+ def test_env
42
+ ENV['VALUE'] = 'value'
43
+ set_env('VALUE', 'value')
44
+ assert_equal(Config.env('VALUE'), 'value')
45
+ ENV['VALUE'] = nil
46
+ end
47
+
48
+ # Config[] returns the value matching the specified environment
49
+ # variable name.
50
+ def test_brackets
51
+ set_env('VALUE', 'value')
52
+ assert_equal(Config[:value], 'value')
53
+ assert_equal(Config['VALUE'], 'value')
54
+ end
55
+
56
+ # Config.env return nil if an unknown environment variable is
57
+ # requested.
58
+ def test_env_with_unknown_name
59
+ assert_equal(Config.env('UNKNOWN'), nil)
60
+ end
61
+
62
+ # Config.env! returns the value matching the specified environment
63
+ # variable name.
64
+ def test_env!
65
+ set_env('VALUE', 'value')
66
+ assert_equal(Config.env!('VALUE'), 'value')
67
+ end
68
+
69
+ # Config.env! raises a RuntimeError if an unknown environment
70
+ # variable is requested.
71
+ def test_env_with_unknown_name!
72
+ error = assert_raises RuntimeError do
73
+ Config.env!('UNKNOWN')
74
+ end
75
+ assert_equal(error.message, 'missing UNKNOWN')
76
+ end
77
+
78
+ # Config.production? is true when RACK_ENV=production.
79
+ def test_production_mode
80
+ set_env 'RACK_ENV', nil
81
+ refute Config.production?
82
+ set_env 'RACK_ENV', 'production'
83
+ assert Config.production?
84
+ end
85
+
86
+ # Config.test? is true when RACK_ENV=test.
87
+ def test_test_mode
88
+ set_env 'RACK_ENV', nil
89
+ refute Config.test?
90
+ set_env 'RACK_ENV', 'test'
91
+ assert Config.test?
92
+ end
93
+
94
+ # Returns DATABASE_URL with no params.
95
+ def test_database_url
96
+ set_env 'DATABASE_URL', "postgres:///foo"
97
+ assert_equal(Config.database_url, 'postgres:///foo')
98
+ end
99
+
100
+ # Returns #{kind}_DATABASE_URL with one param
101
+ def test_database_url_takes_and_capitalizes_params
102
+ set_env 'FOO_DATABASE_URL', "postgres:///foo"
103
+ assert_equal(Config.database_url('foo'), 'postgres:///foo')
104
+ assert_equal(Config.database_url(:foo), 'postgres:///foo')
105
+ end
106
+
107
+ # Config.database_url raises a RuntimeError if no DATABASE_URL
108
+ # environment variables is defined.
109
+ def test_database_url_raises_when_not_found
110
+ assert_raises RuntimeError do
111
+ Config.database_url('foo')
112
+ end
113
+ end
114
+
115
+ # Config.app_name returns the value of the APP_NAME environment
116
+ # variable.
117
+ def test_app_name
118
+ set_env 'APP_NAME', "my-app"
119
+ assert_equal('my-app', Config.app_name)
120
+ end
121
+
122
+ # Config.app_deploy returns the value of the APP_DEPLOY environment
123
+ # variable.
124
+ def test_app_deploy
125
+ set_env 'APP_DEPLOY', "test"
126
+ assert_equal('test', Config.app_deploy)
127
+ end
128
+
129
+ # Config.port raises a RuntimeError if no `PORT` environment variable
130
+ # is defined.
131
+ def test_port_raises
132
+ assert_raises RuntimeError do
133
+ Config.port
134
+ end
135
+ end
136
+
137
+ # Config.port converts the value from the environment to a Fixnum
138
+ def test_port_convert_to_int
139
+ set_env 'PORT', "3000"
140
+ assert_equal(3000, Config.port)
141
+ end
142
+
143
+ # Config.int(VAR) returns nil or VAR as integer.
144
+ def test_int
145
+ assert_equal(nil, Config.int('FOO'))
146
+ set_env 'FOO', "3000"
147
+ assert_equal(3000, Config.int('FOO'))
148
+ assert_equal(3000, Config.int(:foo))
149
+ end
150
+
151
+ # Config.time returns nil or VAR as time
152
+ def test_time
153
+ assert_equal(nil, Config.time('T'))
154
+ =begin
155
+ set_env 'T', '2000'
156
+ assert_equal(Time.utc(2000), Config.time(:t))
157
+ set_env 'T', '2000-2'
158
+ assert_equal(Time.utc(2000,2), Config.time(:t))
159
+ =end
160
+ set_env 'T', '2000-2-2'
161
+ assert_equal(Time.new(2000,2,2), Config.time(:t))
162
+
163
+ set_env 'T', '2000-2-2T11:11'
164
+ assert_equal(Time.new(2000,2,2,11,11), Config.time(:t))
165
+ end
166
+
167
+ # Config.time returns nil or VAR as URI
168
+ def test_uri
169
+ assert_equal(nil, Config.uri('URL'))
170
+ set_env 'URL', 'http://user:password@the-web.com/path/to/greatness?foo=bar'
171
+ uri = Config.uri('URL')
172
+ assert_equal('http', uri.scheme)
173
+ assert_equal('the-web.com', uri.host)
174
+ assert_equal('/path/to/greatness', uri.path)
175
+ assert_equal('foo=bar', uri.query)
176
+ assert_equal(80, uri.port)
177
+ assert_equal('user', uri.user)
178
+ assert_equal('password', uri.password)
179
+ end
180
+
181
+ # Config.array loads a comma-separated list of words into an array of
182
+ # strings.
183
+ def test_array
184
+ set_env 'ARRAY', ''
185
+ assert_equal([], Config.array('ARRAY'))
186
+ set_env 'ARRAY', 'apple'
187
+ assert_equal(['apple'], Config.array('ARRAY'))
188
+ set_env 'ARRAY', 'apple,orange,cherry'
189
+ assert_equal(['apple', 'orange', 'cherry'], Config.array('ARRAY'))
190
+ end
191
+
192
+ # Config.bool?(var) is only true if the value of var is the string
193
+ # 'true'. If the var is absent or any other value, it evaluates to false.
194
+ def test_bool_returns_true
195
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
196
+ set_env 'VAULT_BOOLEAN_VAR', 'true'
197
+ assert_equal(true, Config.bool?('VAULT_BOOLEAN_VAR'))
198
+
199
+ Config.default(:foo, true)
200
+ assert_equal(true, Config.bool?(:foo))
201
+ end
202
+
203
+ # Config.bool?(var) is false if the value of var is anything other
204
+ # than the string 'true'.
205
+ def test_bool_returns_false
206
+ set_env 'VAULT_BOOLEAN_VAR', 'false'
207
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
208
+ set_env 'VAULT_BOOLEAN_VAR', 'foo'
209
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
210
+ set_env 'VAULT_BOOLEAN_VAR', '1'
211
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
212
+
213
+ Config.default(:foo, false)
214
+ assert_equal(false, Config.bool?(:foo))
215
+ end
216
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: env-conf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Continanza
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Follwing 12-factor principles, we use the ENV vars for configuration.
56
+ email:
57
+ - christopher.continanza@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - env-conf.gemspec
68
+ - lib/env-conf.rb
69
+ - lib/env-conf/version.rb
70
+ - test/config_test.rb
71
+ homepage: ''
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.2.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Use ENV vars for Configuration
95
+ test_files:
96
+ - test/config_test.rb