envolve 1.0.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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +45 -0
- data/HISTORY.md +5 -0
- data/LICENSE +16 -0
- data/Manifest.txt +19 -0
- data/README.md +57 -0
- data/Rakefile +16 -0
- data/lib/envolve.rb +9 -0
- data/lib/envolve/config.rb +245 -0
- data/lib/envolve/version.rb +3 -0
- data/tasks/default.rake +259 -0
- data/tasks/this.rb +206 -0
- data/test/test_config.rb +43 -0
- data/test/test_filtered_config.rb +37 -0
- data/test/test_helper.rb +6 -0
- data/test/test_key_separator_config.rb +17 -0
- data/test/test_meta_config.rb +16 -0
- data/test/test_prefix_config.rb +20 -0
- data/test/test_property_config.rb +53 -0
- data/test/test_version.rb +12 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0957b934da66eced716f716a370f189da7633f49
|
4
|
+
data.tar.gz: c6198fd51c04495d8f232114d7d062afc52bbe85
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ea88528575352a016613859399447d0bfc881989db78cf9ab91ca7dc531098da7c882e9dab740b6338310c5c8c7eec10b703c58f1170cd3c746efc07d9d89cc1
|
7
|
+
data.tar.gz: dfb14703a551ee5c85b82d7e98da09da8e732083750cefc17aa711df77989c9933723dc46802b62cde484d95b8dd822bde8a0278e1578b9e605cd886d3cc8570
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Hi there!
|
2
|
+
|
3
|
+
I see you are interested in contributing. That is wonderful. I love
|
4
|
+
contributions.
|
5
|
+
|
6
|
+
I guarantee that there are bugs in this software. And I guarantee that there is
|
7
|
+
a feature you want that is not in here yet. As such, any and all bugs reports
|
8
|
+
are gratefully accepted, bugfixes even more so. Helping out with bugs is the
|
9
|
+
easiest way to contribute.
|
10
|
+
|
11
|
+
|
12
|
+
## The Quick Version
|
13
|
+
|
14
|
+
* Have a [GitHub Account][].
|
15
|
+
* Search the [GitHub Issues][] and see if your issue already present. If so
|
16
|
+
add your comments, :thumbsup:, etc.
|
17
|
+
* Issue not there? Not a problem, open up a [new issue][].
|
18
|
+
* **Bug reports** please be as detailed as possible. Include:
|
19
|
+
* full ruby engine and version: `ruby -e 'puts RUBY_DESCRIPTION'`
|
20
|
+
* operating system and version
|
21
|
+
* version of envolve `ruby -rubygems -e "require 'envolve'; puts Envolve::VERSION"`
|
22
|
+
* as much detail about the bug as possible so I can replicate it. Feel free
|
23
|
+
to link in a [gist][]
|
24
|
+
* **New Feature**
|
25
|
+
* What the new feature should do.
|
26
|
+
* What benefit the new feature brings to the project.
|
27
|
+
* Fork the [repo][].
|
28
|
+
* Create a new branch for your issue: `git checkout -b issue/my-issue`
|
29
|
+
* Lovingly craft your contribution:
|
30
|
+
* `rake develop` to get started, or if you prefer bundler `rake develop:using_bundler && bundle`.
|
31
|
+
* `rake test` to run tests
|
32
|
+
* Make sure that `rake test` passes. It's important, I said it twice.
|
33
|
+
* Add yourself to the contributors section below.
|
34
|
+
* Submit your [pull request][].
|
35
|
+
|
36
|
+
# Contributors
|
37
|
+
|
38
|
+
* [Jeremy Hinegardner](https://github.com/copiousfreetime)
|
39
|
+
|
40
|
+
[GitHub Account]: https://github.com/signup/free "GitHub Signup"
|
41
|
+
[GitHub Issues]: https://github.com/copiousfreetime/envolve/issues "Envolve Issues"
|
42
|
+
[new issue]: https://github.com/copiousfreetime/envolve/issues/new "New Envolve Issue"
|
43
|
+
[gist]: https://gist.github.com/ "New Gist"
|
44
|
+
[repo]: https://github.com/copiousfreetime/envolve "Envolve Repo"
|
45
|
+
[pull request]: https://help.github.com/articles/using-pull-requests "Using Pull Requests"
|
data/HISTORY.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
ISC LICENSE - http://opensource.org/licenses/isc-license.txt
|
2
|
+
|
3
|
+
Copyright (c) 2013 Jeremy Hinegardner
|
4
|
+
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
16
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
CONTRIBUTING.md
|
2
|
+
HISTORY.md
|
3
|
+
LICENSE
|
4
|
+
Manifest.txt
|
5
|
+
README.md
|
6
|
+
Rakefile
|
7
|
+
lib/envolve.rb
|
8
|
+
lib/envolve/config.rb
|
9
|
+
lib/envolve/version.rb
|
10
|
+
tasks/default.rake
|
11
|
+
tasks/this.rb
|
12
|
+
test/test_config.rb
|
13
|
+
test/test_filtered_config.rb
|
14
|
+
test/test_helper.rb
|
15
|
+
test/test_key_separator_config.rb
|
16
|
+
test/test_meta_config.rb
|
17
|
+
test/test_prefix_config.rb
|
18
|
+
test/test_property_config.rb
|
19
|
+
test/test_version.rb
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
## envolve
|
2
|
+
|
3
|
+
* [Homepage](https://github.com/copiousfreetime/envolve/)
|
4
|
+
* [Github Project](https://github.com/copiousfreetime/envolve)
|
5
|
+
|
6
|
+
## DESCRIPTION
|
7
|
+
|
8
|
+
Envolve provides a consistent and validating way to access your application
|
9
|
+
configuration that is set via environment variables.
|
10
|
+
|
11
|
+
This is double beneficial if you are configuring your entire application with
|
12
|
+
environment variables. See. http://12factor.net/config
|
13
|
+
|
14
|
+
## USAGE
|
15
|
+
|
16
|
+
module MyApp
|
17
|
+
class MyConfig < ::Envolve::Config
|
18
|
+
prefix 'my_app'
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def self.config
|
23
|
+
@config ||= MyConfig.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# deep in some code somewhere
|
29
|
+
|
30
|
+
hostname = MyApp.config.hostname # which was originall from ENV['MY_APP_HOSTNAME']
|
31
|
+
|
32
|
+
|
33
|
+
## FEATURES
|
34
|
+
|
35
|
+
envolve
|
36
|
+
|
37
|
+
## Examples
|
38
|
+
|
39
|
+
## ISC LICENSE
|
40
|
+
|
41
|
+
http://opensource.org/licenses/isc-license.txt
|
42
|
+
|
43
|
+
Copyright (c) 2013 Jeremy Hinegardner
|
44
|
+
|
45
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
46
|
+
purpose with or without fee is hereby granted, provided that the above
|
47
|
+
copyright notice
|
48
|
+
and this permission notice appear in all copies.
|
49
|
+
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
51
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
52
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
53
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
54
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
55
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
56
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
57
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# vim: syntax=ruby
|
2
|
+
load 'tasks/this.rb'
|
3
|
+
|
4
|
+
This.name = "envolve"
|
5
|
+
This.author = "Jeremy Hinegardner"
|
6
|
+
This.email = "jeremy@copiousfreetime.org"
|
7
|
+
This.homepage = "http://github.com/copiousfreetime/#{ This.name }"
|
8
|
+
|
9
|
+
This.ruby_gemspec do |spec|
|
10
|
+
spec.add_development_dependency( 'rake' , '~> 10.3')
|
11
|
+
spec.add_development_dependency( 'minitest' , '~> 5.4' )
|
12
|
+
spec.add_development_dependency( 'rdoc' , '~> 4.1' )
|
13
|
+
spec.add_development_dependency( 'simplecov', '~> 0.9' )
|
14
|
+
end
|
15
|
+
|
16
|
+
load 'tasks/default.rake'
|
data/lib/envolve.rb
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
module Envolve
|
2
|
+
# Public: A Configuration class to hold your application configuration
|
3
|
+
#
|
4
|
+
# Feed it ENV or some other Hash-like object and it will allow you to access
|
5
|
+
# the elements in that hash via methods.
|
6
|
+
#
|
7
|
+
# You can also tell it to only pull those items from the initial has that have
|
8
|
+
# a particular prefix, and that prefix will be stripped off of the elements
|
9
|
+
# for access.
|
10
|
+
class Config
|
11
|
+
# Public: Return the default environment.
|
12
|
+
#
|
13
|
+
# Override this to return a different environment source
|
14
|
+
def self.environment_source( *args, &block )
|
15
|
+
if args.size > 0 then
|
16
|
+
@_default_env = args.first
|
17
|
+
elsif block_given? then
|
18
|
+
@_default_env = block.call
|
19
|
+
else
|
20
|
+
@_default_env ||= ENV.to_hash
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: Return the prefix to be used by the class
|
25
|
+
#
|
26
|
+
# Override this to return a different prefix, or meta program it in an
|
27
|
+
# inherited class.
|
28
|
+
def self.prefix( *args )
|
29
|
+
if args.size > 0 then
|
30
|
+
@_prefix = args.first
|
31
|
+
else
|
32
|
+
@_prefix = nil if !defined?( @_prefix )
|
33
|
+
end
|
34
|
+
@_prefix
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: Return the key_separator to be used by the class
|
38
|
+
#
|
39
|
+
# Override this to return a different key_separator, or meta program it in an
|
40
|
+
# inherited class.
|
41
|
+
def self.key_separator( *args, &block )
|
42
|
+
if args.size > 0 then
|
43
|
+
@_key_separator = args.first
|
44
|
+
else
|
45
|
+
@_key_separator = '_'.freeze if !defined?( @_key_separator )
|
46
|
+
end
|
47
|
+
@_key_separator
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Set a property, with possible transformations
|
51
|
+
#
|
52
|
+
# In the conversion of a the environment to the configuration properties
|
53
|
+
# sometimes the keys and/or values need to be converted to a new name.
|
54
|
+
#
|
55
|
+
# All property transformations take place AFTER the initial keys have been downcased
|
56
|
+
# and prefix stripped.
|
57
|
+
#
|
58
|
+
# property - the name of the property we want to appear in the configuration
|
59
|
+
# key - the source key from the environment where this property comes from
|
60
|
+
# value - the new value for this property
|
61
|
+
# default - setting a default for this property should it not exist
|
62
|
+
#
|
63
|
+
# value may also be a lambda, in which ase the lambda is given the original
|
64
|
+
# value and the return value from the labmda is used for the new value.
|
65
|
+
#
|
66
|
+
def self.property( property, key: nil, value: nil, default: nil )
|
67
|
+
properties[property] = { :key => key, :value => value, :default => default }
|
68
|
+
end
|
69
|
+
|
70
|
+
# Internal: Return the hash holding the properties
|
71
|
+
#
|
72
|
+
# Returns Hash
|
73
|
+
def self.properties
|
74
|
+
@_properties ||= Hash.new
|
75
|
+
end
|
76
|
+
|
77
|
+
# Internal: The internal hash holding all the keys and values
|
78
|
+
attr_reader :_env
|
79
|
+
|
80
|
+
# Internal: The prefix to strip off all the keys
|
81
|
+
attr_reader :_prefix
|
82
|
+
|
83
|
+
# Internal: The character to use as the key separator
|
84
|
+
attr_reader :_key_separator
|
85
|
+
|
86
|
+
# Public: Create a new Config
|
87
|
+
def initialize( env: self.class.environment_source, prefix: self.class.prefix,
|
88
|
+
key_separator: self.class.key_separator )
|
89
|
+
@_key_separator = key_separator
|
90
|
+
@_prefix = prefix.nil? ? nil : prefix.to_s.downcase.strip
|
91
|
+
@_env = process_env( env )
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Internal: Process and Transform the keys and values from the environment
|
97
|
+
# into the final hash
|
98
|
+
#
|
99
|
+
def process_env( env )
|
100
|
+
env = downcase_keys( env )
|
101
|
+
if _prefix then
|
102
|
+
env = filter_by_prefix( env, _prefix )
|
103
|
+
end
|
104
|
+
env = transform_properties( env, self.class.properties )
|
105
|
+
end
|
106
|
+
|
107
|
+
# Internal: Transform the environment variables to propreties
|
108
|
+
#
|
109
|
+
# Returns the transformed hash
|
110
|
+
def transform_properties( env, properties )
|
111
|
+
transformed = env.to_h.dup
|
112
|
+
|
113
|
+
properties.each do |dest_key, trans|
|
114
|
+
src_key = trans[:key]
|
115
|
+
src_key ||= dest_key
|
116
|
+
if value = transformed.delete(src_key) then
|
117
|
+
value = apply_transformation(value, trans[:value]) if trans[:value]
|
118
|
+
elsif value.nil? then
|
119
|
+
value = trans[:default] if trans[:default]
|
120
|
+
end
|
121
|
+
transformed[dest_key] = value
|
122
|
+
end
|
123
|
+
|
124
|
+
return transformed
|
125
|
+
end
|
126
|
+
|
127
|
+
# Internal: Apply the given transformation to the input.
|
128
|
+
#
|
129
|
+
# Returns the result of the transformation
|
130
|
+
def apply_transformation( input, transformer )
|
131
|
+
return input if transformer.nil?
|
132
|
+
return transformer.call( input ) if transformer.respond_to?( :call )
|
133
|
+
return transformer
|
134
|
+
end
|
135
|
+
|
136
|
+
# Public: The number of elements in the config
|
137
|
+
#
|
138
|
+
# Returns the number of elements
|
139
|
+
def size
|
140
|
+
_env.size
|
141
|
+
end
|
142
|
+
|
143
|
+
# Public: Just the keys, only the keys, as Strings
|
144
|
+
#
|
145
|
+
# Returns an Array of the keys as Strings
|
146
|
+
def keys
|
147
|
+
_env.keys
|
148
|
+
end
|
149
|
+
|
150
|
+
# Public: return the value for the give key
|
151
|
+
#
|
152
|
+
# key - the String key to use for fetching
|
153
|
+
#
|
154
|
+
# Returns value or nil if no value is found
|
155
|
+
def []( key )
|
156
|
+
_env[key]
|
157
|
+
end
|
158
|
+
|
159
|
+
# Public: Return a subset of the config with just those items that have a
|
160
|
+
# prefix on them
|
161
|
+
#
|
162
|
+
# The resulting Config only has those keys, and all with the prefixes
|
163
|
+
# stripped
|
164
|
+
def config_with_prefix( prefix )
|
165
|
+
self.class.new( env: _env, prefix: prefix )
|
166
|
+
end
|
167
|
+
|
168
|
+
# Public: Return as hash of the keys and values
|
169
|
+
#
|
170
|
+
# Returns a Hash
|
171
|
+
def to_h
|
172
|
+
_env.to_h.dup
|
173
|
+
end
|
174
|
+
alias to_hash to_h
|
175
|
+
|
176
|
+
# Public: Return a hash of the keys and values with the keys as symbols.
|
177
|
+
#
|
178
|
+
# Returns a Hash
|
179
|
+
def to_symbolized_h
|
180
|
+
h = {}
|
181
|
+
_env.each do |key, value|
|
182
|
+
h[key.to_sym] = value
|
183
|
+
end
|
184
|
+
return h
|
185
|
+
end
|
186
|
+
alias to_symbolized_hash to_symbolized_h
|
187
|
+
|
188
|
+
# Internal: This is how we convert method calls into key lookups in the
|
189
|
+
# internal hash.
|
190
|
+
def method_missing( method, *args, &block )
|
191
|
+
s_method = method.to_s
|
192
|
+
if _env.has_key?( s_method ) then
|
193
|
+
_env[ s_method ]
|
194
|
+
else
|
195
|
+
super
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Internal: Respond to missing should always be implemented if you implement
|
200
|
+
# method_missing
|
201
|
+
def respond_to_missing?( symbol, include_all = false )
|
202
|
+
_env.has_key?( symbol.to_s ) || super
|
203
|
+
end
|
204
|
+
|
205
|
+
# Internal: The prefix regular expression used for stripping leading prefix
|
206
|
+
#
|
207
|
+
# This matches Beginning of String followed by the prefix followed by 0 or
|
208
|
+
# more key_separator characters.
|
209
|
+
#
|
210
|
+
# This will use named captures. The prefix will be under key 'prefix' and
|
211
|
+
# the following will be under 'rest'
|
212
|
+
#
|
213
|
+
# Returns the regex
|
214
|
+
def prefix_regex( prefix, key_separator )
|
215
|
+
/\A(?<prefix>#{prefix}[#{key_separator}]*)(?<rest>.*)\Z/i
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
# Return a copy of the hash filtered by the prefix.
|
222
|
+
#
|
223
|
+
# All the keys that match the prefix will have hte prefix stripped off. All
|
224
|
+
# others will be ignored
|
225
|
+
def filter_by_prefix( in_hash, pre = _prefix, ks = _key_separator )
|
226
|
+
out_hash = {}
|
227
|
+
matcher = prefix_regex( pre, ks )
|
228
|
+
in_hash.each do |key, value|
|
229
|
+
if md = matcher.match( key ) then
|
230
|
+
out_hash[ md[:rest] ] = value
|
231
|
+
end
|
232
|
+
end
|
233
|
+
return out_hash
|
234
|
+
end
|
235
|
+
|
236
|
+
# Return a copy of the hash with all the keys downcased
|
237
|
+
def downcase_keys( in_hash )
|
238
|
+
out_hash = {}
|
239
|
+
in_hash.each do |key, value|
|
240
|
+
out_hash[key.downcase] = value
|
241
|
+
end
|
242
|
+
return out_hash
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
data/tasks/default.rake
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
# vim: syntax=ruby
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'digest'
|
4
|
+
#------------------------------------------------------------------------------
|
5
|
+
# If you want to Develop on this project just run 'rake develop' and you'll
|
6
|
+
# have all you need to get going. If you want to use bundler for development,
|
7
|
+
# then run 'rake develop:using_bundler'
|
8
|
+
#------------------------------------------------------------------------------
|
9
|
+
namespace :develop do
|
10
|
+
|
11
|
+
# Install all the development and runtime dependencies of this gem using the
|
12
|
+
# gemspec.
|
13
|
+
task :default do
|
14
|
+
require 'rubygems/dependency_installer'
|
15
|
+
installer = ::Gem::DependencyInstaller.new
|
16
|
+
|
17
|
+
puts "Installing gem depedencies needed for development"
|
18
|
+
This.platform_gemspec.dependencies.each do |dep|
|
19
|
+
if dep.matching_specs.empty? then
|
20
|
+
puts "Installing : #{dep}"
|
21
|
+
installer.install dep
|
22
|
+
else
|
23
|
+
puts "Skipping : #{dep} -> already installed #{dep.matching_specs.first.full_name}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
puts "\n\nNow run 'rake test'"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create a Gemfile that just references the gemspec
|
30
|
+
file 'Gemfile' => :gemspec do
|
31
|
+
File.open( "Gemfile", "w+" ) do |f|
|
32
|
+
f.puts "# DO NOT EDIT - This file is automatically generated"
|
33
|
+
f.puts "# Make changes to Manifest.txt and/or Rakefile and regenerate"
|
34
|
+
f.puts 'source "https://rubygems.org/"'
|
35
|
+
f.puts 'gemspec'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Create a bundler Gemfile"
|
40
|
+
task :using_bundler => 'Gemfile' do
|
41
|
+
puts "Now you can 'bundle'"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Gemfiles are build artifacts
|
45
|
+
CLOBBER << FileList['Gemfile*']
|
46
|
+
end
|
47
|
+
desc "Boostrap development"
|
48
|
+
task :develop => "develop:default"
|
49
|
+
|
50
|
+
#------------------------------------------------------------------------------
|
51
|
+
# Minitest - standard TestTask
|
52
|
+
#------------------------------------------------------------------------------
|
53
|
+
begin
|
54
|
+
require 'rake/testtask'
|
55
|
+
Rake::TestTask.new( :test ) do |t|
|
56
|
+
t.ruby_opts = %w[ -w -rubygems ]
|
57
|
+
t.libs = %w[ lib spec test ]
|
58
|
+
t.pattern = "{test,spec}/**/{test_*,*_spec}.rb"
|
59
|
+
end
|
60
|
+
|
61
|
+
task :test_requirements
|
62
|
+
task :test => :test_requirements
|
63
|
+
task :default => :test
|
64
|
+
rescue LoadError
|
65
|
+
This.task_warning( 'test' )
|
66
|
+
end
|
67
|
+
|
68
|
+
#------------------------------------------------------------------------------
|
69
|
+
# RDoc - standard rdoc rake task, although we must make sure to use a more
|
70
|
+
# recent version of rdoc since it is the one that has 'tomdoc' markup
|
71
|
+
#------------------------------------------------------------------------------
|
72
|
+
begin
|
73
|
+
gem 'rdoc' # otherwise we get the wrong task from stdlib
|
74
|
+
require 'rdoc/task'
|
75
|
+
RDoc::Task.new do |t|
|
76
|
+
t.markup = 'tomdoc'
|
77
|
+
t.rdoc_dir = 'doc'
|
78
|
+
t.main = 'README.md'
|
79
|
+
t.title = "#{This.name} #{This.version}"
|
80
|
+
t.rdoc_files.include( FileList['*.{rdoc,md,txt}'], FileList['ext/**/*.c'],
|
81
|
+
FileList['lib/**/*.rb'] )
|
82
|
+
end
|
83
|
+
rescue StandardError, LoadError
|
84
|
+
This.task_warning( 'rdoc' )
|
85
|
+
end
|
86
|
+
|
87
|
+
#------------------------------------------------------------------------------
|
88
|
+
# Coverage - optional code coverage, rcov for 1.8 and simplecov for 1.9, so
|
89
|
+
# for the moment only rcov is listed.
|
90
|
+
#------------------------------------------------------------------------------
|
91
|
+
begin
|
92
|
+
require 'simplecov'
|
93
|
+
desc 'Run tests with code coverage'
|
94
|
+
task :coverage do
|
95
|
+
ENV['COVERAGE'] = 'true'
|
96
|
+
Rake::Task[:test].execute
|
97
|
+
end
|
98
|
+
CLOBBER << FileList["coverage/**/*"]
|
99
|
+
rescue LoadError
|
100
|
+
This.task_warning( 'simplecov' )
|
101
|
+
end
|
102
|
+
|
103
|
+
#------------------------------------------------------------------------------
|
104
|
+
# Manifest - We want an explicit list of thos files that are to be packaged in
|
105
|
+
# the gem. Most of this is from Hoe.
|
106
|
+
#------------------------------------------------------------------------------
|
107
|
+
namespace 'manifest' do
|
108
|
+
desc "Check the manifest"
|
109
|
+
task :check => :clean do
|
110
|
+
files = FileList["**/*", ".*"].exclude( This.exclude_from_manifest ).to_a.sort
|
111
|
+
files = files.select{ |f| File.file?( f ) }
|
112
|
+
|
113
|
+
tmp = "Manifest.tmp"
|
114
|
+
File.open( tmp, 'w' ) do |f|
|
115
|
+
f.puts files.join("\n")
|
116
|
+
end
|
117
|
+
|
118
|
+
begin
|
119
|
+
sh "diff -du Manifest.txt #{tmp}"
|
120
|
+
ensure
|
121
|
+
rm tmp
|
122
|
+
end
|
123
|
+
puts "Manifest looks good"
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "Generate the manifest"
|
127
|
+
task :generate => :clean do
|
128
|
+
files = %x[ git ls-files ].split("\n").sort
|
129
|
+
files.reject! { |f| f =~ This.exclude_from_manifest }
|
130
|
+
File.open( "Manifest.txt", "w" ) do |f|
|
131
|
+
f.puts files.join("\n")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#------------------------------------------------------------------------------
|
137
|
+
# Fixme - look for fixmes and report them
|
138
|
+
#------------------------------------------------------------------------------
|
139
|
+
namespace :fixme do
|
140
|
+
task :default => 'manifest:check' do
|
141
|
+
This.manifest.each do |file|
|
142
|
+
next if file == __FILE__
|
143
|
+
next unless file =~ %r/(txt|rb|md|rdoc|css|html|xml|css)\Z/
|
144
|
+
puts "FIXME: Rename #{file}" if file =~ /fixme/i
|
145
|
+
IO.readlines( file ).each_with_index do |line, idx|
|
146
|
+
prefix = "FIXME: #{file}:#{idx+1}".ljust(42)
|
147
|
+
puts "#{prefix} => #{line.strip}" if line =~ /fixme/i
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def fixme_project_root
|
153
|
+
This.project_path( '../fixme' )
|
154
|
+
end
|
155
|
+
|
156
|
+
def fixme_project_path( subtree )
|
157
|
+
fixme_project_root.join( subtree )
|
158
|
+
end
|
159
|
+
|
160
|
+
def local_fixme_files
|
161
|
+
This.manifest.select { |p| p =~ %r|^tasks/| }
|
162
|
+
end
|
163
|
+
|
164
|
+
def outdated_fixme_files
|
165
|
+
local_fixme_files.reject do |local|
|
166
|
+
upstream = fixme_project_path( local )
|
167
|
+
Digest::SHA256.file( local ) == Digest::SHA256.file( upstream )
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def fixme_up_to_date?
|
172
|
+
outdated_fixme_files.empty?
|
173
|
+
end
|
174
|
+
|
175
|
+
desc "See if the fixme tools are outdated"
|
176
|
+
task :outdated => :release_check do
|
177
|
+
if fixme_up_to_date? then
|
178
|
+
puts "Fixme files are up to date."
|
179
|
+
else
|
180
|
+
outdated_fixme_files.each do |f|
|
181
|
+
puts "#{f} is outdated"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
desc "Update outdated fixme files"
|
187
|
+
task :update => :release_check do
|
188
|
+
if fixme_up_to_date? then
|
189
|
+
puts "Fixme files are already up to date."
|
190
|
+
else
|
191
|
+
puts "Updating fixme files:"
|
192
|
+
outdated_fixme_files.each do |local|
|
193
|
+
upstream = fixme_project_path( local )
|
194
|
+
puts " * #{local}"
|
195
|
+
FileUtils.cp( upstream, local )
|
196
|
+
end
|
197
|
+
puts "Use your git commands as appropriate."
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
desc "Look for fixmes and report them"
|
202
|
+
task :fixme => "fixme:default"
|
203
|
+
|
204
|
+
#------------------------------------------------------------------------------
|
205
|
+
# Gem Specification
|
206
|
+
#------------------------------------------------------------------------------
|
207
|
+
# Really this is only here to support those who use bundler
|
208
|
+
desc "Build the #{This.name}.gemspec file"
|
209
|
+
task :gemspec do
|
210
|
+
File.open( This.gemspec_file, "wb+" ) do |f|
|
211
|
+
f.puts "# DO NOT EDIT - This file is automatically generated"
|
212
|
+
f.puts "# Make changes to Manifest.txt and/or Rakefile and regenerate"
|
213
|
+
f.write This.platform_gemspec.to_ruby
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# the gemspec is also a dev artifact and should not be kept around.
|
218
|
+
CLOBBER << This.gemspec_file.to_s
|
219
|
+
|
220
|
+
# .rbc files from ruby 2.0
|
221
|
+
CLOBBER << FileList["**/*.rbc"]
|
222
|
+
|
223
|
+
# The standard gem packaging task, everyone has it.
|
224
|
+
require 'rubygems/package_task'
|
225
|
+
::Gem::PackageTask.new( This.platform_gemspec ) do
|
226
|
+
# nothing
|
227
|
+
end
|
228
|
+
|
229
|
+
#------------------------------------------------------------------------------
|
230
|
+
# Release - the steps we go through to do a final release, this is pulled from
|
231
|
+
# a compbination of mojombo's rakegem, hoe and hoe-git
|
232
|
+
#
|
233
|
+
# 1) make sure we are on the master branch
|
234
|
+
# 2) make sure there are no uncommitted items
|
235
|
+
# 3) check the manifest and make sure all looks good
|
236
|
+
# 4) build the gem
|
237
|
+
# 5) do an empty commit to have the commit message of the version
|
238
|
+
# 6) tag that commit as the version
|
239
|
+
# 7) push master
|
240
|
+
# 8) push the tag
|
241
|
+
# 7) pus the gem
|
242
|
+
#------------------------------------------------------------------------------
|
243
|
+
task :release_check do
|
244
|
+
unless `git branch` =~ /^\* master$/
|
245
|
+
abort "You must be on the master branch to release!"
|
246
|
+
end
|
247
|
+
unless `git status` =~ /^nothing to commit/m
|
248
|
+
abort "Nope, sorry, you have unfinished business"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
desc "Create tag v#{This.version}, build and push #{This.platform_gemspec.full_name} to rubygems.org"
|
253
|
+
task :release => [ :release_check, 'manifest:check', :gem ] do
|
254
|
+
sh "git commit --allow-empty -a -m 'Release #{This.version}'"
|
255
|
+
sh "git tag -a -m 'v#{This.version}' v#{This.version}"
|
256
|
+
sh "git push origin master"
|
257
|
+
sh "git push origin v#{This.version}"
|
258
|
+
sh "gem push pkg/#{This.platform_gemspec.full_name}.gem"
|
259
|
+
end
|
data/tasks/this.rb
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
# Public: A Class containing all the metadata and utilities needed to manage a
|
4
|
+
# ruby project.
|
5
|
+
class ThisProject
|
6
|
+
# The name of this project
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
# The author's name
|
10
|
+
attr_accessor :author
|
11
|
+
|
12
|
+
# The email address of the author(s)
|
13
|
+
attr_accessor :email
|
14
|
+
|
15
|
+
# The homepage of this project
|
16
|
+
attr_accessor :homepage
|
17
|
+
|
18
|
+
# The regex of files to exclude from the manifest
|
19
|
+
attr_accessor :exclude_from_manifest
|
20
|
+
|
21
|
+
# The hash of Gem::Specifications keyed' by platform
|
22
|
+
attr_accessor :gemspecs
|
23
|
+
|
24
|
+
# Public: Initialize ThisProject
|
25
|
+
#
|
26
|
+
# Yields self
|
27
|
+
def initialize(&block)
|
28
|
+
@exclude_from_manifest = Regexp.union(/\.(git|DS_Store)/,
|
29
|
+
/^(doc|coverage|pkg|tmp|Gemfile(\.lock)?)/,
|
30
|
+
/^[^\/]+\.gemspec/,
|
31
|
+
/\.(swp|jar|bundle|so|rvmrc|travis.yml)$/,
|
32
|
+
/~$/)
|
33
|
+
@gemspecs = Hash.new
|
34
|
+
yield self if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: return the version of ThisProject
|
38
|
+
#
|
39
|
+
# Search the ruby files in the project looking for the one that has the
|
40
|
+
# version string in it. This does not eval any code in the project, it parses
|
41
|
+
# the source code looking for the string.
|
42
|
+
#
|
43
|
+
# Returns a String version
|
44
|
+
def version
|
45
|
+
[ "lib/#{ name }.rb", "lib/#{ name }/version.rb" ].each do |v|
|
46
|
+
path = project_path( v )
|
47
|
+
line = path.read[/^\s*VERSION\s*=\s*.*/]
|
48
|
+
if line then
|
49
|
+
return line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Internal: Return a section of an RDoc file with the given section name
|
55
|
+
#
|
56
|
+
# path - the relative path in the project of the file to parse
|
57
|
+
# section_name - the section out of the file from which to parse data
|
58
|
+
#
|
59
|
+
# Retuns the text of the section as an array of paragrphs.
|
60
|
+
def section_of( file, section_name )
|
61
|
+
re = /^[=#]+ (.*)$/
|
62
|
+
sectional = project_path( file )
|
63
|
+
parts = sectional.read.split( re )[1..-1]
|
64
|
+
parts.map! { |p| p.strip }
|
65
|
+
|
66
|
+
sections = Hash.new
|
67
|
+
Hash[*parts].each do |k,v|
|
68
|
+
sections[k] = v.split("\n\n")
|
69
|
+
end
|
70
|
+
return sections[section_name]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Internal: print out a warning about the give task
|
74
|
+
def task_warning( task )
|
75
|
+
warn "WARNING: '#{task}' tasks are not defined. Please run 'rake develop'"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Internal: Return the full path to the file that is relative to the project
|
79
|
+
# root.
|
80
|
+
#
|
81
|
+
# path - the relative path of the file from the project root
|
82
|
+
#
|
83
|
+
# Returns the Pathname of the file
|
84
|
+
def project_path( *relative_path )
|
85
|
+
project_root.join( *relative_path )
|
86
|
+
end
|
87
|
+
|
88
|
+
# Internal: The absolute path of this file
|
89
|
+
#
|
90
|
+
# Returns the Pathname of this file.
|
91
|
+
def this_file_path
|
92
|
+
Pathname.new( __FILE__ ).expand_path
|
93
|
+
end
|
94
|
+
|
95
|
+
# Internal: The root directory of this project
|
96
|
+
#
|
97
|
+
# This is defined as being the directory that is in the path of this project
|
98
|
+
# that has the first Rakefile
|
99
|
+
#
|
100
|
+
# Returns the Pathname of the directory
|
101
|
+
def project_root
|
102
|
+
this_file_path.ascend do |p|
|
103
|
+
rakefile = p.join( 'Rakefile' )
|
104
|
+
return p if rakefile.exist?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Internal: Returns the contents of the Manifest.txt file as an array
|
109
|
+
#
|
110
|
+
# Returns an Array of strings
|
111
|
+
def manifest
|
112
|
+
manifest_file = project_path( "Manifest.txt" )
|
113
|
+
abort "You need a Manifest.txt" unless manifest_file.readable?
|
114
|
+
manifest_file.readlines.map { |l| l.strip }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Internal: Return the files that define the extensions
|
118
|
+
#
|
119
|
+
# Returns an Array
|
120
|
+
def extension_conf_files
|
121
|
+
manifest.grep( /extconf.rb\Z/ )
|
122
|
+
end
|
123
|
+
|
124
|
+
# Internal: Returns the gemspace associated with the current ruby platform
|
125
|
+
def platform_gemspec
|
126
|
+
gemspecs[platform]
|
127
|
+
end
|
128
|
+
|
129
|
+
def core_gemspec
|
130
|
+
Gem::Specification.new do |spec|
|
131
|
+
spec.name = name
|
132
|
+
spec.version = version
|
133
|
+
spec.author = author
|
134
|
+
spec.email = email
|
135
|
+
spec.homepage = homepage
|
136
|
+
|
137
|
+
spec.summary = summary
|
138
|
+
spec.description = description
|
139
|
+
spec.license = license
|
140
|
+
|
141
|
+
spec.files = manifest
|
142
|
+
spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
|
143
|
+
spec.test_files = spec.files.grep(/^spec/)
|
144
|
+
|
145
|
+
spec.extra_rdoc_files += spec.files.grep(/(txt|rdoc|md)$/)
|
146
|
+
spec.rdoc_options = [ "--main" , 'README.md',
|
147
|
+
"--markup", "tomdoc" ]
|
148
|
+
|
149
|
+
spec.required_ruby_version = '~> 2.0'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Internal: Return the gemspec for the ruby platform
|
154
|
+
def ruby_gemspec( core = core_gemspec, &block )
|
155
|
+
yielding_gemspec( 'ruby', core, &block )
|
156
|
+
end
|
157
|
+
|
158
|
+
# Internal: Return the gemspec for the jruby platform
|
159
|
+
def java_gemspec( core = core_gemspec, &block )
|
160
|
+
yielding_gemspec( 'java', core, &block )
|
161
|
+
end
|
162
|
+
|
163
|
+
# Internal: give an initial spec and a key, create a new gemspec based off of
|
164
|
+
# it.
|
165
|
+
#
|
166
|
+
# This will force the new gemspecs 'platform' to be that of the key, since the
|
167
|
+
# only reason you would have multiple gemspecs at this point is to deal with
|
168
|
+
# different platforms.
|
169
|
+
def yielding_gemspec( key, core )
|
170
|
+
spec = gemspecs[key] ||= core.dup
|
171
|
+
spec.platform = key
|
172
|
+
yield spec if block_given?
|
173
|
+
return spec
|
174
|
+
end
|
175
|
+
|
176
|
+
# Internal: Return the platform of ThisProject at the current moment in time.
|
177
|
+
def platform
|
178
|
+
(RUBY_PLATFORM == "java") ? 'java' : Gem::Platform::RUBY
|
179
|
+
end
|
180
|
+
|
181
|
+
# Internal: Return the DESCRIPTION section of the README.rdoc file
|
182
|
+
def description_section
|
183
|
+
section_of( 'README.md', 'DESCRIPTION')
|
184
|
+
end
|
185
|
+
|
186
|
+
# Internal: Return the summary text from the README
|
187
|
+
def summary
|
188
|
+
description_section.first
|
189
|
+
end
|
190
|
+
|
191
|
+
# Internal: Return the full description text from the README
|
192
|
+
def description
|
193
|
+
description_section.join(" ").tr("\n", ' ').gsub(/[{}]/,'').gsub(/\[[^\]]+\]/,'') # strip rdoc
|
194
|
+
end
|
195
|
+
|
196
|
+
def license
|
197
|
+
"ISC"
|
198
|
+
end
|
199
|
+
|
200
|
+
# Internal: The path to the gemspec file
|
201
|
+
def gemspec_file
|
202
|
+
project_path( "#{ name }.gemspec" )
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
This = ThisProject.new
|
data/test/test_config.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
|
4
|
+
class TestConfig < ::Minitest::Test
|
5
|
+
def env
|
6
|
+
{ 'EV_TEST_1' => 'test-1',
|
7
|
+
'EV_TEST_2' => 'test-2' }
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@config = Envolve::Config.new( env: env )
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_access_key_as_method
|
15
|
+
assert_equal( 'test-1', @config.ev_test_1 )
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_respond_to
|
19
|
+
assert( @config.respond_to?( :ev_test_2 ) )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_size
|
23
|
+
assert( 2, @config.size )
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_keys
|
27
|
+
assert_equal( [ 'ev_test_1', 'ev_test_2'], @config.keys.sort )
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def test_access
|
32
|
+
assert_equal( 'test-2', @config['ev_test_2'] )
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_config_with_prefix
|
36
|
+
assert_equal( { 'test_1' => 'test-1', 'test_2' => 'test-2' }, @config.config_with_prefix( 'ev' ).to_h )
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_symbolized_h
|
40
|
+
assert_equal( { test_1: 'test-1', test_2: 'test-2' }, @config.config_with_prefix( 'ev' ).to_symbolized_hash )
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
|
4
|
+
class TestFilteredConfig < ::Minitest::Test
|
5
|
+
def env
|
6
|
+
{ 'EV_X_TEST_1' => 'test-1',
|
7
|
+
'EV_X_TEST_2' => 'test-2',
|
8
|
+
'EV_TEST_3' => 'test-3',
|
9
|
+
'EV_TEST_4' => 'test-4' }
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@config = Envolve::Config.new( env: env, prefix: 'ev_x' )
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_access_key_as_method
|
17
|
+
assert_equal( 'test-1', @config.test_1 )
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_respond_to
|
21
|
+
assert( @config.respond_to?( :test_2 ) )
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_size
|
25
|
+
assert( 2, @config.size )
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_keys
|
29
|
+
assert_equal( [ 'test_1', 'test_2'], @config.keys.sort )
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def test_access
|
34
|
+
assert_equal( 'test-2', @config['test_2'] )
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
require 'test_config'
|
4
|
+
|
5
|
+
class KeySeparatorConfig < Envolve::Config
|
6
|
+
environment_source {
|
7
|
+
{ 'EV-TEST-1' => 'test-1', 'EV-TEST-2' => 'test-2' }
|
8
|
+
}
|
9
|
+
key_separator '-'
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestKeySeparatorConfig < ::TestConfig
|
13
|
+
def setup
|
14
|
+
@config = LambdaConfig.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
require 'test_config'
|
4
|
+
|
5
|
+
class LambdaConfig < Envolve::Config
|
6
|
+
environment_source {
|
7
|
+
{ 'EV_TEST_1' => 'test-1', 'EV_TEST_2' => 'test-2' }
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
class TestMetaConfig < ::TestConfig
|
12
|
+
def setup
|
13
|
+
@config = LambdaConfig.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
require 'test_filtered_config'
|
4
|
+
|
5
|
+
class PrefixConfig < Envolve::Config
|
6
|
+
def self.env
|
7
|
+
{ 'EV_X_TEST_1' => 'test-1',
|
8
|
+
'EV_X_TEST_2' => 'test-2',
|
9
|
+
'EV_TEST_3' => 'test-3',
|
10
|
+
'EV_TEST_4' => 'test-4' }
|
11
|
+
end
|
12
|
+
|
13
|
+
environment_source( env )
|
14
|
+
prefix 'ev_x'
|
15
|
+
end
|
16
|
+
class TestPrefixConfig < TestFilteredConfig
|
17
|
+
def setup
|
18
|
+
@config = PrefixConfig.new
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/config'
|
3
|
+
|
4
|
+
class PropertyConfig < ::Envolve::Config
|
5
|
+
environment_source {
|
6
|
+
{
|
7
|
+
'EV_TEST_1' => 'test-1',
|
8
|
+
'EV_TEST_2' => 'test-2',
|
9
|
+
'EV_FOO' => 'test-bar',
|
10
|
+
'EV_WIBBLE' => 'wobble',
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
prefix 'ev'
|
15
|
+
|
16
|
+
property 'bar', :key => 'foo'
|
17
|
+
property 'wibble', :value => lambda { |val| val.gsub('o', 'ee') }
|
18
|
+
property 'ara', :default => 42, :value => lambda { |val| Integer(val) }
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestPropertyConfig < ::Minitest::Test
|
23
|
+
def setup
|
24
|
+
@config = PropertyConfig.new
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def test_access_key_as_method
|
29
|
+
assert_equal( 'test-1', @config.test_1 )
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_respond_to
|
33
|
+
assert( @config.respond_to?( :test_2 ) )
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_size
|
37
|
+
assert( 4, @config.size )
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_keys
|
41
|
+
keys = %w[ test_1 test_2 bar wibble ara].sort
|
42
|
+
assert_equal( keys, @config.keys.sort )
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_access
|
46
|
+
assert_equal( 'weebble', @config['wibble'] )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_defaults
|
50
|
+
assert_equal( 42, @config['ara'] )
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'envolve/version'
|
3
|
+
|
4
|
+
class TestVersion < ::Minitest::Test
|
5
|
+
def test_version_constant_match
|
6
|
+
assert_match(/\A\d+\.\d+\.\d+\Z/, Envolve::VERSION)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_version_string_match
|
10
|
+
assert_match(/\A\d+\.\d+\.\d+\Z/, Envolve::VERSION.to_s)
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: envolve
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Hinegardner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.9'
|
69
|
+
description: Envolve provides a consistent and validating way to access your application
|
70
|
+
configuration that is set via environment variables. This is double beneficial if
|
71
|
+
you are configuring your entire application with environment variables. See. http://12factor.net/config
|
72
|
+
email: jeremy@copiousfreetime.org
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files:
|
76
|
+
- CONTRIBUTING.md
|
77
|
+
- HISTORY.md
|
78
|
+
- Manifest.txt
|
79
|
+
- README.md
|
80
|
+
files:
|
81
|
+
- CONTRIBUTING.md
|
82
|
+
- HISTORY.md
|
83
|
+
- LICENSE
|
84
|
+
- Manifest.txt
|
85
|
+
- README.md
|
86
|
+
- Rakefile
|
87
|
+
- lib/envolve.rb
|
88
|
+
- lib/envolve/config.rb
|
89
|
+
- lib/envolve/version.rb
|
90
|
+
- tasks/default.rake
|
91
|
+
- tasks/this.rb
|
92
|
+
- test/test_config.rb
|
93
|
+
- test/test_filtered_config.rb
|
94
|
+
- test/test_helper.rb
|
95
|
+
- test/test_key_separator_config.rb
|
96
|
+
- test/test_meta_config.rb
|
97
|
+
- test/test_prefix_config.rb
|
98
|
+
- test/test_property_config.rb
|
99
|
+
- test/test_version.rb
|
100
|
+
homepage: http://github.com/copiousfreetime/envolve
|
101
|
+
licenses:
|
102
|
+
- ISC
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options:
|
106
|
+
- "--main"
|
107
|
+
- README.md
|
108
|
+
- "--markup"
|
109
|
+
- tomdoc
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '2.0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.2.2
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Envolve provides a consistent and validating way to access your application
|
128
|
+
configuration that is set via environment variables.
|
129
|
+
test_files: []
|