tengine_support 0.3.0 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +10 -0
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/VERSION +1 -1
- data/gemfiles/Gemfile.activesupport-3.0.10 +20 -0
- data/gemfiles/Gemfile.activesupport-3.1.1 +20 -0
- data/lib/tengine/support.rb +1 -0
- data/lib/tengine/support/config.rb +17 -0
- data/lib/tengine/support/config/amqp.rb +26 -0
- data/lib/tengine/support/config/definition.rb +146 -0
- data/lib/tengine/support/config/definition/field.rb +54 -0
- data/lib/tengine/support/config/definition/group.rb +18 -0
- data/lib/tengine/support/config/definition/has_many_children.rb +152 -0
- data/lib/tengine/support/config/definition/optparse_visitor.rb +66 -0
- data/lib/tengine/support/config/definition/suite.rb +42 -0
- data/lib/tengine/support/config/logger.rb +23 -0
- data/lib/tengine/support/config/mongoid.rb +14 -0
- data/spec/support/app1.rb +27 -0
- data/spec/support/suite.rb +49 -0
- data/spec/tengine_support/config/amqp_spec.rb +24 -0
- data/spec/tengine_support/config/logger_spec.rb +86 -0
- data/spec/tengine_support/config/mongoid_spec.rb +24 -0
- data/spec/tengine_support/config_spec.rb +190 -0
- data/spec/tengine_support/config_spec/load_config_file_by_config_option_spec.rb +94 -0
- data/spec/tengine_support/config_spec/load_spec.rb +66 -0
- data/spec/tengine_support/config_spec/load_spec_01.yml.erb +43 -0
- data/spec/tengine_support/config_spec/parse_spec.rb +155 -0
- data/tengine_support.gemspec +28 -2
- metadata +51 -17
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -14,7 +14,7 @@ It doesn't depend on other tengine gems.
|
|
14
14
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
15
15
|
|
16
16
|
## License
|
17
|
-
|
17
|
+
tengine_support is distributed under the LGPL and MPL
|
18
18
|
|
19
19
|
## Copyright
|
20
20
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
@@ -0,0 +1,20 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem "activesupport", "= 3.0.10"
|
7
|
+
|
8
|
+
# Add dependencies to develop your gem here.
|
9
|
+
# Include everything needed to run rake, tests, features, etc.
|
10
|
+
group :development do
|
11
|
+
gem "rspec", "~> 2.6.0"
|
12
|
+
gem "yard", "~> 0.7.2"
|
13
|
+
gem "bundler", "~> 1.0.18"
|
14
|
+
gem "jeweler", "~> 1.6.4"
|
15
|
+
# gem "rcov", ">= 0"
|
16
|
+
gem "simplecov", "~> 0.5.3"
|
17
|
+
gem "autotest"
|
18
|
+
|
19
|
+
gem 'rdiscount'
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem "activesupport", "= 3.1.1"
|
7
|
+
|
8
|
+
# Add dependencies to develop your gem here.
|
9
|
+
# Include everything needed to run rake, tests, features, etc.
|
10
|
+
group :development do
|
11
|
+
gem "rspec", "~> 2.6.0"
|
12
|
+
gem "yard", "~> 0.7.2"
|
13
|
+
gem "bundler", "~> 1.0.18"
|
14
|
+
gem "jeweler", "~> 1.6.4"
|
15
|
+
# gem "rcov", ">= 0"
|
16
|
+
gem "simplecov", "~> 0.5.3"
|
17
|
+
gem "autotest"
|
18
|
+
|
19
|
+
gem 'rdiscount'
|
20
|
+
end
|
data/lib/tengine/support.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'tengine/support'
|
2
|
+
|
3
|
+
module Tengine::Support::Config
|
4
|
+
autoload :Definition, 'tengine/support/config/definition'
|
5
|
+
|
6
|
+
autoload :Mongoid, 'tengine/support/config/mongoid'
|
7
|
+
autoload :Amqp , 'tengine/support/config/amqp'
|
8
|
+
autoload :Logger , 'tengine/support/config/logger'
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def suite(options = {}, &block)
|
12
|
+
result = Tengine::Support::Config::Definition::Suite.new
|
13
|
+
result.instance_eval(&block)
|
14
|
+
result
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'tengine/support/config'
|
2
|
+
|
3
|
+
module Tengine::Support::Config::Amqp
|
4
|
+
class Connection
|
5
|
+
include Tengine::Support::Config::Definition
|
6
|
+
field :host , 'hostname to connect queue.', :default => 'localhost', :type => :string
|
7
|
+
field :port , "port to connect queue.", :default => 5672, :type => :integer
|
8
|
+
field :vhost, "vhost to connect queue.", :type => :string
|
9
|
+
field :user , "username to connect queue.", :type => :string
|
10
|
+
field :pass , "password to connect queue.", :type => :string
|
11
|
+
end
|
12
|
+
|
13
|
+
class Exchange
|
14
|
+
include Tengine::Support::Config::Definition
|
15
|
+
field :name , "exchange name.", :type => :string
|
16
|
+
field :type , "exchange type.", :type => :string, :default => 'direct'
|
17
|
+
field :durable, "exchange durable.", :type => :boolean, :default => true
|
18
|
+
end
|
19
|
+
|
20
|
+
class Queue
|
21
|
+
include Tengine::Support::Config::Definition
|
22
|
+
field :name , "queue name.", :type => :string
|
23
|
+
field :durable, "queue durable.", :type => :boolean, :default => true
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'tengine/support/config'
|
2
|
+
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
4
|
+
|
5
|
+
module Tengine::Support::Config::Definition
|
6
|
+
autoload :Field, 'tengine/support/config/definition/field'
|
7
|
+
autoload :Group, 'tengine/support/config/definition/group'
|
8
|
+
autoload :Suite, 'tengine/support/config/definition/suite'
|
9
|
+
autoload :HasManyChildren, 'tengine/support/config/definition/has_many_children'
|
10
|
+
autoload :OptparseVisitor, 'tengine/support/config/definition/optparse_visitor'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def included(klass)
|
14
|
+
klass.extend(ClassMethods)
|
15
|
+
klass.class_eval do
|
16
|
+
self.class_attribute :children, :instance_writer => false, :instance_reader => false
|
17
|
+
self.children = []
|
18
|
+
|
19
|
+
self.class_attribute :definition_reference_names, :instance_writer => false
|
20
|
+
self.definition_reference_names = []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
def field(__name__, *args)
|
27
|
+
attrs = args.last.is_a?(Hash) ? args.pop : {}
|
28
|
+
attrs[:description] = args.first unless args.empty?
|
29
|
+
attrs[:__name__] = __name__
|
30
|
+
attrs[:__parent__] = self
|
31
|
+
|
32
|
+
if (superclass < Tengine::Support::Config::Definition) &&
|
33
|
+
(self.children == self.superclass.children)
|
34
|
+
self.children = self.superclass.children.dup
|
35
|
+
end
|
36
|
+
if field = children.detect{|child| child.__name__ == __name__}
|
37
|
+
new_field = field.dup
|
38
|
+
new_field.update(attrs)
|
39
|
+
idx = self.children.index(field)
|
40
|
+
self.children[idx] = new_field
|
41
|
+
field = new_field
|
42
|
+
else
|
43
|
+
field = Field.new(attrs)
|
44
|
+
self.children << field
|
45
|
+
end
|
46
|
+
(class << self; self; end).module_eval do
|
47
|
+
define_method(field.__name__){ field }
|
48
|
+
end
|
49
|
+
self.class_eval do
|
50
|
+
field_name = field.__name__
|
51
|
+
ivar_name = :"@#{field_name}"
|
52
|
+
|
53
|
+
define_method(field_name) do
|
54
|
+
if result = instance_variable_get(ivar_name)
|
55
|
+
result
|
56
|
+
else
|
57
|
+
field = child_by_name(field_name)
|
58
|
+
result = field ? field.default_value : nil
|
59
|
+
instance_variable_set(ivar_name, result)
|
60
|
+
result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
attr_writer field_name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def parameters
|
68
|
+
@parameters ||= []
|
69
|
+
end
|
70
|
+
|
71
|
+
def parameter(parameter_name)
|
72
|
+
parameters << parameter_name
|
73
|
+
self.class_eval do
|
74
|
+
attr_accessor parameter_name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def depends(*definition_reference_names)
|
79
|
+
if superclass.is_a?(Tengine::Support::Config::Definition) &&
|
80
|
+
(self.definition_reference_names == self.superclass.definition_reference_names)
|
81
|
+
self.definition_reference_names = self.superclass.definition_reference_names.dup
|
82
|
+
end
|
83
|
+
self.class_eval do
|
84
|
+
definition_reference_names.each do |ref_name|
|
85
|
+
attr_accessor ref_name
|
86
|
+
end
|
87
|
+
end
|
88
|
+
self.definition_reference_names += definition_reference_names
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
attr_accessor :__name__, :__parent__, :children
|
94
|
+
|
95
|
+
def instantiate_children
|
96
|
+
@children = self.class.children.map do |class_child|
|
97
|
+
child = class_child.dup
|
98
|
+
child.__parent__ = self
|
99
|
+
child
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def child_by_name(__name__)
|
104
|
+
(children || []).detect{|child| child.__name__ == __name__}
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_hash
|
108
|
+
children.inject({}) do |dest, child|
|
109
|
+
dest[child.__name__] = child.to_hash
|
110
|
+
dest
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def load(hash)
|
115
|
+
hash.each{|__name__, value| send("#{__name__}=", value)}
|
116
|
+
end
|
117
|
+
|
118
|
+
def accept_visitor(visitor)
|
119
|
+
visitor.visit(self)
|
120
|
+
end
|
121
|
+
|
122
|
+
def root
|
123
|
+
__parent__ ? __parent__.root : nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def name_array
|
127
|
+
(__parent__ ? __parent__.name_array : []) + [__name__]
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_value(obj)
|
131
|
+
obj.is_a?(Proc) ? self.instance_eval(&obj) : obj
|
132
|
+
end
|
133
|
+
|
134
|
+
def short_opt
|
135
|
+
r = root.mapping[ name_array ]
|
136
|
+
r ? "-#{r}" : nil
|
137
|
+
end
|
138
|
+
|
139
|
+
def long_opt
|
140
|
+
'--' << name_array.join('-').gsub(%r{_}, '-')
|
141
|
+
end
|
142
|
+
|
143
|
+
def action?; false; end
|
144
|
+
def separator?; false; end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'tengine/support/config/definition'
|
2
|
+
|
3
|
+
class Tengine::Support::Config::Definition::Field
|
4
|
+
attr_accessor :__name__, :__parent__, :__block__, :__type__
|
5
|
+
attr_accessor :type, :default_description, :default, :description
|
6
|
+
def initialize(attrs = {})
|
7
|
+
attrs.each{|k, v| send("#{k}=", v)}
|
8
|
+
end
|
9
|
+
|
10
|
+
def field?; @__type__ == :field; end
|
11
|
+
def action?; @__type__ == :action; end
|
12
|
+
def separator?; @__type__ == :separator; end
|
13
|
+
|
14
|
+
def update(attrs)
|
15
|
+
attrs.each{|k, v| send("#{k}=", v)}
|
16
|
+
end
|
17
|
+
|
18
|
+
def description_value
|
19
|
+
[
|
20
|
+
__parent__.get_value(description),
|
21
|
+
__parent__.get_value(default_description)
|
22
|
+
].join(' ')
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_value
|
26
|
+
default.respond_to?(:to_proc) ? __parent__.instance_eval(&default) : default
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
default_value
|
31
|
+
end
|
32
|
+
|
33
|
+
def accept_visitor(visitor)
|
34
|
+
visitor.visit(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def name_array
|
38
|
+
(__parent__ ? __parent__.name_array : []) + [__name__]
|
39
|
+
end
|
40
|
+
|
41
|
+
def root
|
42
|
+
__parent__ ? __parent__.root : nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def short_opt
|
46
|
+
r = root.mapping[ name_array ]
|
47
|
+
r ? "-#{r}" : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def long_opt
|
51
|
+
'--' << name_array.join('-').gsub(%r{_}, '-')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'tengine/support/config/definition'
|
2
|
+
|
3
|
+
class Tengine::Support::Config::Definition::Group
|
4
|
+
include Tengine::Support::Config::Definition::HasManyChildren
|
5
|
+
|
6
|
+
attr_reader :__name__
|
7
|
+
attr_accessor :__parent__
|
8
|
+
|
9
|
+
def initialize(__name__, options)
|
10
|
+
@__name__ = __name__
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def root
|
15
|
+
__parent__.root
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'tengine/support/config/definition'
|
2
|
+
|
3
|
+
module Tengine::Support::Config::Definition::HasManyChildren
|
4
|
+
|
5
|
+
def children
|
6
|
+
@children ||= []
|
7
|
+
end
|
8
|
+
|
9
|
+
def child_by_name(__name__)
|
10
|
+
__name__= __name__.to_sym if __name__.respond_to?(:to_sym)
|
11
|
+
children.detect{|child| child.__name__ == __name__}
|
12
|
+
end
|
13
|
+
|
14
|
+
def find(name_array)
|
15
|
+
name_array = Array(name_array)
|
16
|
+
head = name_array.shift
|
17
|
+
if child = child_by_name(head)
|
18
|
+
name_array.empty? ? child : child.find(name_array)
|
19
|
+
else
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(__name__, klass, options = {}, &block)
|
25
|
+
result = klass.new
|
26
|
+
result.__parent__ = self
|
27
|
+
result.__name__ = __name__
|
28
|
+
result.instantiate_children
|
29
|
+
dependencies = options[:dependencies] || {}
|
30
|
+
klass.definition_reference_names.each do |res_name|
|
31
|
+
name_array = dependencies[res_name]
|
32
|
+
raise "missing dependency of #{__name__.inspect} in :dependencies options to add(#{__name__.inspect}, #{klass.name}...)" unless name_array
|
33
|
+
obj = root.find(Array(name_array))
|
34
|
+
raise "#{name_array.inspect} not found" unless obj
|
35
|
+
result.send("#{res_name}=", obj)
|
36
|
+
end
|
37
|
+
|
38
|
+
defaults = options[:defaults] || {}
|
39
|
+
defaults.each do |key, value|
|
40
|
+
child = result.child_by_name(key)
|
41
|
+
raise "child not found for #{key.inspct} in #{result.__name__}" unless child
|
42
|
+
child.default = value if value
|
43
|
+
end
|
44
|
+
|
45
|
+
children << result
|
46
|
+
result.instance_eval(&block) if block
|
47
|
+
(class << self; self; end).class_eval{ define_method(__name__){ result } }
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
def group(__name__, options = {}, &block)
|
52
|
+
result = Tengine::Support::Config::Definition::Group.new(__name__, options)
|
53
|
+
result.__parent__ = self
|
54
|
+
(class << self; self; end).class_eval{ define_method(__name__){ result } }
|
55
|
+
children << result
|
56
|
+
result.instance_eval(&block) if block
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
def field(__name__, *args, &block)
|
61
|
+
attrs = args.last.is_a?(Hash) ? args.pop : {}
|
62
|
+
attrs[:description] = args.first unless args.empty?
|
63
|
+
attrs.update({
|
64
|
+
:__name__ => __name__,
|
65
|
+
:__parent__ => self,
|
66
|
+
:__block__ => block,
|
67
|
+
:__type__ => attrs[:__type__] || :field,
|
68
|
+
})
|
69
|
+
if field = children.detect{|child| child.__name__ == __name__}
|
70
|
+
new_field = field.dup
|
71
|
+
new_field.update(attrs)
|
72
|
+
idx = self.children.index(field)
|
73
|
+
self.children[idx] = new_field
|
74
|
+
field = new_field
|
75
|
+
else
|
76
|
+
field = Tengine::Support::Config::Definition::Field.new(attrs)
|
77
|
+
self.children << field
|
78
|
+
end
|
79
|
+
(class << self; self; end).module_eval do
|
80
|
+
attr_accessor field.__name__
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def action(__name__, *args, &block)
|
85
|
+
attrs = args.last.is_a?(Hash) ? args.pop : {}
|
86
|
+
attrs.update({
|
87
|
+
:__name__ => __name__,
|
88
|
+
:__parent__ => self,
|
89
|
+
:__block__ => block,
|
90
|
+
:__type__ => :action,
|
91
|
+
})
|
92
|
+
attrs[:description] = args.first unless args.empty?
|
93
|
+
field = Tengine::Support::Config::Definition::Field.new(attrs)
|
94
|
+
self.children << field
|
95
|
+
end
|
96
|
+
alias_method :__action__, :action
|
97
|
+
|
98
|
+
def action?; false; end
|
99
|
+
|
100
|
+
def separator(description)
|
101
|
+
attrs = {
|
102
|
+
:description => description,
|
103
|
+
:__name__ => :"separator#{children.count + 1}",
|
104
|
+
:__parent__ => self,
|
105
|
+
:__type__ => :separator,
|
106
|
+
}
|
107
|
+
field = Tengine::Support::Config::Definition::Field.new(attrs)
|
108
|
+
self.children << field
|
109
|
+
end
|
110
|
+
|
111
|
+
def separator?; false; end
|
112
|
+
|
113
|
+
def load_config(name, *args)
|
114
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
115
|
+
options[:type] = :load_config
|
116
|
+
args << options
|
117
|
+
field(name, *args)
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_hash
|
121
|
+
children.inject({}) do |dest, child|
|
122
|
+
unless child.action? || child.separator?
|
123
|
+
value = child.to_hash
|
124
|
+
unless value.is_a?(Hash) && value.empty?
|
125
|
+
dest[child.__name__] = child.to_hash
|
126
|
+
end
|
127
|
+
end
|
128
|
+
dest
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def load(hash)
|
133
|
+
hash.each do |__name__, value|
|
134
|
+
child = child_by_name(__name__)
|
135
|
+
raise "child not found for #{__name__.inspect} on #{__name__}" unless child
|
136
|
+
child.load(value)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def accept_visitor(visitor)
|
141
|
+
visitor.visit(self)
|
142
|
+
end
|
143
|
+
|
144
|
+
def name_array
|
145
|
+
(__parent__ ? __parent__.name_array : []) + [__name__]
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_value(obj)
|
149
|
+
obj.is_a?(Proc) ? self.instance_eval(&obj) : obj
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|