config_module 0.0.3 → 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.
- checksums.yaml +7 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/config_module.gemspec +3 -0
- data/lib/config_module.rb +15 -48
- data/lib/config_module/config_helper.rb +40 -0
- data/lib/config_module/config_option.rb +41 -0
- data/lib/config_module/exceptions.rb +21 -0
- data/lib/config_module/version.rb +1 -1
- data/spec/config/example.yml +6 -0
- data/{test → spec}/config/false_nil.yml +0 -0
- data/spec/config_helper_spec.rb +16 -0
- data/{test/test.rb → spec/config_module_spec.rb} +20 -12
- data/{test → spec}/example_config.rb +0 -0
- data/spec/namespace_spec.rb +23 -0
- data/spec/spec_helper.rb +10 -0
- metadata +53 -20
- data/test/config/example.yml +0 -6
- data/test/mutest.rb +0 -112
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4ff9be2b58fa4690a4341b05c51578ca4066810c
|
4
|
+
data.tar.gz: 0c6aeb9814bf45f447b86091c869804954909a3b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9308b74b9f72f8c1f58384cb6063ed8736349628b5e30d338fa7f42290f5aabfc2e87e0b76f1c9b8ca1c2685d9bff2c13525d93db915cffd6639d5560e0e159a
|
7
|
+
data.tar.gz: 083a6b61d0e40931f2335ef76b02db1e07bbca73cb8523f0667247f1650b0938fb0dae2a00669c80a39f1577200f80bc56d74c733165ae554d5466469395d26f
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create ruby-2.0.0-p0@config_module
|
data/Gemfile
CHANGED
data/config_module.gemspec
CHANGED
@@ -16,4 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'pry'
|
21
|
+
gem.add_development_dependency 'pry-theme'
|
19
22
|
end
|
data/lib/config_module.rb
CHANGED
@@ -1,71 +1,38 @@
|
|
1
|
-
require_relative 'config_module/version'
|
2
1
|
require 'ostruct'
|
3
2
|
require 'yaml'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require_relative 'config_module/version'
|
6
|
+
require_relative 'config_module/exceptions'
|
7
|
+
require_relative 'config_module/config_option'
|
8
|
+
require_relative 'config_module/config_helper'
|
4
9
|
|
5
10
|
module ConfigModule
|
6
11
|
def [] key
|
7
|
-
config.send key
|
12
|
+
__config_module_helper.config.send key
|
8
13
|
end
|
9
14
|
|
10
15
|
def config
|
11
|
-
|
16
|
+
__config_module_helper.config
|
12
17
|
end
|
13
18
|
|
14
19
|
protected
|
15
20
|
|
16
|
-
def config_file
|
17
|
-
|
21
|
+
def config_file new_config_file
|
22
|
+
__config_module_helper.config_file = new_config_file
|
18
23
|
end
|
19
24
|
|
20
|
-
def namespace *
|
21
|
-
|
25
|
+
def namespace *new_namespace
|
26
|
+
__config_module_helper.namespaces = *new_namespace
|
22
27
|
end
|
23
28
|
|
24
29
|
private
|
25
30
|
|
26
|
-
def
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
def load_config
|
31
|
-
file = YAML.load_file(@config_file)
|
32
|
-
|
33
|
-
if namespaced? then
|
34
|
-
@namespace.inject(file) do |file, ns|
|
35
|
-
file.include?(ns) && file[ns] || file.include?(ns.to_sym) && file[ns.to_sym]
|
36
|
-
end
|
37
|
-
else
|
38
|
-
file
|
39
|
-
end
|
31
|
+
def __config_module_helper
|
32
|
+
@__config_module_helper ||= ConfigHelper.new
|
40
33
|
end
|
41
34
|
|
42
35
|
def method_missing name
|
43
|
-
|
44
|
-
rescue NoMethodError => error
|
45
|
-
if error.name == name then
|
46
|
-
raise NoMethodError, "undefined method `#{name}' for #{self}", caller(1)
|
47
|
-
else
|
48
|
-
raise
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class ConfigOption < OpenStruct
|
53
|
-
def self.wrap data
|
54
|
-
if data.is_a? Hash then
|
55
|
-
ConfigOption.new data
|
56
|
-
else
|
57
|
-
data
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def get name
|
62
|
-
if @table.include? name then
|
63
|
-
self.class.wrap @table[name]
|
64
|
-
else
|
65
|
-
raise ConfigOption::NotFound
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class NotFound < RangeError; end
|
36
|
+
__config_module_helper.method_missing_handler name, caller(1)
|
70
37
|
end
|
71
38
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ConfigModule
|
2
|
+
class ConfigHelper
|
3
|
+
attr :raw_config
|
4
|
+
attr_accessor :config_file, :namespaces
|
5
|
+
|
6
|
+
def config
|
7
|
+
@config ||= ConfigOption.wrap load_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing_handler name, source
|
11
|
+
config.send name
|
12
|
+
rescue NoMethodError => error
|
13
|
+
if error.name == name then
|
14
|
+
raise # ConfigOption::NotFoundError.new(name, source)#, source
|
15
|
+
else
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_config
|
21
|
+
@raw_config = YAML.load_file config_file
|
22
|
+
|
23
|
+
load_namespaces_from raw_config
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_namespaces_from tree
|
27
|
+
return tree unless namespaced?
|
28
|
+
|
29
|
+
Array(namespaces).inject(ConfigOption.wrap tree) do |subtree, ns|
|
30
|
+
raise(InvalidNamespaceError.new(ns, subtree)) unless subtree.respond_to? ns
|
31
|
+
|
32
|
+
subtree.send ns
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def namespaced?
|
37
|
+
!(namespaces.nil? || namespaces.empty?)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ConfigModule
|
2
|
+
class ConfigOption < OpenStruct
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def self.wrap data
|
6
|
+
if data.is_a? Hash then
|
7
|
+
ConfigOption.new data
|
8
|
+
else
|
9
|
+
data
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def each
|
14
|
+
return to_enum __method__ unless block_given?
|
15
|
+
@table.each_pair{|p| yield p}
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing name, *args, &block
|
19
|
+
result = super
|
20
|
+
|
21
|
+
if result || @table.include?(name) then
|
22
|
+
self.class.wrap result
|
23
|
+
else
|
24
|
+
raise ConfigOption::NotFoundError.new name, self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def new_ostruct_member name
|
29
|
+
name = name.to_sym
|
30
|
+
unless respond_to? name
|
31
|
+
define_singleton_method(name) { self.class.wrap @table[name] }
|
32
|
+
define_singleton_method("#{name}=") { |x| modifiable[name] = x }
|
33
|
+
end
|
34
|
+
name
|
35
|
+
end
|
36
|
+
|
37
|
+
class NotFoundError < ::ConfigModule::ConfigError
|
38
|
+
def identifier; :key; end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ConfigModule
|
2
|
+
class ConfigError < NoMethodError
|
3
|
+
def initialize name, object
|
4
|
+
@name, @object = name, object
|
5
|
+
super "invalid #{identifier} `#{name}' for #{object_info}"
|
6
|
+
end
|
7
|
+
attr :name, :object
|
8
|
+
|
9
|
+
def object_info
|
10
|
+
if object.is_a?(Class) then
|
11
|
+
object.name
|
12
|
+
else
|
13
|
+
"instance of `#{object.class} < #{object.class.superclass}'"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class InvalidNamespaceError < ConfigError
|
19
|
+
def identifier; :namespace; end
|
20
|
+
end
|
21
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
hash = {a: {b: 5}}
|
4
|
+
opt = ConfigModule::ConfigOption.new hash
|
5
|
+
|
6
|
+
spec 'ConfigOptions are Enumerable' do
|
7
|
+
opt.map{|k,v| v[:b]} == [5]
|
8
|
+
end
|
9
|
+
|
10
|
+
spec 'to_ary' do
|
11
|
+
begin
|
12
|
+
opt.to_ary
|
13
|
+
rescue NoMethodError => error
|
14
|
+
error.class == ConfigModule::ConfigOption::NotFoundError
|
15
|
+
end
|
16
|
+
end
|
@@ -1,12 +1,6 @@
|
|
1
|
-
require_relative '
|
2
|
-
extend Mutest
|
3
|
-
|
4
|
-
require_relative '../lib/config_module'
|
5
|
-
module Rails; def self.env; 'production'; end; end
|
1
|
+
require_relative 'spec_helper'
|
6
2
|
require_relative 'example_config'
|
7
3
|
|
8
|
-
Dir.chdir File.dirname(__FILE__)
|
9
|
-
|
10
4
|
spec 'modules extended with ConfigModule will load configurations' do
|
11
5
|
ExampleConfig.foo == 'bar'
|
12
6
|
end
|
@@ -15,12 +9,12 @@ spec 'modules extended with ConfigModule have "namespace" methods' do
|
|
15
9
|
ExampleConfig.methods.include? :namespace
|
16
10
|
end
|
17
11
|
|
18
|
-
spec '
|
19
|
-
ExampleConfig.
|
12
|
+
spec 'config modules have [] methods' do
|
13
|
+
ExampleConfig.respond_to? :[]
|
20
14
|
end
|
21
15
|
|
22
|
-
spec '
|
23
|
-
ExampleConfig
|
16
|
+
spec 'nested hash values are properly wrapped' do
|
17
|
+
ExampleConfig.dictionary.class == ConfigModule::ConfigOption
|
24
18
|
end
|
25
19
|
|
26
20
|
spec 'subkeys are accessible with methods' do
|
@@ -43,7 +37,7 @@ end
|
|
43
37
|
spec 'missing keys raise exception when called as methods' do
|
44
38
|
begin
|
45
39
|
FalseNil.nonexistant
|
46
|
-
rescue ConfigModule::ConfigOption::
|
40
|
+
rescue ConfigModule::ConfigOption::NotFoundError
|
47
41
|
true
|
48
42
|
end
|
49
43
|
end
|
@@ -57,3 +51,17 @@ end
|
|
57
51
|
spec 'multiple namespaces can be set' do
|
58
52
|
MultipleExample.configuration == ExampleConfig.dictionary.configuration
|
59
53
|
end
|
54
|
+
|
55
|
+
module InvalidNamespaceExample
|
56
|
+
extend ConfigModule
|
57
|
+
config_file './config/example.yml'
|
58
|
+
namespace :jimmy, :pop, :ali
|
59
|
+
end
|
60
|
+
|
61
|
+
spec 'incorrect namespaces raise informative errors' do
|
62
|
+
begin
|
63
|
+
InvalidNamespaceExample.whatever
|
64
|
+
rescue => error
|
65
|
+
error.class == ConfigModule::InvalidNamespaceError
|
66
|
+
end
|
67
|
+
end
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
def self.helper
|
4
|
+
if @helper then @helper
|
5
|
+
else
|
6
|
+
@helper = ConfigModule::ConfigHelper.new
|
7
|
+
@helper.config_file = './config/example.yml'
|
8
|
+
@helper.namespaces = 'production'
|
9
|
+
@helper.config
|
10
|
+
@helper
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
table = helper.load_config.instance_variable_get(:@table)
|
15
|
+
|
16
|
+
spec 'namespaces obtain subtrees of the full config' do
|
17
|
+
table.keys == [:foo, :noodle, :dictionary]
|
18
|
+
end
|
19
|
+
|
20
|
+
spec 'specifying a namespace forces #config to return that subtree the first time its called' do
|
21
|
+
symbolized_keys_from_full_config = helper.raw_config['production'].keys.map(&:to_sym)
|
22
|
+
symbolized_keys_from_full_config == table.keys
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: config_module
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Anthony Cook
|
@@ -10,7 +9,35 @@ autorequire:
|
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
11
|
date: 2013-02-27 00:00:00.000000000 Z
|
13
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-theme
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
14
41
|
description: Wrap a configuration file in a module for easy use throughout your application.
|
15
42
|
Inspired by Rails.
|
16
43
|
email:
|
@@ -20,45 +47,51 @@ extensions: []
|
|
20
47
|
extra_rdoc_files: []
|
21
48
|
files:
|
22
49
|
- .gitignore
|
50
|
+
- .rvmrc
|
23
51
|
- Gemfile
|
24
52
|
- README.markdown
|
25
53
|
- Rakefile
|
26
54
|
- config_module.gemspec
|
27
55
|
- lib/config_module.rb
|
56
|
+
- lib/config_module/config_helper.rb
|
57
|
+
- lib/config_module/config_option.rb
|
58
|
+
- lib/config_module/exceptions.rb
|
28
59
|
- lib/config_module/version.rb
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
60
|
+
- spec/config/example.yml
|
61
|
+
- spec/config/false_nil.yml
|
62
|
+
- spec/config_helper_spec.rb
|
63
|
+
- spec/config_module_spec.rb
|
64
|
+
- spec/example_config.rb
|
65
|
+
- spec/namespace_spec.rb
|
66
|
+
- spec/spec_helper.rb
|
34
67
|
homepage: http://github.com/acook/config_module
|
35
68
|
licenses: []
|
69
|
+
metadata: {}
|
36
70
|
post_install_message:
|
37
71
|
rdoc_options: []
|
38
72
|
require_paths:
|
39
73
|
- lib
|
40
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
75
|
requirements:
|
43
|
-
- -
|
76
|
+
- - '>='
|
44
77
|
- !ruby/object:Gem::Version
|
45
78
|
version: '0'
|
46
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
-
none: false
|
48
80
|
requirements:
|
49
|
-
- -
|
81
|
+
- - '>='
|
50
82
|
- !ruby/object:Gem::Version
|
51
83
|
version: '0'
|
52
84
|
requirements: []
|
53
85
|
rubyforge_project:
|
54
|
-
rubygems_version:
|
86
|
+
rubygems_version: 2.0.0
|
55
87
|
signing_key:
|
56
|
-
specification_version:
|
88
|
+
specification_version: 4
|
57
89
|
summary: Load important configuration files into their own modules!
|
58
90
|
test_files:
|
59
|
-
-
|
60
|
-
-
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
64
|
-
|
91
|
+
- spec/config/example.yml
|
92
|
+
- spec/config/false_nil.yml
|
93
|
+
- spec/config_helper_spec.rb
|
94
|
+
- spec/config_module_spec.rb
|
95
|
+
- spec/example_config.rb
|
96
|
+
- spec/namespace_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
data/test/config/example.yml
DELETED
data/test/mutest.rb
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
module Mutest
|
2
|
-
def spec description
|
3
|
-
print ' -- ', description
|
4
|
-
|
5
|
-
return puts(': ' + yellow('pending') + vspace) unless block_given?
|
6
|
-
|
7
|
-
begin
|
8
|
-
result = yield
|
9
|
-
rescue => result
|
10
|
-
end
|
11
|
-
|
12
|
-
print ': ', colorize(result, caller), "\n"
|
13
|
-
end
|
14
|
-
|
15
|
-
module Color
|
16
|
-
|
17
|
-
def colors
|
18
|
-
{
|
19
|
-
red: 1,
|
20
|
-
green: 2,
|
21
|
-
yellow: 3,
|
22
|
-
white: 7
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
def color hue, text = nil
|
27
|
-
esc("3#{colors[hue]};1") + "#{text}#{normal if text}"
|
28
|
-
end
|
29
|
-
|
30
|
-
def esc seq
|
31
|
-
"\e[#{seq}m"
|
32
|
-
end
|
33
|
-
|
34
|
-
def normal text=nil
|
35
|
-
esc(0) + text.to_s
|
36
|
-
end
|
37
|
-
|
38
|
-
def colorize result, source
|
39
|
-
if result == true then
|
40
|
-
green result
|
41
|
-
elsif result == false then
|
42
|
-
red result
|
43
|
-
elsif result.is_a? Exception then
|
44
|
-
[
|
45
|
-
red('Exception'), vspace,
|
46
|
-
hspace, 'Spec encountered an Exception ', newline,
|
47
|
-
hspace, 'in spec at ', source.first, vspace,
|
48
|
-
hspace, message(result), vspace,
|
49
|
-
white(trace result)
|
50
|
-
].join
|
51
|
-
else
|
52
|
-
[
|
53
|
-
red('Unknown Result'), vspace,
|
54
|
-
hspace, 'Spec did not return a boolean value ', newline,
|
55
|
-
hspace, 'in spec at ', source.first, vspace,
|
56
|
-
hspace, red(classinfo(result)), result.inspect, newline
|
57
|
-
].join
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def trace error
|
62
|
-
error.backtrace.inject(String.new) do |text, line|
|
63
|
-
text << hspace + line + newline
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def message error
|
68
|
-
red(classinfo error) + error.message
|
69
|
-
end
|
70
|
-
|
71
|
-
def classinfo object
|
72
|
-
"#{classify object} < #{superclass object}: "
|
73
|
-
end
|
74
|
-
|
75
|
-
def classify object
|
76
|
-
object.is_a?(Module) ? object : object.class
|
77
|
-
end
|
78
|
-
|
79
|
-
def superclass object
|
80
|
-
classify(object).superclass
|
81
|
-
end
|
82
|
-
|
83
|
-
def hspace
|
84
|
-
' '
|
85
|
-
end
|
86
|
-
|
87
|
-
def vspace
|
88
|
-
newline + newline
|
89
|
-
end
|
90
|
-
|
91
|
-
def newline
|
92
|
-
$/
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def method_missing name, *args, &block
|
98
|
-
if colors.keys.include? name then
|
99
|
-
color name, *args
|
100
|
-
else
|
101
|
-
super
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
include Color
|
110
|
-
end
|
111
|
-
|
112
|
-
|