teapot 1.0.0.pre.rc9 → 1.0.0.pre.rc10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +5 -0
- data/README.md +3 -1
- data/Rakefile +3 -1
- data/bin/teapot +1 -1
- data/lib/teapot/configuration.rb +0 -1
- data/lib/teapot/context.rb +8 -2
- data/lib/teapot/controller/build.rb +3 -6
- data/lib/teapot/controller/create.rb +2 -2
- data/lib/teapot/controller/fetch.rb +1 -1
- data/lib/teapot/dependency.rb +0 -2
- data/lib/teapot/generator.rb +2 -2
- data/lib/teapot/loader.rb +4 -4
- data/lib/teapot/{name.rb → metadata.rb} +15 -22
- data/lib/teapot/package.rb +0 -2
- data/lib/teapot/repository.rb +1 -1
- data/lib/teapot/target.rb +5 -4
- data/lib/teapot/version.rb +1 -1
- data/{lib/teapot/environment.rb → spec/teapot/metadata_spec.rb} +11 -5
- data/teapot.gemspec +1 -3
- metadata +9 -49
- data/lib/teapot/build.rb +0 -254
- data/lib/teapot/environment/base.rb +0 -62
- data/lib/teapot/environment/constructor.rb +0 -133
- data/lib/teapot/environment/evaluator.rb +0 -51
- data/lib/teapot/environment/flatten.rb +0 -102
- data/lib/teapot/environment/system.rb +0 -56
- data/lib/teapot/rule.rb +0 -188
- data/lib/teapot/rulebook.rb +0 -91
- data/spec/teapot/build_spec.rb +0 -52
- data/spec/teapot/environment_spec.rb +0 -91
- data/spec/teapot/name_spec.rb +0 -50
@@ -1,51 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
module Teapot
|
22
|
-
class Environment
|
23
|
-
class Evaluator
|
24
|
-
def initialize(environment)
|
25
|
-
@environment = environment
|
26
|
-
end
|
27
|
-
|
28
|
-
def method_missing(name)
|
29
|
-
object_value(@environment[name])
|
30
|
-
end
|
31
|
-
|
32
|
-
# Compute the literal object value for a given key:
|
33
|
-
def object_value(value)
|
34
|
-
case value
|
35
|
-
when Array
|
36
|
-
value.collect{|item| object_value(item)}.flatten
|
37
|
-
when Symbol
|
38
|
-
object_value(@environment[value])
|
39
|
-
when Proc
|
40
|
-
object_value(instance_exec(&value))
|
41
|
-
when Default
|
42
|
-
object_value(value.value)
|
43
|
-
when Replace
|
44
|
-
object_value(value.value)
|
45
|
-
else
|
46
|
-
value
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require 'digest/md5'
|
22
|
-
|
23
|
-
module Teapot
|
24
|
-
class Environment
|
25
|
-
def to_h
|
26
|
-
@values
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_hash
|
30
|
-
hash = {}
|
31
|
-
|
32
|
-
# Flatten this chain of environments:
|
33
|
-
flatten_to_hash(hash)
|
34
|
-
|
35
|
-
# Evaluate all items to their respective object value:
|
36
|
-
evaluator = Evaluator.new(hash)
|
37
|
-
|
38
|
-
# Evaluate all the individual environment values so that they are flat:
|
39
|
-
Hash[hash.map{|key, value| [key, evaluator.object_value(value)]}]
|
40
|
-
end
|
41
|
-
|
42
|
-
def flatten
|
43
|
-
self.class.new(nil, self.to_hash)
|
44
|
-
end
|
45
|
-
|
46
|
-
def defined
|
47
|
-
@values.select{|name,value| Define === value}
|
48
|
-
end
|
49
|
-
|
50
|
-
def inspect(output = $stdout, indent = "")
|
51
|
-
@values.each do |(key, value)|
|
52
|
-
output.puts "#{indent}#{key}: #{value}"
|
53
|
-
end
|
54
|
-
|
55
|
-
@parent.inspect(output, indent + "\t") if @parent
|
56
|
-
end
|
57
|
-
|
58
|
-
# This should be stable within environments that produce the same results.
|
59
|
-
def checksum
|
60
|
-
digester = Digest::MD5.new
|
61
|
-
|
62
|
-
checksum_recursively(digester)
|
63
|
-
|
64
|
-
return digester.hexdigest
|
65
|
-
end
|
66
|
-
|
67
|
-
protected
|
68
|
-
|
69
|
-
def checksum_recursively(digester)
|
70
|
-
@values.each do |(key, value)|
|
71
|
-
digester.update(key.to_s)
|
72
|
-
digester.update(value.to_s)
|
73
|
-
end
|
74
|
-
|
75
|
-
@parent.checksum_recursively(digester) if @parent
|
76
|
-
end
|
77
|
-
|
78
|
-
# We fold in the ancestors one at a time from oldest to youngest.
|
79
|
-
def flatten_to_hash(hash)
|
80
|
-
if @parent
|
81
|
-
@parent.flatten_to_hash(hash)
|
82
|
-
end
|
83
|
-
|
84
|
-
@values.each do |key, value|
|
85
|
-
previous = hash[key]
|
86
|
-
|
87
|
-
if Replace === value
|
88
|
-
# Replace the parent value
|
89
|
-
hash[key] = value
|
90
|
-
elsif Array === previous
|
91
|
-
# Merge with the parent value
|
92
|
-
hash[key] = previous + Array(value)
|
93
|
-
elsif Default === value
|
94
|
-
# Update the parent value if not defined.
|
95
|
-
hash[key] = previous || value
|
96
|
-
else
|
97
|
-
hash[key] = value
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require 'rainbow'
|
22
|
-
require 'rainbow/ext/string'
|
23
|
-
|
24
|
-
module Teapot
|
25
|
-
class Environment
|
26
|
-
module System
|
27
|
-
def self.shell_escape(value)
|
28
|
-
case value
|
29
|
-
when Array
|
30
|
-
value.flatten.collect{|argument| shell_escape(argument)}.join(' ')
|
31
|
-
else
|
32
|
-
# Ensure that any whitespace has been escaped:
|
33
|
-
value.to_s.gsub(/ /, '\ ')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.convert_to_shell(environment)
|
38
|
-
Hash[environment.values.map{|key, value| [
|
39
|
-
key.to_s.upcase,
|
40
|
-
shell_escape(value)
|
41
|
-
]}]
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.dump(environment, io = STDOUT)
|
45
|
-
environment.values.each do |key, value|
|
46
|
-
io.puts "#{key}:".rjust(20).color(:magenta) + " #{value.inspect}"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Construct an environment from a given system environment:
|
52
|
-
def self.system_environment(env = ENV)
|
53
|
-
self.new(Hash[env.map{|key, value| [key.downcase.to_sym, value]}])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/lib/teapot/rule.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
module Teapot
|
22
|
-
# A rule is a function with a specific set of input and output parameters, which can match against a given set of specific inputs and outputs. For example, there might be several rules for compiling, but the specific rules depend on the language being compiled.
|
23
|
-
class Rule
|
24
|
-
class Parameter
|
25
|
-
def initialize(direction, name, options = {}, &block)
|
26
|
-
@direction = direction
|
27
|
-
@name = name
|
28
|
-
|
29
|
-
@options = options
|
30
|
-
|
31
|
-
@dynamic = block_given? ? Proc.new(&block) : nil
|
32
|
-
end
|
33
|
-
|
34
|
-
attr :direction
|
35
|
-
attr :name
|
36
|
-
|
37
|
-
attr :options
|
38
|
-
|
39
|
-
def dynamic?
|
40
|
-
@dynamic != nil
|
41
|
-
end
|
42
|
-
|
43
|
-
def implicit?
|
44
|
-
dynamic? and @options[:implicit]
|
45
|
-
end
|
46
|
-
|
47
|
-
# Optional parameters are those that are either defined as optional or implicit.
|
48
|
-
def optional?
|
49
|
-
@options[:optional] || implicit?
|
50
|
-
end
|
51
|
-
|
52
|
-
def applicable? arguments
|
53
|
-
value = arguments.fetch(@name) do
|
54
|
-
# Value couldn't be found, if it wasn't optional, this parameter didn't apply:
|
55
|
-
return optional?
|
56
|
-
end
|
57
|
-
|
58
|
-
# If a pattern is provided, we must match it.
|
59
|
-
if pattern = @options[:pattern]
|
60
|
-
return Array(value).all? {|item| pattern.match(item)}
|
61
|
-
end
|
62
|
-
|
63
|
-
return true
|
64
|
-
end
|
65
|
-
|
66
|
-
def compute(arguments, scope)
|
67
|
-
if implicit?
|
68
|
-
# Can be replaced if supplied:
|
69
|
-
arguments[@name] || scope.instance_exec(arguments, &@dynamic)
|
70
|
-
elsif dynamic?
|
71
|
-
# Argument is optional:
|
72
|
-
scope.instance_exec(arguments[@name], arguments, &@dynamic)
|
73
|
-
else
|
74
|
-
arguments[@name]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def inspect
|
79
|
-
"#{direction}:#{@name} (#{options.inspect})"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def initialize(process_name, type)
|
84
|
-
@name = process_name + "." + type
|
85
|
-
@full_name = @name.gsub(/[^\w]/, '_')
|
86
|
-
|
87
|
-
@process_name = process_name.gsub('-', '_').to_sym
|
88
|
-
@type = type
|
89
|
-
|
90
|
-
@apply = nil
|
91
|
-
|
92
|
-
@parameters = []
|
93
|
-
end
|
94
|
-
|
95
|
-
# compile.cpp
|
96
|
-
attr :name
|
97
|
-
|
98
|
-
# compile
|
99
|
-
attr :process_name
|
100
|
-
|
101
|
-
# compile_cpp
|
102
|
-
attr :full_name
|
103
|
-
|
104
|
-
attr :primary_output
|
105
|
-
|
106
|
-
def input(name, options = {}, &block)
|
107
|
-
@parameters << Parameter.new(:input, name, options, &block)
|
108
|
-
end
|
109
|
-
|
110
|
-
def parameter(name, options = {}, &block)
|
111
|
-
@parameters << Parameter.new(:argument, name, options, &block)
|
112
|
-
end
|
113
|
-
|
114
|
-
def output(name, options = {}, &block)
|
115
|
-
@parameters << Parameter.new(:output, name, options, &block)
|
116
|
-
|
117
|
-
@primary_output ||= @parameters.last
|
118
|
-
end
|
119
|
-
|
120
|
-
# Check if this rule can process these parameters
|
121
|
-
def applicable?(arguments)
|
122
|
-
@parameters.each do |parameter|
|
123
|
-
next if parameter.implicit?
|
124
|
-
|
125
|
-
return false unless parameter.applicable?(arguments)
|
126
|
-
end
|
127
|
-
|
128
|
-
return true
|
129
|
-
end
|
130
|
-
|
131
|
-
# The scope is the context in which the dynamic rule computation is done, usually an instance of Task.
|
132
|
-
def normalize(arguments, scope)
|
133
|
-
Hash[
|
134
|
-
@parameters.collect do |parameter|
|
135
|
-
[parameter.name, parameter.compute(arguments, scope)]
|
136
|
-
end
|
137
|
-
]
|
138
|
-
end
|
139
|
-
|
140
|
-
def files(arguments)
|
141
|
-
input_files = []
|
142
|
-
output_files = []
|
143
|
-
|
144
|
-
@parameters.each do |parameter|
|
145
|
-
# This could probably be improved a bit, we are assuming all parameters are file based:
|
146
|
-
value = arguments[parameter.name]
|
147
|
-
|
148
|
-
next unless value
|
149
|
-
|
150
|
-
case parameter.direction
|
151
|
-
when :input
|
152
|
-
input_files << value
|
153
|
-
when :output
|
154
|
-
output_files << value
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
return Build::Files::Composite.new(input_files), Build::Files::Composite.new(output_files)
|
159
|
-
end
|
160
|
-
|
161
|
-
def apply(&block)
|
162
|
-
@apply = Proc.new(&block)
|
163
|
-
end
|
164
|
-
|
165
|
-
def apply!(scope, arguments)
|
166
|
-
scope.instance_exec(arguments, &@apply) if @apply
|
167
|
-
end
|
168
|
-
|
169
|
-
def result(arguments)
|
170
|
-
if @primary_output
|
171
|
-
arguments[@primary_output.name]
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def to_s
|
176
|
-
"<#{self.class.name} #{@name.dump}>"
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
class NoApplicableRule < StandardError
|
181
|
-
def initialize(name, arguments)
|
182
|
-
super "No applicable rule with name #{name}.* for parameters: #{arguments.inspect}"
|
183
|
-
|
184
|
-
@name = name
|
185
|
-
@arguments = arguments
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
data/lib/teapot/rulebook.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require 'teapot/rule'
|
22
|
-
|
23
|
-
module Teapot
|
24
|
-
class Rulebook
|
25
|
-
def initialize
|
26
|
-
@rules = {}
|
27
|
-
@processes = {}
|
28
|
-
end
|
29
|
-
|
30
|
-
attr :rules
|
31
|
-
|
32
|
-
def << rule
|
33
|
-
@rules[rule.name] = rule
|
34
|
-
|
35
|
-
# A cache for fast process/file-type lookup:
|
36
|
-
processes = @processes[rule.process_name] ||= []
|
37
|
-
processes << rule
|
38
|
-
end
|
39
|
-
|
40
|
-
def [] name
|
41
|
-
@rules[name]
|
42
|
-
end
|
43
|
-
|
44
|
-
def with(superclass, state = {})
|
45
|
-
task_class = Class.new(superclass)
|
46
|
-
|
47
|
-
# Define methods for all processes, e.g. task_class#compile
|
48
|
-
@processes.each do |key, rules|
|
49
|
-
# Define general rules, which use rule applicability for disambiguation:
|
50
|
-
task_class.send(:define_method, key) do |arguments, &block|
|
51
|
-
rule = rules.find{|rule| rule.applicable? arguments }
|
52
|
-
|
53
|
-
if rule
|
54
|
-
update(rule, arguments, &block)
|
55
|
-
else
|
56
|
-
raise NoApplicableRule.new(key, arguments)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Define methods for all rules, e.g. task_class#compile_cpp
|
62
|
-
@rules.each do |key, rule|
|
63
|
-
task_class.send(:define_method, rule.full_name) do |arguments, &block|
|
64
|
-
update(rule, arguments, &block)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
state.each do |key, value|
|
69
|
-
task_class.send(:define_method, key) do
|
70
|
-
value
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
return task_class
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.for(environment)
|
78
|
-
rulebook = self.new
|
79
|
-
|
80
|
-
environment.defined.each do |name, define|
|
81
|
-
object = define.klass.new(*name.split('.', 2))
|
82
|
-
|
83
|
-
object.instance_eval(&define.block)
|
84
|
-
|
85
|
-
rulebook << object
|
86
|
-
end
|
87
|
-
|
88
|
-
return rulebook
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|