dead_simple_conf 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.
- data/.gitignore +5 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/Guardfile +12 -0
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/Rakefile +13 -0
- data/dead_simple_conf.gemspec +28 -0
- data/examples/conf.yml +11 -0
- data/examples/test.rb +43 -0
- data/lib/dead_simple_conf.rb +36 -0
- data/lib/dead_simple_conf/version.rb +3 -0
- data/specs/common.rb +15 -0
- data/specs/lib/dead_simple_conf_spec.rb +96 -0
- metadata +137 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
|
5
|
+
# parameters:
|
6
|
+
# output => the formatted to use
|
7
|
+
# backtrace => number of lines, nil = everything
|
8
|
+
guard 'bacon', :output => "BetterOutput", :backtrace => 4 do
|
9
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "specs/lib/#{m[1]}_spec.rb" }
|
10
|
+
watch(%r{specs/.+\.rb$})
|
11
|
+
end
|
12
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Julien Ammous
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
|
2
|
+
This is my own implementation of a REALLY simple configuration library, and
|
3
|
+
when I say simple I mean it ! Most of the library available out there are far
|
4
|
+
too complicated.
|
5
|
+
|
6
|
+
I decided to extract this code in a proper gem when I got tired of copying it over
|
7
|
+
and over in my projects.
|
8
|
+
|
9
|
+
# What this gem provides
|
10
|
+
|
11
|
+
My requirements for a config parser are:
|
12
|
+
|
13
|
+
- check that each line typed in the yaml file match a valid parameter
|
14
|
+
I spent far too much time debugging application loading just because
|
15
|
+
activerecord or any other gem did not warned me that a key was unknown
|
16
|
+
(like "size" instead of "pool_size", you get the idea).
|
17
|
+
What I expect is to have some return, taise an error, throw me a brick, do something damn !
|
18
|
+
|
19
|
+
- have a useable syntax to read the values
|
20
|
+
- something minimal which can be extended as needed (look at the source
|
21
|
+
to really figure out how small this library is, there may even be more text
|
22
|
+
in this README ! )
|
23
|
+
|
24
|
+
And honestly that's all, I don't want or need 100 different allowed formats
|
25
|
+
with complex cases handled, so now that we are clear let's see how this
|
26
|
+
thing works.
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
# How it works
|
31
|
+
|
32
|
+
You have this yaml file:
|
33
|
+
|
34
|
+
```yaml
|
35
|
+
|
36
|
+
logger:
|
37
|
+
level: debug
|
38
|
+
output: /tmp/file.log
|
39
|
+
|
40
|
+
app:
|
41
|
+
data_path: /tmp
|
42
|
+
|
43
|
+
server:
|
44
|
+
port: 9000
|
45
|
+
address: 127.0.0.1
|
46
|
+
```
|
47
|
+
|
48
|
+
Here is how you would use it:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
require 'bundler/setup'
|
52
|
+
require 'dead_simple_conf'
|
53
|
+
|
54
|
+
module ConfigLoader
|
55
|
+
class ServerConfig < DeadSimpleConf::ConfigBlock
|
56
|
+
attr_accessor :port, :address
|
57
|
+
end
|
58
|
+
|
59
|
+
class AppConfig < DeadSimpleConf::ConfigBlock
|
60
|
+
attr_accessor :data_path
|
61
|
+
sub_section :server, ServerConfig
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class LoggerConfig < DeadSimpleConf::ConfigBlock
|
66
|
+
attr_accessor :level, :output
|
67
|
+
end
|
68
|
+
|
69
|
+
class MyConfig < DeadSimpleConf::ConfigBlock
|
70
|
+
sub_section :app, AppConfig
|
71
|
+
sub_section :logger, LoggerConfig
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.load(path)
|
75
|
+
raw_data = YAML.load_file(path)
|
76
|
+
MyConfig.new(raw_data)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
conf = ConfigLoader.load("conf.yml")
|
81
|
+
puts "conf.app.data_path : #{conf.app.data_path}"
|
82
|
+
puts "conf.app.server.port : #{conf.app.server.port}"
|
83
|
+
|
84
|
+
```
|
85
|
+
|
86
|
+
You can see both files in the examples folder.
|
87
|
+
|
88
|
+
|
89
|
+
# Extending it
|
90
|
+
|
91
|
+
Since I am only using standard class with getter and setters you should be able to extend it
|
92
|
+
without much trouble, one one the thing which comes in mind is to use activemodel validation
|
93
|
+
to validate incoming entries.
|
94
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dead_simple_conf/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dead_simple_conf"
|
7
|
+
s.version = DeadSimpleConf::VERSION
|
8
|
+
s.authors = ["Julien Ammous"]
|
9
|
+
s.email = []
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Config loader}
|
12
|
+
s.description = %q{YAML Config loader}
|
13
|
+
|
14
|
+
s.rubyforge_project = "dead_simple_conf"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- specs/*`.split("\n")
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency 'schmurfy-bacon', '~> 1.2'
|
21
|
+
s.add_development_dependency 'guard-bacon', '~> 1.0.2'
|
22
|
+
s.add_development_dependency "growl", '~> 1.0.3'
|
23
|
+
s.add_development_dependency "rb-fsevent", '~> 0.4.3'
|
24
|
+
s.add_development_dependency "mocha", '~> 0.10.0'
|
25
|
+
s.add_development_dependency "simplecov", '~> 0.5.3'
|
26
|
+
s.add_development_dependency "rake", '~> 0.9.2'
|
27
|
+
|
28
|
+
end
|
data/examples/conf.yml
ADDED
data/examples/test.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'dead_simple_conf'
|
3
|
+
|
4
|
+
# logger:
|
5
|
+
# level: debug
|
6
|
+
# output: /tmp/file.log
|
7
|
+
#
|
8
|
+
# app:
|
9
|
+
# data_path: /tmp
|
10
|
+
#
|
11
|
+
# server:
|
12
|
+
# port: 9000
|
13
|
+
# address: 127.0.0.1
|
14
|
+
|
15
|
+
module ConfigLoader
|
16
|
+
class ServerConfig < DeadSimpleConf::ConfigBlock
|
17
|
+
attr_accessor :port, :address
|
18
|
+
end
|
19
|
+
|
20
|
+
class AppConfig < DeadSimpleConf::ConfigBlock
|
21
|
+
attr_accessor :data_path
|
22
|
+
sub_section :server, ServerConfig
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class LoggerConfig < DeadSimpleConf::ConfigBlock
|
27
|
+
attr_accessor :level, :output
|
28
|
+
end
|
29
|
+
|
30
|
+
class MyConfig < DeadSimpleConf::ConfigBlock
|
31
|
+
sub_section :app, AppConfig
|
32
|
+
sub_section :logger, LoggerConfig
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.load(path)
|
36
|
+
raw_data = YAML.load_file(path)
|
37
|
+
MyConfig.new(raw_data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
conf = ConfigLoader.load("conf.yml")
|
42
|
+
puts "conf.app.data_path : #{conf.app.data_path}"
|
43
|
+
puts "conf.app.server.port : #{conf.app.server.port}"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "dead_simple_conf/version"
|
2
|
+
|
3
|
+
module DeadSimpleConf
|
4
|
+
|
5
|
+
class ConfigBlock
|
6
|
+
|
7
|
+
def self.sub_section(name, klass)
|
8
|
+
attr_reader(name)
|
9
|
+
|
10
|
+
define_method("#{name}=") do |h|
|
11
|
+
instance_variable_set("@#{name}", klass.new(h))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(attributes)
|
16
|
+
_load_data(attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def _load_data(attributes)
|
20
|
+
unknown = attributes.reject do |key, value|
|
21
|
+
if respond_to?("#{key}=")
|
22
|
+
send("#{key}=", value)
|
23
|
+
true
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
unless unknown.empty?
|
30
|
+
fail "unknown parameter(s) in config block #{self.class}: #{unknown.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/specs/common.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
if ENV['COVERAGE'] && (RUBY_VERSION >= "1.9")
|
5
|
+
require 'simplecov'
|
6
|
+
SimpleCov.start do
|
7
|
+
root File.expand_path('../..', __FILE__)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'mocha'
|
12
|
+
require 'bacon'
|
13
|
+
|
14
|
+
require 'dead_simple_conf'
|
15
|
+
Bacon.summary_at_exit()
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.expand_path('../../common', __FILE__)
|
2
|
+
|
3
|
+
describe 'DeadSimpleConf' do
|
4
|
+
|
5
|
+
describe 'one level config' do
|
6
|
+
before do
|
7
|
+
@conf_data = YAML.load(%{
|
8
|
+
login: user_login
|
9
|
+
path: /tmp
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'raise an error on unknown parameter' do
|
14
|
+
parser_module = Module.new do
|
15
|
+
class MainBlock < DeadSimpleConf::ConfigBlock
|
16
|
+
attr_accessor :login
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.load(data)
|
20
|
+
MainBlock.new(data)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
proc {
|
25
|
+
result = parser_module.load(@conf_data)
|
26
|
+
}.should.raise(RuntimeError)
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'parse successfully known parameter' do
|
31
|
+
parser_module = Module.new do
|
32
|
+
class MainBlock < DeadSimpleConf::ConfigBlock
|
33
|
+
attr_accessor :login, :path
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.load(data)
|
37
|
+
MainBlock.new(data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
result = parser_module.load(@conf_data)
|
42
|
+
result.login.should == "user_login"
|
43
|
+
result.path.should == "/tmp"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'multi level config' do
|
48
|
+
before do
|
49
|
+
@conf_data = YAML.load(%{
|
50
|
+
login: user_login
|
51
|
+
path: /tmp
|
52
|
+
|
53
|
+
server:
|
54
|
+
address: 127.0.0.1
|
55
|
+
port: 5000
|
56
|
+
|
57
|
+
another_section:
|
58
|
+
name: out_of_ideas
|
59
|
+
})
|
60
|
+
end
|
61
|
+
|
62
|
+
should 'parse it with correct loader' do
|
63
|
+
parser_module = Module.new do
|
64
|
+
class AnotherSectionBlock < DeadSimpleConf::ConfigBlock
|
65
|
+
attr_accessor :name
|
66
|
+
end
|
67
|
+
|
68
|
+
class ServerBlock < DeadSimpleConf::ConfigBlock
|
69
|
+
attr_accessor :address, :port
|
70
|
+
sub_section :another_section, AnotherSectionBlock
|
71
|
+
end
|
72
|
+
|
73
|
+
class MainBlock < DeadSimpleConf::ConfigBlock
|
74
|
+
attr_accessor :login, :path
|
75
|
+
sub_section :server, ServerBlock
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.load(data)
|
79
|
+
MainBlock.new(data)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
result = parser_module.load(@conf_data)
|
84
|
+
result.login.should == "user_login"
|
85
|
+
result.path.should == "/tmp"
|
86
|
+
|
87
|
+
result.server.address.should == "127.0.0.1"
|
88
|
+
result.server.port.should == 5000
|
89
|
+
|
90
|
+
result.server.another_section.name.should == "out_of_ideas"
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dead_simple_conf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Julien Ammous
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-08 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: schmurfy-bacon
|
16
|
+
requirement: &70347746200320 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.2'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70347746200320
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: guard-bacon
|
27
|
+
requirement: &70347746199760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.2
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70347746199760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: growl
|
38
|
+
requirement: &70347746198860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.3
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70347746198860
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rb-fsevent
|
49
|
+
requirement: &70347746197820 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.3
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70347746197820
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mocha
|
60
|
+
requirement: &70347746196760 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.10.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70347746196760
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: &70347746195140 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.5.3
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70347746195140
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rake
|
82
|
+
requirement: &70347746194040 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.2
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70347746194040
|
91
|
+
description: YAML Config loader
|
92
|
+
email: []
|
93
|
+
executables: []
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- .gitignore
|
98
|
+
- .travis.yml
|
99
|
+
- Gemfile
|
100
|
+
- Guardfile
|
101
|
+
- LICENSE
|
102
|
+
- README.md
|
103
|
+
- Rakefile
|
104
|
+
- dead_simple_conf.gemspec
|
105
|
+
- examples/conf.yml
|
106
|
+
- examples/test.rb
|
107
|
+
- lib/dead_simple_conf.rb
|
108
|
+
- lib/dead_simple_conf/version.rb
|
109
|
+
- specs/common.rb
|
110
|
+
- specs/lib/dead_simple_conf_spec.rb
|
111
|
+
homepage: ''
|
112
|
+
licenses: []
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project: dead_simple_conf
|
131
|
+
rubygems_version: 1.8.11
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: Config loader
|
135
|
+
test_files:
|
136
|
+
- specs/common.rb
|
137
|
+
- specs/lib/dead_simple_conf_spec.rb
|