configdsl 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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +212 -0
- data/Rakefile +2 -0
- data/configdsl.gemspec +19 -0
- data/examples/example.rb +56 -0
- data/examples/test.cdsl.rb +29 -0
- data/lib/configdsl.rb +165 -0
- data/lib/configdsl/version.rb +3 -0
- metadata +71 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 MOZGIII
|
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,212 @@
|
|
1
|
+
# ConfigDSL
|
2
|
+
|
3
|
+
A tasty DSL for configuration files. Get rid of those ugly YAML and JSON configs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'configdsl'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install configdsl
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Standalone Usage
|
22
|
+
|
23
|
+
#### To read a config file
|
24
|
+
|
25
|
+
- in your app:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# Read external data
|
29
|
+
ConfigDSL.read("test.cdsl.rb")
|
30
|
+
```
|
31
|
+
|
32
|
+
- test.cdsl.rb
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
hi "User"
|
36
|
+
# p hi # => "User"
|
37
|
+
|
38
|
+
list do
|
39
|
+
one "123"
|
40
|
+
two "345"
|
41
|
+
three do
|
42
|
+
one "1"
|
43
|
+
three_two one + " 2"
|
44
|
+
three_three "three"
|
45
|
+
end
|
46
|
+
see "will_be_ovewritten"
|
47
|
+
end
|
48
|
+
|
49
|
+
list 5 do |index|
|
50
|
+
append "anything"
|
51
|
+
second index + 1
|
52
|
+
square index ** 2
|
53
|
+
|
54
|
+
see "overwritten!"
|
55
|
+
end
|
56
|
+
|
57
|
+
starting_time Time.now
|
58
|
+
```
|
59
|
+
|
60
|
+
will produce
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
pp ConfigDSL.data
|
64
|
+
|
65
|
+
{:hi=>"User",
|
66
|
+
:list=>
|
67
|
+
{:one=>"123",
|
68
|
+
:two=>"345",
|
69
|
+
:three=>{:one=>"1", :three_two=>"1 2", :three_three=>"three"},
|
70
|
+
:see=>"overwritten!",
|
71
|
+
:append=>"anything",
|
72
|
+
:second=>6,
|
73
|
+
:square=>25},
|
74
|
+
:starting_time=>2012-11-05 22:47:36 +0000}
|
75
|
+
```
|
76
|
+
|
77
|
+
#### You can also load inline configs form your code
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
# Execute inline data
|
81
|
+
ConfigDSL.execute do
|
82
|
+
inline_loading_example "here goes"
|
83
|
+
value "awesome"
|
84
|
+
code "great"
|
85
|
+
block_test "config option" do |preset|
|
86
|
+
block_val preset
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Another inline data
|
91
|
+
ConfigDSL.execute do
|
92
|
+
value "awesome"
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
gives
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
{:inline_loading_example=>"here goes",
|
100
|
+
:value=>"awesome",
|
101
|
+
:code=>"great",
|
102
|
+
:block_test=>{:block_val=>"config option"}}
|
103
|
+
```
|
104
|
+
|
105
|
+
|
106
|
+
#### You can combine theese two
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
# Read external data
|
110
|
+
ConfigDSL.read("test.cdsl.rb")
|
111
|
+
|
112
|
+
# Execute inline data
|
113
|
+
ConfigDSL.execute do
|
114
|
+
inline_loading_example "here goes"
|
115
|
+
value "awesome"
|
116
|
+
code "great"
|
117
|
+
block_test "config option" do |preset|
|
118
|
+
block_val preset
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Another inline data
|
123
|
+
ConfigDSL.execute do
|
124
|
+
value "awesome"
|
125
|
+
end
|
126
|
+
|
127
|
+
require "pp" # for pretty print
|
128
|
+
pp ConfigDSL.data
|
129
|
+
```
|
130
|
+
|
131
|
+
is
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
{:hi=>"User",
|
135
|
+
:list=>
|
136
|
+
{:one=>"123",
|
137
|
+
:two=>"345",
|
138
|
+
:three=>{:one=>"1", :three_two=>"1 2", :three_three=>"three"},
|
139
|
+
:see=>"overwritten!",
|
140
|
+
:append=>"anything",
|
141
|
+
:second=>6,
|
142
|
+
:square=>25},
|
143
|
+
:starting_time=>2012-11-05 22:48:40 +0000,
|
144
|
+
:inline_loading_example=>"here goes",
|
145
|
+
:value=>"awesome",
|
146
|
+
:code=>"great",
|
147
|
+
:block_test=>{:block_val=>"config option"}}
|
148
|
+
```
|
149
|
+
|
150
|
+
#### You can coviniently access all the config values in your app
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
# Here is how you get all the config
|
154
|
+
p ConfigDSL.data
|
155
|
+
|
156
|
+
# To read data from your app you can do this:
|
157
|
+
|
158
|
+
puts ; puts "Value of :value is: "
|
159
|
+
p ConfigDSL.data[:value]
|
160
|
+
|
161
|
+
# or this
|
162
|
+
|
163
|
+
puts ; puts "Another way to get it is: "
|
164
|
+
p ConfigDSL[:value]
|
165
|
+
|
166
|
+
# Access block values
|
167
|
+
|
168
|
+
puts "Block values: "
|
169
|
+
|
170
|
+
puts ; puts "-- [:list][:one]"
|
171
|
+
p ConfigDSL[:list][:one]
|
172
|
+
|
173
|
+
puts ; puts "-- [:list][:two]"
|
174
|
+
p ConfigDSL[:list][:two]
|
175
|
+
|
176
|
+
puts ; puts "-- [:list][:three]"
|
177
|
+
p ConfigDSL[:list][:three]
|
178
|
+
|
179
|
+
puts ; puts "-- [:list][:three][:three_two]"
|
180
|
+
p ConfigDSL[:list][:three][:three_two]
|
181
|
+
|
182
|
+
# Get something complex
|
183
|
+
puts ; puts "Program was stared at: "
|
184
|
+
p ConfigDSL[:starting_time]
|
185
|
+
```
|
186
|
+
|
187
|
+
#### Check out the example!
|
188
|
+
|
189
|
+
There is an `examples` dir. Check it out to see how it works for yourself!
|
190
|
+
|
191
|
+
### Use Hashie::Mash
|
192
|
+
|
193
|
+
If you're using Hashie::Mash from https://github.com/intridea/hashie, it will be used to store the config.
|
194
|
+
Just make sure to require it before you read the first value.
|
195
|
+
|
196
|
+
|
197
|
+
### Ruby on Rails
|
198
|
+
|
199
|
+
To be implemented. For now you can use it like standalone as initializer.
|
200
|
+
|
201
|
+
### To-Do List
|
202
|
+
|
203
|
+
- Ruby on Rails integration
|
204
|
+
- Lazy config values
|
205
|
+
|
206
|
+
## Contributing
|
207
|
+
|
208
|
+
1. Fork it
|
209
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
210
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
211
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
212
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/configdsl.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/configdsl/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["MOZGIII"]
|
6
|
+
gem.email = ["mike-n@narod.ru"]
|
7
|
+
gem.description = %q{A convinient DSL for your app configuration!}
|
8
|
+
gem.summary = %q{A convinient DSL for your app configuration!}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "configdsl"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Configdsl::VERSION
|
17
|
+
|
18
|
+
gem.add_runtime_dependency "activesupport"
|
19
|
+
end
|
data/examples/example.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
$: << "../lib"
|
2
|
+
require 'configdsl'
|
3
|
+
|
4
|
+
# Read external data
|
5
|
+
ConfigDSL.read("test.cdsl.rb")
|
6
|
+
|
7
|
+
# Execute inline data
|
8
|
+
ConfigDSL.execute do
|
9
|
+
inline_loading_example "here goes"
|
10
|
+
value "awesome"
|
11
|
+
code "great"
|
12
|
+
block_test "config option" do |preset|
|
13
|
+
block_val preset
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Another inline data
|
18
|
+
ConfigDSL.execute do
|
19
|
+
value "awesome"
|
20
|
+
end
|
21
|
+
|
22
|
+
require "pp" # for pretty print
|
23
|
+
|
24
|
+
# Here is how you get all the config
|
25
|
+
pp ConfigDSL.data
|
26
|
+
|
27
|
+
# To read data from your app you can do this:
|
28
|
+
|
29
|
+
puts ; puts "Value of :value is: "
|
30
|
+
p ConfigDSL.data[:value]
|
31
|
+
|
32
|
+
# or this
|
33
|
+
|
34
|
+
puts ; puts "Another way to get it is: "
|
35
|
+
p ConfigDSL[:value]
|
36
|
+
|
37
|
+
# Access block values
|
38
|
+
|
39
|
+
puts "Block values: "
|
40
|
+
|
41
|
+
puts ; puts "-- [:list][:one]"
|
42
|
+
p ConfigDSL[:list][:one]
|
43
|
+
|
44
|
+
puts ; puts "-- [:list][:two]"
|
45
|
+
p ConfigDSL[:list][:two]
|
46
|
+
|
47
|
+
puts ; puts "-- [:list][:three]"
|
48
|
+
p ConfigDSL[:list][:three]
|
49
|
+
|
50
|
+
puts ; puts "-- [:list][:three][:three_two]"
|
51
|
+
p ConfigDSL[:list][:three][:three_two]
|
52
|
+
|
53
|
+
# Get something complex
|
54
|
+
puts ; puts "Program was stared at: "
|
55
|
+
p ConfigDSL[:starting_time]
|
56
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Simple example
|
2
|
+
hi "User"
|
3
|
+
# p hi # => "User"
|
4
|
+
|
5
|
+
# Local variables still work!
|
6
|
+
local_var = "it is me"
|
7
|
+
another_var = "not included in config but can be used as usual"
|
8
|
+
|
9
|
+
# Complex example
|
10
|
+
list do
|
11
|
+
one "123"
|
12
|
+
two "345"
|
13
|
+
three do
|
14
|
+
one "1"
|
15
|
+
three_two one + " 2"
|
16
|
+
three_three "three"
|
17
|
+
end
|
18
|
+
see "will_be_ovewritten"
|
19
|
+
end
|
20
|
+
|
21
|
+
list 5 do |index|
|
22
|
+
append "anything"
|
23
|
+
second index + 1
|
24
|
+
square index ** 2
|
25
|
+
|
26
|
+
see "overwritten!"
|
27
|
+
end
|
28
|
+
|
29
|
+
starting_time Time.now
|
data/lib/configdsl.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require "configdsl/version"
|
2
|
+
require "active_support/concern"
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module ConfigDSL
|
6
|
+
module Memory
|
7
|
+
class << self
|
8
|
+
# Creates a new layer-level storage element
|
9
|
+
def layers_factory
|
10
|
+
# Try to use Hashie::Mash if defined (see hashie gem)
|
11
|
+
return Hashie::Mash.new if defined?(Hashie::Mash)
|
12
|
+
|
13
|
+
# Fallback to standart ruby Hash
|
14
|
+
Hash.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# Main data container
|
18
|
+
def data
|
19
|
+
@data ||= layers_factory
|
20
|
+
end
|
21
|
+
|
22
|
+
# Stores a value in specified key for specified context
|
23
|
+
def store(key, value, context = [])
|
24
|
+
layer = expand_context(context)
|
25
|
+
layer[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fetches a specified key for a specified context
|
29
|
+
# Allows to provide a default value
|
30
|
+
def fetch(key, defaul_value = nil, context = [])
|
31
|
+
fetch!(key, context)
|
32
|
+
rescue KeyError => e
|
33
|
+
defaul_value
|
34
|
+
end
|
35
|
+
|
36
|
+
# Fetches a specified key for a specified context
|
37
|
+
# Raises exception if something goes wrong
|
38
|
+
def fetch!(key, context = [])
|
39
|
+
layer = expand_context(context)
|
40
|
+
raise KeyError, "In context #{context} key not found: #{key.inspect}" unless layer.has_key?(key)
|
41
|
+
layer[key]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return a layer described by context or rises an exception
|
45
|
+
# if any of parent layers is undefined
|
46
|
+
def expand_context(context)
|
47
|
+
context.inject(data) do |hash, level|
|
48
|
+
hash[level]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Adds a new layer if it does not exist
|
53
|
+
def add_layer(new_layer, context)
|
54
|
+
current_layer = expand_context(context)
|
55
|
+
current_layer[new_layer] ||= layers_factory
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module DSL
|
61
|
+
extend ActiveSupport::Concern
|
62
|
+
|
63
|
+
def self.debug?
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
def context
|
68
|
+
@@context ||= []
|
69
|
+
end
|
70
|
+
|
71
|
+
def debug(text)
|
72
|
+
puts text if DSL.debug?
|
73
|
+
end
|
74
|
+
|
75
|
+
def varibales_hook(meth, *args, &block)
|
76
|
+
debug "Hooked #{meth}"
|
77
|
+
debug "Context is #{context}"
|
78
|
+
if block_given?
|
79
|
+
# Add list
|
80
|
+
debug "Adding list #{meth}"
|
81
|
+
evaluate_within_layer(meth, block, args)
|
82
|
+
else
|
83
|
+
if args.empty?
|
84
|
+
# Read variable
|
85
|
+
debug "Reading variable #{meth}"
|
86
|
+
Memory.fetch!(meth, context)
|
87
|
+
else
|
88
|
+
# Add variable
|
89
|
+
debug "Adding variable #{meth}"
|
90
|
+
value = args.size == 1 ? args.first : args.dup
|
91
|
+
Memory.store(meth, value, context)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def evaluate_within_layer(new_layer, block, args = [])
|
97
|
+
Memory.add_layer(new_layer, context)
|
98
|
+
begin
|
99
|
+
context.push new_layer
|
100
|
+
block.call(*args)
|
101
|
+
ensure
|
102
|
+
context.pop
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def method_missing(meth, *args, &block)
|
107
|
+
if respond_to?(meth)
|
108
|
+
super
|
109
|
+
else
|
110
|
+
varibales_hook(meth, *args, &block)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
module Processor
|
117
|
+
class Sandbox
|
118
|
+
include DSL
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.process(filename)
|
122
|
+
sandbox = Sandbox.new
|
123
|
+
sandbox.instance_eval(File.read(filename), filename)
|
124
|
+
sandbox
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.execute(&block)
|
128
|
+
sandbox = Sandbox.new
|
129
|
+
sandbox.instance_eval(&block)
|
130
|
+
sandbox
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.add_module(module_const)
|
134
|
+
Sandbox.extend module_const
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class << self
|
139
|
+
def read(filename)
|
140
|
+
Processor.process(filename)
|
141
|
+
end
|
142
|
+
|
143
|
+
def execute(&block)
|
144
|
+
Processor.execute(&block)
|
145
|
+
end
|
146
|
+
|
147
|
+
def data
|
148
|
+
Memory.data
|
149
|
+
end
|
150
|
+
|
151
|
+
def method_missing(meth, *args, &block)
|
152
|
+
if data.respond_to?(meth)
|
153
|
+
data.send(meth, *args, &block)
|
154
|
+
else
|
155
|
+
super
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def respond_to?(meth)
|
160
|
+
super_value = super
|
161
|
+
return super_value if super_value != false
|
162
|
+
data.respond_to?(meth)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: configdsl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- MOZGIII
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: A convinient DSL for your app configuration!
|
31
|
+
email:
|
32
|
+
- mike-n@narod.ru
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- configdsl.gemspec
|
43
|
+
- examples/example.rb
|
44
|
+
- examples/test.cdsl.rb
|
45
|
+
- lib/configdsl.rb
|
46
|
+
- lib/configdsl/version.rb
|
47
|
+
homepage: ''
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.24
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: A convinient DSL for your app configuration!
|
71
|
+
test_files: []
|