basechip 0.0.1
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/.document +5 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +14 -0
- data/README.rdoc +19 -0
- data/VERSION +1 -0
- data/bin/basechip +25 -0
- data/collateral/block/block.rb.erb +20 -0
- data/collateral/configuration/configuration.rb.erb +19 -0
- data/collateral/project/Gemfile +19 -0
- data/collateral/project/gitignore +6 -0
- data/collateral/project/project.rb.erb +76 -0
- data/collateral/project/settings.rb.erb +26 -0
- data/collateral/recipes/icarus.rb +73 -0
- data/collateral/recipes/icarus.rb.erb +88 -0
- data/collateral/recipes/local_cluster.rb +27 -0
- data/lib/array.rb +26 -0
- data/lib/base_chip/action.rb +309 -0
- data/lib/base_chip/base.rb +105 -0
- data/lib/base_chip/block.rb +75 -0
- data/lib/base_chip/bom.rb +75 -0
- data/lib/base_chip/bom_file.rb +45 -0
- data/lib/base_chip/cli.rb +371 -0
- data/lib/base_chip/cluster.rb +93 -0
- data/lib/base_chip/cluster_type.rb +45 -0
- data/lib/base_chip/code_area.rb +30 -0
- data/lib/base_chip/configuration.rb +257 -0
- data/lib/base_chip/dsl.rb +593 -0
- data/lib/base_chip/exit_error.rb +20 -0
- data/lib/base_chip/generator_menu.rb +64 -0
- data/lib/base_chip/git.rb +32 -0
- data/lib/base_chip/hierarchy.rb +84 -0
- data/lib/base_chip/install_menu.rb +89 -0
- data/lib/base_chip/ipc.rb +50 -0
- data/lib/base_chip/list_menu.rb +134 -0
- data/lib/base_chip/menu.rb +70 -0
- data/lib/base_chip/out_file.rb +68 -0
- data/lib/base_chip/permutation.rb +26 -0
- data/lib/base_chip/permute.rb +25 -0
- data/lib/base_chip/post.rb +26 -0
- data/lib/base_chip/problem.rb +33 -0
- data/lib/base_chip/project.rb +472 -0
- data/lib/base_chip/requirement.rb +26 -0
- data/lib/base_chip/runable.rb +36 -0
- data/lib/base_chip/source_language.rb +40 -0
- data/lib/base_chip/source_type.rb +24 -0
- data/lib/base_chip/statistic.rb +27 -0
- data/lib/base_chip/task.rb +21 -0
- data/lib/base_chip/task_master.rb +50 -0
- data/lib/base_chip/taskable.rb +77 -0
- data/lib/base_chip/tasker.rb +260 -0
- data/lib/base_chip/test.rb +202 -0
- data/lib/base_chip/test_list.rb +120 -0
- data/lib/base_chip/tool.rb +51 -0
- data/lib/base_chip/tool_version.rb +34 -0
- data/lib/base_chip/top_menu.rb +203 -0
- data/lib/base_chip/track_state.rb +61 -0
- data/lib/base_chip.rb +215 -0
- data/lib/dir.rb +30 -0
- data/lib/reporting.rb +97 -0
- metadata +215 -0
@@ -0,0 +1,593 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'active_support/core_ext/hash'
|
18
|
+
|
19
|
+
module Boolean; end
|
20
|
+
class TrueClass ; include Boolean; end
|
21
|
+
class FalseClass; include Boolean; end
|
22
|
+
|
23
|
+
module BaseChip
|
24
|
+
# class ConfigHash < Hash
|
25
|
+
# def [](key)
|
26
|
+
# value = super(key)
|
27
|
+
# value.configure
|
28
|
+
# value
|
29
|
+
# end
|
30
|
+
# def each
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
module Dsl
|
34
|
+
def self.included mod
|
35
|
+
mod.extend Dsl::ClassMethods
|
36
|
+
mod.class_eval do
|
37
|
+
include Reporting
|
38
|
+
include Dsl::InstanceMethods
|
39
|
+
attr_accessor :name
|
40
|
+
attr_reader :foster
|
41
|
+
attr_reader :parent
|
42
|
+
attr_accessor :settings
|
43
|
+
attr_accessor :children
|
44
|
+
attr_accessor :possible_settings
|
45
|
+
attr_reader :configured
|
46
|
+
attr_accessor :blks
|
47
|
+
attr_accessor :abstract
|
48
|
+
|
49
|
+
@settings = Hash.new
|
50
|
+
@possible_settings = Hash.new
|
51
|
+
@child_types = Hash.new
|
52
|
+
@possible_child_types = Hash.new
|
53
|
+
end
|
54
|
+
end
|
55
|
+
module ClassMethods
|
56
|
+
# class instance variables
|
57
|
+
attr_accessor :settings
|
58
|
+
attr_accessor :child_types
|
59
|
+
attr_accessor :possible_settings
|
60
|
+
|
61
|
+
def define_settings(h); h.each { |name, legal_types| define_setting name, legal_types } end
|
62
|
+
def define_children(h); h.each { |name, type | define_child name, type } end
|
63
|
+
|
64
|
+
def define_setting(name,legal_types)
|
65
|
+
@possible_settings[name] = legal_types
|
66
|
+
@settings[name] = legal_types
|
67
|
+
define_settings_methods(name,legal_types)
|
68
|
+
end
|
69
|
+
def define_child(name,type)
|
70
|
+
@possible_settings .merge! type.possible_settings
|
71
|
+
@possible_child_types.merge! type.possible_child_types
|
72
|
+
@possible_child_types[name] = type
|
73
|
+
@child_types[name] = type
|
74
|
+
type.possible_settings .each { |name, legal_types| define_settings_methods name, legal_types }
|
75
|
+
type.possible_child_types.each { |name, type | define_child_methods name, type }
|
76
|
+
define_child_methods(name,type)
|
77
|
+
end
|
78
|
+
|
79
|
+
def define_settings_methods(name,type)
|
80
|
+
# if name =~ /s$/
|
81
|
+
# define_method name.to_s.singularize do |index,value|
|
82
|
+
# hash = (instance_variable_get("@#{name}") || HashWithIndifferentAccess.new)
|
83
|
+
# instance_variable_set "@#{name}", hash
|
84
|
+
# hash[index] = value
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
define_method name do |value=:base_chip_get_operation|
|
88
|
+
unless value == :base_chip_get_operation
|
89
|
+
check_type(name,value,type)
|
90
|
+
if value.is_a? Hash
|
91
|
+
instance_variable_set "@#{name}", value.with_indifferent_access
|
92
|
+
else
|
93
|
+
instance_variable_set "@#{name}", value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if (value = instance_variable_get "@#{name}") and value.is_a? Hash
|
97
|
+
value.with_indifferent_access
|
98
|
+
else
|
99
|
+
value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
define_method "prepend_#{name}" do |value|
|
104
|
+
check_type(name,value,type)
|
105
|
+
if value && (current_value = instance_variable_get("@#{name}"))
|
106
|
+
if value.is_a? Hash
|
107
|
+
instance_variable_set "@#{name}", current_value.merge( value).with_indifferent_access
|
108
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
109
|
+
if current_value.is_a? Array
|
110
|
+
instance_variable_set "@#{name}", current_value.unshift(value)
|
111
|
+
else
|
112
|
+
instance_variable_set "@#{name}", "#{value} " + current_value
|
113
|
+
end
|
114
|
+
else
|
115
|
+
instance_variable_set "@#{name}", value + current_value
|
116
|
+
end
|
117
|
+
else
|
118
|
+
instance_variable_set "@#{name}", value
|
119
|
+
end
|
120
|
+
if (value = instance_variable_get "@#{name}") and value.is_a? Hash
|
121
|
+
value.with_indifferent_access
|
122
|
+
else
|
123
|
+
value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
define_method "append_#{name}" do |value|
|
128
|
+
check_type(name,value,type)
|
129
|
+
if value && (current_value = instance_variable_get("@#{name}"))
|
130
|
+
if value.is_a? Hash
|
131
|
+
instance_variable_set("@#{name}", current_value.merge( value).with_indifferent_access)
|
132
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
133
|
+
if current_value.is_a? Array
|
134
|
+
instance_variable_set "@#{name}", current_value << value
|
135
|
+
else
|
136
|
+
instance_variable_set "@#{name}", current_value + " #{value}"
|
137
|
+
end
|
138
|
+
else
|
139
|
+
instance_variable_set "@#{name}", current_value + value
|
140
|
+
end
|
141
|
+
else
|
142
|
+
instance_variable_set "@#{name}", value
|
143
|
+
end
|
144
|
+
if (value = instance_variable_get "@#{name}") and value.is_a? Hash
|
145
|
+
value.with_indifferent_access
|
146
|
+
else
|
147
|
+
value
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
def define_child_methods(child_name,type)
|
152
|
+
child_name_plural = child_name.to_s.pluralize.to_sym
|
153
|
+
attr_accessor child_name_plural
|
154
|
+
define_method child_name do |name=nil,&blk| # why is this an accessor also?
|
155
|
+
if name
|
156
|
+
hash = instance_variable_or_equal(child_name_plural,HashWithIndifferentAccess.new)
|
157
|
+
tmp = (hash[name] ||= type.new)
|
158
|
+
tmp.name = name
|
159
|
+
tmp.parent = self
|
160
|
+
tmp.blks << blk if blk
|
161
|
+
tmp
|
162
|
+
else
|
163
|
+
instance_variable_get("@#{name}")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
define_method "abstract_#{child_name}" do |name=nil,&blk|
|
167
|
+
tmp = send(child_name, name, &blk)
|
168
|
+
tmp.abstract = true
|
169
|
+
end
|
170
|
+
define_method "import_#{child_name}" do |name,object|
|
171
|
+
fault "attempting to import object #{object.name} of type #{object.class} into #{child_name_plural} of type #{type}" if object.class != type
|
172
|
+
hash = instance_variable_or_equal(child_name_plural,HashWithIndifferentAccess.new)
|
173
|
+
fault "#{child_name} '#{name} already exists. Import is not possible" if hash[name]
|
174
|
+
tmp = (hash[name] = object.clone)
|
175
|
+
tmp.name = name
|
176
|
+
tmp.foster = tmp.parent
|
177
|
+
tmp.parent = self
|
178
|
+
end
|
179
|
+
|
180
|
+
define_method "remove_#{child_name}" do |name|
|
181
|
+
hash = instance_variable_or_equal(child_name_plural,HashWithIndifferentAccess.new)
|
182
|
+
hash.delete name
|
183
|
+
end
|
184
|
+
|
185
|
+
# FIXME this only works on defined objects
|
186
|
+
define_method "all_#{child_name_plural}" do |&blk|
|
187
|
+
hash = instance_variable_or_equal(child_name_plural,HashWithIndifferentAccess.new)
|
188
|
+
hash.each_value do |value|
|
189
|
+
value.blks << blk
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def settings ; @settings end
|
195
|
+
def child_types ; @child_types end
|
196
|
+
def possible_settings ; @possible_settings end
|
197
|
+
def possible_child_types; @possible_child_types end
|
198
|
+
|
199
|
+
def to_doc_hash
|
200
|
+
doc_settings = {}
|
201
|
+
doc_child_types = {}
|
202
|
+
doc_possible_settings = {}
|
203
|
+
doc_possible_child_types = {}
|
204
|
+
|
205
|
+
settings .each { |name,types| doc_settings[name] = types.map{|t|t.to_s} }
|
206
|
+
possible_settings .each { |name,types| unless doc_settings[name]; doc_possible_settings[name] = types.map{|t|t.to_s} end}
|
207
|
+
|
208
|
+
child_types .each { |k,v| doc_child_types[k.to_s] = v.to_s }
|
209
|
+
possible_child_types .each { |k,v| doc_possible_child_types[k.to_s] = v.to_s unless doc_child_types[k.to_s] }
|
210
|
+
|
211
|
+
doc_method_list = instance_methods - Object.methods
|
212
|
+
doc_methods = {}
|
213
|
+
doc_method_list.each do |m|
|
214
|
+
im = instance_method(m)
|
215
|
+
doc_methods[m] = {
|
216
|
+
:inputs => im.parameters,
|
217
|
+
:expects => (im.parameters.empty? ? "This method takes no inputs." : nil)
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
221
|
+
possible_settings.keys.each do |n|
|
222
|
+
[ n ,
|
223
|
+
"append_#{ n}".to_sym,
|
224
|
+
"prepend_#{n}".to_sym
|
225
|
+
].each do |m|
|
226
|
+
doc_methods[m][:setting] = n.to_s
|
227
|
+
end
|
228
|
+
end
|
229
|
+
possible_child_types.keys.each do |n|
|
230
|
+
[ n ,
|
231
|
+
"remove_#{n}".to_sym,
|
232
|
+
"abstract_#{n}".to_sym,
|
233
|
+
"import_#{n}".to_sym,
|
234
|
+
"all_#{n}".pluralize.to_sym,
|
235
|
+
n.to_s.pluralize.to_sym,
|
236
|
+
"#{n.to_s.pluralize}=".to_sym
|
237
|
+
].each do |m|
|
238
|
+
doc_methods[m][:object] = n.to_s
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
h = { self.to_s => { :type => self.to_s ,
|
243
|
+
:child_types => doc_child_types ,
|
244
|
+
:settings => doc_settings ,
|
245
|
+
:possible_child_types => doc_possible_child_types ,
|
246
|
+
:possible_settings => doc_possible_settings ,
|
247
|
+
:methods => doc_methods }
|
248
|
+
}
|
249
|
+
child_types.each_value do |v|
|
250
|
+
next if v == self
|
251
|
+
h.merge! v.to_doc_hash
|
252
|
+
end
|
253
|
+
h
|
254
|
+
end
|
255
|
+
end
|
256
|
+
module InstanceMethods
|
257
|
+
def initialize(*args)
|
258
|
+
super(*args)
|
259
|
+
@blks = []
|
260
|
+
@modes = []
|
261
|
+
@base_types = []
|
262
|
+
end
|
263
|
+
def parent=(parent)
|
264
|
+
@parent = parent
|
265
|
+
end
|
266
|
+
|
267
|
+
# # and then the settings
|
268
|
+
# @settings = Hash.new
|
269
|
+
# @children = Hash.new
|
270
|
+
# @possible_settings = Hash.new
|
271
|
+
|
272
|
+
# (self.class. settings).each { |n,s| s2 = s.dup; s2.parent = self; @settings[n] = s2 }
|
273
|
+
# (self.class.possible_settings).each { |n,s| s2 = s.dup; s2.parent = self; @possible_settings[n] = s2 }
|
274
|
+
# end
|
275
|
+
def check_type(setting,value,types)
|
276
|
+
return if value.nil?
|
277
|
+
if types.is_a? Array
|
278
|
+
types.each do |t|
|
279
|
+
return if value.is_a? t
|
280
|
+
end
|
281
|
+
else
|
282
|
+
return if value.is_a? type
|
283
|
+
end
|
284
|
+
raise "setting '#{setting}' is set to #{value.inspect} which is of type '#{value.class}', but should have been set to a #{types.map{|t|"'#{t}'"}.join(' or a ')}"
|
285
|
+
end
|
286
|
+
def deep_configure
|
287
|
+
configure
|
288
|
+
self.class.child_types.each_key do |name|
|
289
|
+
next unless hash = self.send(name.to_s.pluralize)
|
290
|
+
hash.each_value do |child|
|
291
|
+
child.deep_configure
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
def clear
|
296
|
+
self.class.possible_settings .each_key {|s| self.send s, nil }
|
297
|
+
self.class.possible_child_types.each_key {|s| (hash = self.send s) and hash.delete_if {true} }
|
298
|
+
@configured = false
|
299
|
+
end
|
300
|
+
def configure
|
301
|
+
return if @configured
|
302
|
+
|
303
|
+
if foster ; foster.configure ; @modes += foster.modes end
|
304
|
+
if parent ; parent.configure ; @modes += parent.modes end
|
305
|
+
@modes.uniq!
|
306
|
+
|
307
|
+
verbose "configuring #{@name}"
|
308
|
+
|
309
|
+
find_parent_values(:foster)
|
310
|
+
find_parent_values(:parent)
|
311
|
+
|
312
|
+
@base_types.each do |t|
|
313
|
+
instance_calls(t.blks)
|
314
|
+
end
|
315
|
+
instance_calls(@blks)
|
316
|
+
|
317
|
+
@configured = true
|
318
|
+
end
|
319
|
+
def instance_calls(blks)
|
320
|
+
blks.each do |b|
|
321
|
+
if b.parameters.empty?
|
322
|
+
self.instance_exec(&b)
|
323
|
+
else
|
324
|
+
b.call(self)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
# def eat_settings_hash(h,file)
|
329
|
+
# h.each do |str,v|
|
330
|
+
# k = str.to_sym
|
331
|
+
# if s = (@settings[k] || @possible_settings[k])
|
332
|
+
# s.set(v,file)
|
333
|
+
# elsif c = @children[k]
|
334
|
+
# if v.is_a? Array
|
335
|
+
# str = str.sub(/s$/,'_array')
|
336
|
+
# k = str.to_sym
|
337
|
+
# c = @children[k]
|
338
|
+
# end
|
339
|
+
# if c.is_a? Hash
|
340
|
+
# t = self.class.child_types[k]
|
341
|
+
# # FIXME fault if v is not also hash ?? Maybe support strings and arrays also ??
|
342
|
+
# raise "v is a #{v.class}" unless v.is_a? Hash
|
343
|
+
# v.each do |kc,vc|
|
344
|
+
# tmp = (c[kc] ||= t.new(self))
|
345
|
+
# tmp.name = kc
|
346
|
+
# tmp.eat_settings_hash(vc,file) if vc
|
347
|
+
# end
|
348
|
+
# elsif c.is_a? Array
|
349
|
+
# t = self.class.child_types[k]
|
350
|
+
# # FIXME fault if v is not also hash ?? Maybe support strings and arrays also ??
|
351
|
+
# raise "v is a #{v.class}" unless v.is_a? Array
|
352
|
+
# v.each do |vc|
|
353
|
+
# c << (tmp = t.new(self))
|
354
|
+
# tmp.eat_settings_hash(vc,file) if vc
|
355
|
+
# end
|
356
|
+
# else
|
357
|
+
# c.eat_settings_hash(v,file)
|
358
|
+
# end
|
359
|
+
# end
|
360
|
+
# end
|
361
|
+
# end
|
362
|
+
def find_parent_values(parent_type)
|
363
|
+
if parent = self.send(parent_type)
|
364
|
+
raise "parent #{parent.name} of type #{parent.class.class_string} has not yet been configured" unless parent.configured
|
365
|
+
end
|
366
|
+
self.class.possible_settings.each_key do |name|
|
367
|
+
next unless (self.send name).nil? # PROB UNNECESSARY
|
368
|
+
next unless parent = (self.send parent_type)
|
369
|
+
self.send name, (parent.send name)
|
370
|
+
end
|
371
|
+
self.class.possible_child_types.each do |name,type|
|
372
|
+
next unless parent = self.send(parent_type)
|
373
|
+
plural = name.to_s.pluralize
|
374
|
+
next unless child_defaults = parent.send(plural)
|
375
|
+
hash = instance_variable_or_equal(plural,HashWithIndifferentAccess.new)
|
376
|
+
child_defaults.each do |name,object|
|
377
|
+
object2 = (hash[name] ||= type.new)
|
378
|
+
object2.name ||= name
|
379
|
+
object2.parent ||= self
|
380
|
+
object2.blks = object.blks + object2.blks
|
381
|
+
object2.abstract ||= object.abstract
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
def instance_variable_or_equal(name,value)
|
386
|
+
value = instance_variable_get("@#{name}") || value
|
387
|
+
instance_variable_set "@#{name}", value
|
388
|
+
value
|
389
|
+
end
|
390
|
+
# def meaningful_settings
|
391
|
+
# return @meaningful_settings if @meaningful_settings
|
392
|
+
# @meaningful_settings = Hash.new
|
393
|
+
# @settings.each do |n,s|
|
394
|
+
# @meaningful_settings[n] = s.value if s.value_set
|
395
|
+
# end
|
396
|
+
# @meaningful_settings
|
397
|
+
# end
|
398
|
+
# def to_hash
|
399
|
+
# h = meaningful_settings.dup
|
400
|
+
# @children.each do |t,c_hash|
|
401
|
+
# h[t] = h2 = Hash.new
|
402
|
+
# c_hash.each{|n,c| h2[n] = c.to_hash}
|
403
|
+
# end
|
404
|
+
# h
|
405
|
+
# end
|
406
|
+
# def to_regex(data)
|
407
|
+
# data = data.join('|') if data.respond_to? :join
|
408
|
+
# /#{data}/
|
409
|
+
# end
|
410
|
+
# def print_configuration
|
411
|
+
# puts configuration_hash.to_yaml
|
412
|
+
# end
|
413
|
+
# def configuration_hash
|
414
|
+
# h = { :settings => settings_to_hash(@settings ),
|
415
|
+
# :possible_settings => settings_to_hash(@possible_settings),
|
416
|
+
# :children => {} }
|
417
|
+
# @children.each do |type,children|
|
418
|
+
# h[:children][type] = children.class.new
|
419
|
+
# children.each do |name,child|
|
420
|
+
# if child
|
421
|
+
# h[:children][type][name] = child.configuration_hash
|
422
|
+
# else
|
423
|
+
# h[:children][type] << name.configuration_hash
|
424
|
+
# end
|
425
|
+
# end
|
426
|
+
# end
|
427
|
+
# h
|
428
|
+
# end
|
429
|
+
# def settings_to_hash(settings)
|
430
|
+
# h = {}
|
431
|
+
# @settings.each do |n,s|
|
432
|
+
# if s.value_set
|
433
|
+
# h[n] = s.value
|
434
|
+
# end
|
435
|
+
# end
|
436
|
+
# h
|
437
|
+
# end
|
438
|
+
# methods that probably shouldn't be here, common to project and block
|
439
|
+
def find_file(file)
|
440
|
+
found = nil
|
441
|
+
@search_paths ||= ['', @work_dir+'/', @top_dir+'/', @project.project_root+'/'].uniq
|
442
|
+
@search_paths.each do |p|
|
443
|
+
return found if File.exist?(found = "#{p}#{file}")
|
444
|
+
end
|
445
|
+
fault "Could not resolve path to file #{file.inspect}. Attempted the following:\n#{@search_paths.map{|p| " '#{p}#{file}'"}.join("\n")}"
|
446
|
+
end
|
447
|
+
def full_name
|
448
|
+
if self == BaseChip.project
|
449
|
+
nil
|
450
|
+
elsif @parent and @parent.full_name
|
451
|
+
"#{@parent.full_name}:#{@name}"
|
452
|
+
else
|
453
|
+
@name
|
454
|
+
end
|
455
|
+
end
|
456
|
+
alias task_name full_name
|
457
|
+
def steal_settings(object)
|
458
|
+
self.class.settings.each_key do |name|
|
459
|
+
if (value = object.send(name))
|
460
|
+
self.send(name, value)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
def steal_children(object)
|
465
|
+
self.class.child_types.each_key do |name|
|
466
|
+
plural = name.to_s.pluralize
|
467
|
+
ohash = HashWithIndifferentAccess.new
|
468
|
+
if ihash = object.send(plural)
|
469
|
+
ihash.each do |key,value|
|
470
|
+
ohash[key] = value.clone if value
|
471
|
+
end
|
472
|
+
self.send("#{plural}=", ohash)
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
def clone
|
477
|
+
c = super
|
478
|
+
c.steal_children(self)
|
479
|
+
c
|
480
|
+
end
|
481
|
+
def file(f=nil)
|
482
|
+
if f
|
483
|
+
@file = absolute_path(f)
|
484
|
+
if File.exist? @file
|
485
|
+
instance_eval(File.read(@file),@file)
|
486
|
+
else
|
487
|
+
fault "file '#{@file}' could not be found for #{self.class_string.downcase} '#{@name}'" +
|
488
|
+
(self.parent ? " in #{self.parent.class_string.downcase} '#{self.parent.name}'" : '')
|
489
|
+
end
|
490
|
+
else
|
491
|
+
@file
|
492
|
+
end
|
493
|
+
end
|
494
|
+
def absolute_path(f)
|
495
|
+
if f =~ /^\//
|
496
|
+
f
|
497
|
+
else
|
498
|
+
"#{BaseChip.root}/#{f}"
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|
502
|
+
attr_accessor :modes
|
503
|
+
def add_child_mode_as_child(child_name,mode)
|
504
|
+
if c = @children[child_name.to_sym]
|
505
|
+
c2 = c.clone
|
506
|
+
c2.blks = c.blks # copy has the same blocks
|
507
|
+
c2.modes << mode
|
508
|
+
else
|
509
|
+
fault "add_child_mode_as_child could not find child '#{child_name}'"
|
510
|
+
end
|
511
|
+
end
|
512
|
+
def mode(name, &blk)
|
513
|
+
if mode? name
|
514
|
+
blk.call
|
515
|
+
end
|
516
|
+
end
|
517
|
+
def mode?(name)
|
518
|
+
# fault "Attempted to use mode '#{name}', which isn't registered with the project. Call register_mode(#{name}) in project.rb to allow." unless project.registered_modes.include? name.to_s
|
519
|
+
if modes.include? name.to_s
|
520
|
+
".#{name}"
|
521
|
+
end # else return nil
|
522
|
+
end
|
523
|
+
def type_plural
|
524
|
+
if is_a? Project ; 'project.subprojects'
|
525
|
+
elsif is_a? Block ; 'project.blocks'
|
526
|
+
elsif is_a? Configuration; 'block.configurations'
|
527
|
+
elsif is_a? Action ; 'configuration.actions'
|
528
|
+
elsif is_a? TestList ; 'configuration.test_lists'
|
529
|
+
elsif is_a? Test ; 'test_list.test'
|
530
|
+
else fault "Could not determine type of '#{full_name}' in order to make 'inherit' call"
|
531
|
+
end
|
532
|
+
end
|
533
|
+
def inherit(name)
|
534
|
+
return if @base_types.map{|t|t.name}.include? name
|
535
|
+
things = parent.instance_eval(type_plural)
|
536
|
+
fault "'#{full_name}' tried to inherit from #{name.inspect}, but there are no '#{type_plural}' in '#{parent.full_name}'to extend'" unless things
|
537
|
+
thing = things[name.to_sym]
|
538
|
+
fault "'#{full_name}' tried to inherit from #{name.inspect}, but '#{parent.full_name}.#{type_plural}[#{name.inspect}]' is nil'" unless thing
|
539
|
+
@base_types << thing
|
540
|
+
end
|
541
|
+
|
542
|
+
# only used in block and project
|
543
|
+
# def determine_dirs_to_top(dir = nil)
|
544
|
+
# dir ||= @work_dir
|
545
|
+
# @dirs_to_top = []
|
546
|
+
# loop do
|
547
|
+
# @dirs_to_top << dir
|
548
|
+
# break if File.exist? dir + '/.cs_top'
|
549
|
+
|
550
|
+
# if dir == '/'
|
551
|
+
# fault "Couldn't find file '.cs_top' in any directory above #{@pwd}.\n" +
|
552
|
+
# "'.cs_top' is an empty file expected to reside at the top of the checked out project.\n" +
|
553
|
+
# "Go to the top of your check-out and type 'touch .cs_top'"
|
554
|
+
# end
|
555
|
+
# dir = File.expand_path(dir + '/../')
|
556
|
+
# end
|
557
|
+
# $environment['PROJECT_ROOT'] = $project_root = @project_root = dir
|
558
|
+
# end
|
559
|
+
# only used in block and project
|
560
|
+
# def read_settings_files(settings_files)
|
561
|
+
# @settings_files = settings_files
|
562
|
+
# @project_root = @project.project_root
|
563
|
+
|
564
|
+
# # @settings_files += @supplimental_yaml if @supplimental_yaml
|
565
|
+
# # @project.dirs_to_top.each do |d|
|
566
|
+
# # if File.exist? (file = d + '/settings.yaml')
|
567
|
+
# # @settings_files << file
|
568
|
+
# # end
|
569
|
+
# # end
|
570
|
+
|
571
|
+
# # print_configuration
|
572
|
+
# @settings_files.each do |sf|
|
573
|
+
# found = nil
|
574
|
+
# sf = sf.gsub(/\$([A-Z_]+)/) { instance_variable_get "@#{$1.downcase}" }
|
575
|
+
# sf = find_file sf
|
576
|
+
# if h = YAML.load_file(sf)
|
577
|
+
# self.eat_settings_hash(h,sf)
|
578
|
+
# self.find_parent_values
|
579
|
+
# end
|
580
|
+
# end
|
581
|
+
|
582
|
+
# # FIXME TODAY unless self.aliases.size > 0
|
583
|
+
# # FIXME TODAY fault "No aliases found"
|
584
|
+
# # FIXME TODAY end
|
585
|
+
|
586
|
+
# # FIXME TODAY unless self.actions.size > 0
|
587
|
+
# # FIXME TODAY fault "No action definitions were found in any of the following settings files:\n#{@settings_files.join("\n")}"
|
588
|
+
# # FIXME TODAY end
|
589
|
+
#
|
590
|
+
# end
|
591
|
+
|
592
|
+
end
|
593
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module BaseChip
|
18
|
+
class ExitError < RuntimeError
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'base_chip/menu'
|
18
|
+
module BaseChip
|
19
|
+
class GeneratorMenu < Menu
|
20
|
+
include Cli
|
21
|
+
option :git, :description=>"Check in generated files", :type=>:boolean, :alias=>[:g,:r,:repo]
|
22
|
+
|
23
|
+
desc "Generate a block"
|
24
|
+
def block(name)
|
25
|
+
BaseChip.load_environment
|
26
|
+
BaseChip.find_root(dir = nil)
|
27
|
+
@block_name = name
|
28
|
+
BaseChip.build_directory_structure(name,BaseChip.block_directories)
|
29
|
+
BaseChip.erb_template "#{BaseChip::GEM_DIR}/collateral/block/block.rb.erb", "#{BaseChip.root}/#{name}/base_chip/block.rb"
|
30
|
+
FileUtils.cd BaseChip.root
|
31
|
+
puts "block generation complete"
|
32
|
+
|
33
|
+
if options.git
|
34
|
+
system "git add ./#{name}"
|
35
|
+
system "git commit -m 'Initial automated block build of '#{name}' BaseChip.' ./#{name}"
|
36
|
+
|
37
|
+
normal "block '#{name}' has been created."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Generate a configuration"
|
42
|
+
def configuration(name)
|
43
|
+
BaseChip.load_environment
|
44
|
+
BaseChip.find_root(dir = nil)
|
45
|
+
@configuration_name = name
|
46
|
+
BaseChip.build_directory_structure(name,BaseChip.configuration_directories)
|
47
|
+
BaseChip.erb_template "#{BaseChip::GEM_DIR}/collateral/configuration/configuration.rb.erb", "#{BaseChip.root}/#{name}/base_chip/configuration.rb"
|
48
|
+
FileUtils.cd BaseChip.root
|
49
|
+
puts "configuration generation complete"
|
50
|
+
|
51
|
+
if options.git
|
52
|
+
system "git add ./#{name}"
|
53
|
+
system "git commit -m 'Initial automated configuration build of '#{name}' BaseChip.' ./#{name}"
|
54
|
+
|
55
|
+
normal "configuration '#{name}' has been created."
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "Generate a tool config file"
|
60
|
+
def tool(name)
|
61
|
+
puts "tool generation complete"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|