funfig 0.0.2
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/Gemfile +4 -0
- data/README +81 -0
- data/Rakefile +1 -0
- data/funfig.gemspec +24 -0
- data/lib/funfig/version.rb +3 -0
- data/lib/funfig.rb +292 -0
- metadata +52 -0
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
Example
|
2
|
+
=======
|
3
|
+
|
4
|
+
require 'funfig'
|
5
|
+
|
6
|
+
UploadConf = Funfig.new do
|
7
|
+
p.root '/services'
|
8
|
+
g.nginx do
|
9
|
+
p.folder { File.join(_.root, 'nginx') }
|
10
|
+
p.port '8000'
|
11
|
+
end
|
12
|
+
p.public_ip_port '*:80'
|
13
|
+
end
|
14
|
+
|
15
|
+
conf = UploadConf.new
|
16
|
+
p conf.nginx.folder
|
17
|
+
conf.root = "~/MailProject/upload"
|
18
|
+
p conf.nginx.folder
|
19
|
+
conf.each {|k,v| puts "#{k} #{v}"}
|
20
|
+
p conf
|
21
|
+
p conf.to_hash()
|
22
|
+
p conf.to_hash(true)
|
23
|
+
|
24
|
+
Up1Conf = UploadConf.clone do
|
25
|
+
g.nginx do
|
26
|
+
p.folder { File.join(_.root, 'nganx') }
|
27
|
+
p.location '/public'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
conf1 = Up1Conf.new
|
32
|
+
conf1.update(conf.to_hash())
|
33
|
+
p conf1
|
34
|
+
conf1.nginx_reset!
|
35
|
+
p conf1
|
36
|
+
|
37
|
+
TODO
|
38
|
+
====
|
39
|
+
|
40
|
+
1. define array of same kinds
|
41
|
+
|
42
|
+
Conf = Funfig.new do
|
43
|
+
p.port 8000
|
44
|
+
p.folder '/folder'
|
45
|
+
array :servers do
|
46
|
+
p.port { _parent.port + _pos }
|
47
|
+
p.folder { File.join(_parent.folder, _pos.to_s) }
|
48
|
+
end
|
49
|
+
a.servers1 do
|
50
|
+
p.port { _parent.port + _pos }
|
51
|
+
p.folder { File.join(_parent.folder, _pos.to_s) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
2. define hash of same kinds
|
56
|
+
|
57
|
+
Conf = Funfig.new do
|
58
|
+
hash :environments do
|
59
|
+
p.host 'localhost'
|
60
|
+
p.database { "mybase_#{_name}" }
|
61
|
+
end
|
62
|
+
h.environments1 do
|
63
|
+
p.host 'localhost'
|
64
|
+
p.database { "mybase_#{_name}" }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
3. Correct composition of schemes
|
69
|
+
|
70
|
+
ConfServ = Funfig.new do
|
71
|
+
p.port 80
|
72
|
+
p.ip '192.168.168.192'
|
73
|
+
end
|
74
|
+
|
75
|
+
ConfApp = Funfig.new do
|
76
|
+
p.path '/srv/path'
|
77
|
+
g.server ConfServ do
|
78
|
+
p.path { _.path }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/funfig.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "funfig/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "funfig"
|
7
|
+
s.version = Funfig::VERSION
|
8
|
+
s.authors = ["Sokolov Yura 'funny-falcon'"]
|
9
|
+
s.email = ["funny.falcon@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Configuration with calculable defaults}
|
12
|
+
s.description = %q{Defines configuration schema with calculable defaults}
|
13
|
+
|
14
|
+
s.rubyforge_project = "funfig"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
data/lib/funfig.rb
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
require "funfig/version"
|
2
|
+
require "yaml" unless defined? YAML
|
3
|
+
|
4
|
+
module Funfig
|
5
|
+
NOT_SET = Object.new.freeze
|
6
|
+
class ProxyParam < BasicObject
|
7
|
+
def initialize(group)
|
8
|
+
@group = group
|
9
|
+
end
|
10
|
+
def method_missing(name, value = NOT_SET, &block)
|
11
|
+
unless value.equal? NOT_SET
|
12
|
+
@group.param name, value
|
13
|
+
else
|
14
|
+
@group.param name, &block
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ProxyGroup < BasicObject
|
20
|
+
def initialize(group)
|
21
|
+
@group = group
|
22
|
+
end
|
23
|
+
def method_missing(name, &block)
|
24
|
+
@group.group name, &block
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Group
|
29
|
+
def initialize(parent=nil) # :nodoc:
|
30
|
+
@parent = parent
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get enclosing group
|
34
|
+
def _parent
|
35
|
+
@parent
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get root of configuration
|
39
|
+
# :call-seq:
|
40
|
+
# _
|
41
|
+
# _root
|
42
|
+
def _
|
43
|
+
@parent._
|
44
|
+
end
|
45
|
+
alias _root _
|
46
|
+
|
47
|
+
# Update config by yaml file
|
48
|
+
def load_file(filename)
|
49
|
+
params = YAML.load_file(filename)
|
50
|
+
update(params)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Update config by hash
|
54
|
+
def update(hash)
|
55
|
+
hash.each{|k, v|
|
56
|
+
self.send("#{k}=", v)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Iterate over parameter names
|
61
|
+
def each_param
|
62
|
+
return to_enum(:each_param) unless block_given?
|
63
|
+
self.class._params.each{|k, _|
|
64
|
+
yield k
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
# Iterate over parameters and values
|
69
|
+
# If called with parameter +true+, then iterate only over explicit setted parameters
|
70
|
+
#
|
71
|
+
# :call-seq:
|
72
|
+
# config.each{|name, value| puts "#{name} = #{value}"}
|
73
|
+
# config.each(true){|name, value| puts "#{name} = #{value}"}
|
74
|
+
def each(explicit=false)
|
75
|
+
return to_enum(:each, explicit) unless block_given?
|
76
|
+
self.class._params.each{|k, _|
|
77
|
+
yield k, send(k) unless explicit && !instance_variable_defined?("@#{k}")
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
# Convert configuration to hash
|
82
|
+
# If called with parameter +true+ than consider only explicit setted parameters
|
83
|
+
def to_hash(explicit=false)
|
84
|
+
h = {}
|
85
|
+
each(explicit){|k, v|
|
86
|
+
if Group === v
|
87
|
+
v = v.to_hash(explicit)
|
88
|
+
next if explicit && v.empty?
|
89
|
+
end
|
90
|
+
h[k] = v
|
91
|
+
}
|
92
|
+
h
|
93
|
+
end
|
94
|
+
|
95
|
+
def inspect
|
96
|
+
"<#{self.class.name} #{each.map{|k,v| "#{k}=#{v.inspect}"}.join(' ')}>"
|
97
|
+
end
|
98
|
+
|
99
|
+
# :stopdoc:
|
100
|
+
|
101
|
+
def _cache_get(k, &block)
|
102
|
+
_._cache.fetch(_sub_name(k), NOT_SET)
|
103
|
+
end
|
104
|
+
|
105
|
+
def _cache_set(k, v)
|
106
|
+
_._cache[_sub_name(k)] = v
|
107
|
+
end
|
108
|
+
|
109
|
+
def _sub_name(name)
|
110
|
+
self.class._sub_name(name)
|
111
|
+
end
|
112
|
+
|
113
|
+
def _path
|
114
|
+
self.class._path
|
115
|
+
end
|
116
|
+
|
117
|
+
def self._params
|
118
|
+
@params ||= {}
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.initialize_clone(arg)
|
122
|
+
super
|
123
|
+
if @params
|
124
|
+
params, @params = @params, {}
|
125
|
+
params.each{|name, par|
|
126
|
+
if par.is_a?(Class) && Group >= par
|
127
|
+
@params[name] = par.clone
|
128
|
+
else
|
129
|
+
@params[name] = par
|
130
|
+
end
|
131
|
+
}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self._sub_name(name)
|
136
|
+
"#{_path}.#{name}"
|
137
|
+
end
|
138
|
+
|
139
|
+
# :startdoc:
|
140
|
+
|
141
|
+
# Define named group of values
|
142
|
+
#
|
143
|
+
# :call-seq:
|
144
|
+
# config = Funfig.new do
|
145
|
+
# group :name_of_group do
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
def self.group(name, &block)
|
149
|
+
name = name.to_sym
|
150
|
+
vname = :"@#{name}"
|
151
|
+
_prev = _params[name]
|
152
|
+
klass = _prev.is_a?(Class) && Group >= _prev ? _prev : Class.new(Group)
|
153
|
+
_params[name] = klass
|
154
|
+
path = _sub_name(name)
|
155
|
+
const_set name.capitalize, klass
|
156
|
+
|
157
|
+
klass.send(:define_singleton_method, :_path) do
|
158
|
+
path
|
159
|
+
end
|
160
|
+
|
161
|
+
define_method(name) do
|
162
|
+
instance_variable_get(vname) ||
|
163
|
+
instance_variable_set(vname, klass.new(self))
|
164
|
+
end
|
165
|
+
|
166
|
+
define_method("#{name}=") do |hash|
|
167
|
+
send(name).update(hash)
|
168
|
+
end
|
169
|
+
|
170
|
+
define_method("#{name}_reset!") do
|
171
|
+
_._cache_clear!
|
172
|
+
remove_instance_variable(vname) if instance_variable_defined?(vname)
|
173
|
+
end
|
174
|
+
klass.class_exec ProxyParam.new(klass), &block
|
175
|
+
end
|
176
|
+
|
177
|
+
# define named parameter
|
178
|
+
#
|
179
|
+
# :call-seq:
|
180
|
+
# config = Funfig.new do
|
181
|
+
# param :name_of_param do calculate_default_value end
|
182
|
+
# end
|
183
|
+
def self.param(name, value = NOT_SET, &block)
|
184
|
+
_params[name] = true
|
185
|
+
vname = :"@#{name}"
|
186
|
+
name = name.to_sym
|
187
|
+
|
188
|
+
block ||= proc{
|
189
|
+
begin
|
190
|
+
value.dup
|
191
|
+
rescue TypeError
|
192
|
+
block = proc { value }
|
193
|
+
value
|
194
|
+
end
|
195
|
+
}
|
196
|
+
|
197
|
+
define_method(name) do
|
198
|
+
if instance_variable_defined?(vname)
|
199
|
+
instance_variable_get(vname)
|
200
|
+
else
|
201
|
+
if (v = _cache_get(name)).equal? NOT_SET
|
202
|
+
raise "Parameter #{_sub_name(name)} must be set!" unless block
|
203
|
+
_cache_set(name, (v = instance_eval &block))
|
204
|
+
end
|
205
|
+
v
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
define_method("#{name}=") do |v|
|
210
|
+
_._cache_clear!
|
211
|
+
instance_variable_set(vname, v)
|
212
|
+
end
|
213
|
+
|
214
|
+
define_method("#{name}_reset!") do
|
215
|
+
_._cache_clear!
|
216
|
+
remove_instance_variable(vname) if instance_variable_defined?(vname)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# syntax sugar proxy for declaring params
|
221
|
+
#
|
222
|
+
# :call-seq
|
223
|
+
# conf = Funfig.new do
|
224
|
+
# p.name_of_param :default_value
|
225
|
+
# p.other_param { calculate_default }
|
226
|
+
# end
|
227
|
+
def self.p
|
228
|
+
@proxy_param ||= ProxyParam.new(self)
|
229
|
+
end
|
230
|
+
|
231
|
+
# syntax sugar proxy for declaring group
|
232
|
+
#
|
233
|
+
# :call-seq
|
234
|
+
# conf = Funfig.new do
|
235
|
+
# g.name_of_group do
|
236
|
+
# end
|
237
|
+
# end
|
238
|
+
def self.g
|
239
|
+
@group_param ||= ProxyGroup.new(self)
|
240
|
+
end
|
241
|
+
|
242
|
+
# Create a copy of configuration scheme
|
243
|
+
#
|
244
|
+
# :call-seq:
|
245
|
+
# other_conf = config.clone do
|
246
|
+
# param :other_value do other_default end
|
247
|
+
# end
|
248
|
+
def self.clone(&block)
|
249
|
+
new = super
|
250
|
+
new.send(:class_eval, &block) if block_given?
|
251
|
+
new
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# :stopdoc:
|
256
|
+
class Root < Group
|
257
|
+
attr_reader :_cache
|
258
|
+
def initialize
|
259
|
+
@_cache = {}
|
260
|
+
end
|
261
|
+
|
262
|
+
def _cache_clear!
|
263
|
+
@_cache.clear
|
264
|
+
end
|
265
|
+
|
266
|
+
def _parent
|
267
|
+
raise "Already at root"
|
268
|
+
end
|
269
|
+
|
270
|
+
def _
|
271
|
+
self
|
272
|
+
end
|
273
|
+
|
274
|
+
def self._path
|
275
|
+
""
|
276
|
+
end
|
277
|
+
|
278
|
+
def self._sub_name(name)
|
279
|
+
name.to_s
|
280
|
+
end
|
281
|
+
end
|
282
|
+
# :startdoc:
|
283
|
+
|
284
|
+
# Create configuration schema
|
285
|
+
#
|
286
|
+
# :call-seq:
|
287
|
+
def self.new(&block)
|
288
|
+
conf = Class.new(Root)
|
289
|
+
conf.class_exec ProxyParam.new(conf), &block
|
290
|
+
conf
|
291
|
+
end
|
292
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: funfig
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sokolov Yura 'funny-falcon'
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-30 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Defines configuration schema with calculable defaults
|
15
|
+
email:
|
16
|
+
- funny.falcon@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README
|
24
|
+
- Rakefile
|
25
|
+
- funfig.gemspec
|
26
|
+
- lib/funfig.rb
|
27
|
+
- lib/funfig/version.rb
|
28
|
+
homepage: ''
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project: funfig
|
48
|
+
rubygems_version: 1.8.17
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: Configuration with calculable defaults
|
52
|
+
test_files: []
|