rook 0.0.2 → 0.1.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.
Files changed (87) hide show
  1. data/README.txt +124 -37
  2. data/bin/rook +8 -902
  3. data/doc-api/classes/BZ2.html +111 -0
  4. data/doc-api/classes/BZ2/Reader.html +234 -0
  5. data/doc-api/classes/Digest.html +107 -0
  6. data/doc-api/classes/Digest/Base.html +254 -0
  7. data/doc-api/classes/Enumerable.html +430 -0
  8. data/doc-api/classes/File.html +208 -0
  9. data/doc-api/classes/FileUtils.html +758 -0
  10. data/doc-api/classes/Kernel.html +317 -0
  11. data/doc-api/classes/Rook.html +148 -0
  12. data/doc-api/classes/Rook/Assertion.html +164 -0
  13. data/doc-api/classes/Rook/AssertionError.html +111 -0
  14. data/doc-api/classes/Rook/CommandOptionError.html +113 -0
  15. data/doc-api/classes/Rook/Commands.html +1158 -0
  16. data/doc-api/classes/Rook/Cookbook.html +357 -0
  17. data/doc-api/classes/Rook/CookbookError.html +161 -0
  18. data/doc-api/classes/Rook/CookbookValidator.html +215 -0
  19. data/doc-api/classes/Rook/Kitchen.html +875 -0
  20. data/doc-api/classes/Rook/KitchenHelper.html +386 -0
  21. data/doc-api/classes/Rook/Main.html +325 -0
  22. data/doc-api/classes/Rook/Parameters.html +443 -0
  23. data/doc-api/classes/Rook/Recipe.html +546 -0
  24. data/doc-api/classes/Rook/RookError.html +111 -0
  25. data/doc-api/classes/Rook/Util.html +408 -0
  26. data/doc-api/classes/Rook/Util/UndefinedPropertyError.html +160 -0
  27. data/doc-api/created.rid +1 -0
  28. data/doc-api/files/__/README_txt.html +313 -0
  29. data/doc-api/files/rook/commands_rb.html +115 -0
  30. data/doc-api/files/rook/cookbook_rb.html +115 -0
  31. data/doc-api/files/rook/helper/bz2_rb.html +114 -0
  32. data/doc-api/files/rook/helper/digest_rb.html +114 -0
  33. data/doc-api/files/rook/helper/enumerable_rb.html +107 -0
  34. data/doc-api/files/rook/helper/file_rb.html +107 -0
  35. data/doc-api/files/rook/helper/fileutils_rb.html +124 -0
  36. data/doc-api/files/rook/helper/kernel_rb.html +107 -0
  37. data/doc-api/files/rook/kitchen_rb.html +117 -0
  38. data/doc-api/files/rook/main_rb.html +117 -0
  39. data/doc-api/files/rook/recipe_rb.html +114 -0
  40. data/doc-api/files/rook/util_rb.html +115 -0
  41. data/doc-api/files/rook_rb.html +122 -0
  42. data/doc-api/fr_class_index.html +50 -0
  43. data/doc-api/fr_file_index.html +40 -0
  44. data/doc-api/fr_method_index.html +181 -0
  45. data/doc-api/index.html +24 -0
  46. data/doc-api/rdoc-style.css +208 -0
  47. data/examples/hello_c/Rookbook.rb +37 -0
  48. data/examples/hello_c/Rookbook.yaml +45 -0
  49. data/examples/hello_c/hello.c +6 -3
  50. data/examples/project/README.txt +8 -0
  51. data/examples/project/Rookbook.props +1 -0
  52. data/examples/project/Rookbook.rb +120 -0
  53. data/examples/project/Rookbook.yaml +117 -0
  54. data/examples/project/bin/example +12 -0
  55. data/examples/project/example.gemspec +29 -0
  56. data/examples/project/lib/example.rb +36 -0
  57. data/examples/{archive → project}/lib/example/bar.rb +0 -0
  58. data/examples/{archive → project}/lib/example/baz.rb +0 -0
  59. data/examples/{archive → project}/lib/example/foo.rb +0 -0
  60. data/examples/project/setup.rb +1331 -0
  61. data/examples/project/test/test.rb +27 -0
  62. data/lib/rook.rb +50 -0
  63. data/lib/rook/commands.rb +426 -0
  64. data/lib/rook/cookbook.rb +237 -0
  65. data/lib/rook/helper/bz2.rb +39 -0
  66. data/lib/rook/helper/digest.rb +76 -0
  67. data/lib/rook/helper/enumerable.rb +121 -0
  68. data/lib/rook/helper/file.rb +50 -0
  69. data/lib/rook/helper/fileutils.rb +340 -0
  70. data/lib/rook/helper/kernel.rb +108 -0
  71. data/lib/rook/kitchen.rb +668 -0
  72. data/lib/rook/main.rb +280 -0
  73. data/lib/rook/recipe.rb +259 -0
  74. data/lib/rook/rookbook.schema.yaml +156 -0
  75. data/lib/rook/util.rb +172 -0
  76. data/rook.gemspec +56 -0
  77. metadata +139 -45
  78. data/examples/archive/COPYING +0 -340
  79. data/examples/archive/README.txt +0 -1
  80. data/examples/archive/Rookbook +0 -56
  81. data/examples/archive/bin/example +0 -0
  82. data/examples/archive/doc/index.html +0 -0
  83. data/examples/archive/doc/index.txt +0 -0
  84. data/examples/archive/lib/example.rb +0 -0
  85. data/examples/archive/test/test1.rb +0 -0
  86. data/examples/archive/test/test2.rb +0 -0
  87. data/examples/hello_c/Rookbook +0 -24
@@ -0,0 +1,668 @@
1
+ ##
2
+ ## $Rev: 32 $
3
+ ## $Release: 0.1.0 $
4
+ ## copyright(c) 2006 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+
8
+ require 'abstract'
9
+ require 'rook/util'
10
+ require 'rook/cookbook'
11
+ require 'rook/recipe'
12
+
13
+
14
+
15
+ module Rook
16
+
17
+
18
+
19
+ ##
20
+ ## add functions for DSL (ruby-style cookbook)
21
+ ##
22
+ module KitchenHelper
23
+
24
+ private
25
+
26
+
27
+ ##
28
+ ## define a property in Rookbook.rb
29
+ ##
30
+ ## ex. (in Rookbook.rb)
31
+ ## property 'release', '1.0.0', :desc=>'release number'
32
+ ## property 'project', 'myapp'
33
+ ##
34
+ ## the above is equivarent to the following (in Rookbook.yaml):
35
+ ## properties:
36
+ ## - release : 1.0.0
37
+ ## :desc : 'release number'
38
+ ## - project : myapp
39
+ ##
40
+ ## this method define a global variable which name is the same as property name.
41
+ ## for example, global variables $release and $project are defined in above ex.
42
+ ##
43
+ ## property value can be overwrited by command-line option.
44
+ ##
45
+ ## ex. (in command-line)
46
+ ## $ rook --release=1.2.3 --project='myapp2'
47
+ ##
48
+ def property(name, value, options={}) # :doc:
49
+ hash = { 'name'=>name.to_s, 'value'=>value }
50
+ options.each { |name, value| hash[name.to_s] = value }
51
+ add_property(hash)
52
+ end
53
+
54
+ #--
55
+ #abstract_method 'hash', :add_property, :add_variable
56
+ #++
57
+
58
+ def add_property(hash)
59
+ not_implemented
60
+ end
61
+
62
+ def add_variable(hash)
63
+ not_implemented
64
+ end
65
+
66
+
67
+ ##
68
+ ## define a variable in Rookbook.rb
69
+ ##
70
+ ## ex. (in Rookbook.rb)
71
+ ## variable :srcdir, 'src'
72
+ ## variable :files, Dir.glob('src/*.rb')
73
+ ## variable :rook_product, :all
74
+ ##
75
+ ## the above code is equivalent to the following in Rookbook.yaml:
76
+ ## variables:
77
+ ## - srcdir : src
78
+ ## - files* : Dir.glob('src/*.rb')
79
+ ## - rook_product : :all
80
+ ##
81
+ def variable(name, value, options={}) # :doc:
82
+ hash = { 'name'=>name.to_s, 'value'=>value }
83
+ options.each { |name, value| hash[name.to_s] = value }
84
+ add_variable(hash)
85
+ end
86
+
87
+
88
+ ##
89
+ ## specify material (= non-products) in Rookbook.rb
90
+ ##
91
+ ## ex. (in Rookbook.rb)
92
+ ## material 'index.html'
93
+ ## material 'readme.html'
94
+ ##
95
+ ## the above is equivarent to the following in Rookbook.yaml:
96
+ ## materials:
97
+ ## - index.html
98
+ ## - readme.html
99
+ ##
100
+ def material(material_name) # :doc:
101
+ add_material(material_name)
102
+ end
103
+
104
+ #--
105
+ #abstract_method 'material_name', :add_material
106
+ #++
107
+
108
+
109
+ def add_material(material_name)
110
+ not_implemented
111
+ end
112
+
113
+
114
+
115
+ ##
116
+ ## specify description of recipe in Rookbook.rb
117
+ ##
118
+ ## ex. (in Rookbook.rb)
119
+ ## desc 'create *.o from *.c'
120
+ ## recipe '*.o', '$(1).c' do
121
+ ## sys "gcc -c #{@ingreds[0]}"
122
+ ## end
123
+ ##
124
+ ## the above is equivarent to the following in Rookbook.yaml:
125
+ ## recipes:
126
+ ## - product: *.o
127
+ ## desc: create *.o from *.c
128
+ ## ingreds: [ $(1).c ]
129
+ ## method: |
130
+ ## sys "gcc -c #{@ingreds[0]}"
131
+ ##
132
+ def desc(text) # :doc:
133
+ @_desc = text
134
+ end
135
+
136
+
137
+
138
+ ##
139
+ ## define a recipe in Rookbook.rb
140
+ ##
141
+ ## ex. (in Rookbook.rb)
142
+ ## recipe '*.o' , '$(1).c', :options=>['$(1).h'], :desc=>'compile *.c' do
143
+ ## sys "gcc -c #{@ingreds[0]}"
144
+ ## end
145
+ ##
146
+ ## the above is equivarent to the following in Rookbook.yaml:
147
+ ## recipes:
148
+ ## - product: *.o
149
+ ## ingreds: [ $(1).c ]
150
+ ## options: [ $(1).h ]
151
+ ## desc: compile *.c
152
+ ## method: |
153
+ ## sys "gcc -c #{@ingreds[0]}"
154
+ ##
155
+ ## return value is a recipe created.
156
+ ##
157
+ def recipe(product, *args, &block) # :doc:
158
+ hash = {}
159
+ if args[-1].is_a?(Hash)
160
+ args.pop.each do |key, val|
161
+ case key.to_s
162
+ when 'option', 'coprod', 'byprod'
163
+ hash[key.to_s + 's'] = [val]
164
+ else
165
+ hash[key.to_s] = val
166
+ end
167
+ end
168
+ end
169
+ hash['product'] = product
170
+ hash['ingreds'] = args.flatten
171
+ hash['block'] = block
172
+ if @_desc != nil
173
+ hash['desc'] = @_desc
174
+ @_desc = nil
175
+ end
176
+ r = Recipe.new(hash)
177
+ add_recipe(r)
178
+ return r
179
+ end
180
+
181
+
182
+ #--
183
+ #abstract_method 'product, *args, &block', :add_recipe
184
+ #++
185
+
186
+ def add_recipe(product, *args, &block)
187
+ not_implemented
188
+ end
189
+
190
+
191
+ end
192
+
193
+
194
+ class Parameters
195
+
196
+ def initialize
197
+ @_property_table = {}
198
+ @_variable_table = {}
199
+ end
200
+
201
+ def has_property?(name)
202
+ return @_property_table.key?(name.to_s)
203
+ end
204
+
205
+ def has_variable?(name)
206
+ return @_variable_table.key?(name.to_s)
207
+ end
208
+
209
+ def set_property(name, value)
210
+ name = name.to_s
211
+ return if has_property?(name) # cannot override
212
+ @_property_table[name] = value
213
+ instance_variable_set("@#{name}", value)
214
+ end
215
+
216
+ def set_variable(name, value)
217
+ @_variable_table[name.to_s] = value
218
+ end
219
+
220
+ def get_property(name)
221
+ return @_property_table[name.to_s]
222
+ end
223
+
224
+ def get_variable(name)
225
+ return @_variable_table[name.to_s]
226
+ end
227
+
228
+ def get_value(name)
229
+ name = name.to_s
230
+ return get_property(name) if has_property?(name) # allow overwrite variable by property
231
+ return get_variable(name) if has_variable?(name)
232
+ #if has_property?(name) || has_variable?(name)
233
+ # return _get(name)
234
+ #end
235
+ msg = "'$(#{name})': no such property nor variable."
236
+ #raise UndefinedPropertyError.new(msg, name)
237
+ raise RookError.new(msg)
238
+ end
239
+
240
+ def evaluate_value(value)
241
+ case value
242
+ when String
243
+ if value =~ /\A\$\(([a-zA-Z_]\w*)\)\z/
244
+ val = get_value($1)
245
+ else
246
+ val = value.gsub(/\$\(([a-zA-Z_]\w*)\)/) { get_value($1) }
247
+ end
248
+ when Array
249
+ list = value.collect { |val| evaluate_value(val) }
250
+ val = list
251
+ when Hash
252
+ hash = {}
253
+ value.each { |key, val| hash[key] = evaluate_value(val) }
254
+ val = hash
255
+ else
256
+ val = value
257
+ end
258
+ return val
259
+ end
260
+
261
+ def evaluate_expr(expr, filename='(expr)', linenum=1)
262
+ code = @_variable_table.keys.collect { |name| "#{name}=@_variable_table['#{name}'];" }
263
+ code << expr
264
+ return self.instance_eval(code.join, filename, linenum)
265
+ end
266
+
267
+ def property_names
268
+ return @_property_table.keys
269
+ end
270
+
271
+ def variable_names
272
+ return @_variable_table.keys
273
+ end
274
+
275
+ end
276
+
277
+
278
+
279
+
280
+ ##
281
+ ## kitchen class
282
+ ##
283
+ ## ex.
284
+ ## cookbooks, errors = Cookbook.load_yamlfile('Rookbook.yaml')
285
+ ## kitchen = Kitchen.new
286
+ ## cookbooks.each { |book| kitchen.load_book(book) }
287
+ ## kitchen.start_cooking('product_name')
288
+ ##
289
+ class Kitchen
290
+ include Assertion
291
+ include KitchenHelper
292
+
293
+
294
+ def initialize(properties={}, options={})
295
+ @parameters = Parameters.new
296
+ @properties = []
297
+ @variables = []
298
+ properties.each do |name, value|
299
+ add_property({'name'=>name.to_s, 'value'=>value})
300
+ end
301
+ @recipes = []
302
+ @recipe_table = {}
303
+ @materials = []
304
+ @precookings = []
305
+ @forced = options[:forced]
306
+ #@verbose = options[:verbose]
307
+ #@noexec = options[:noexec]
308
+ end
309
+ attr_reader :properties, :variables
310
+ attr_reader :materials, :precookings, :recipes
311
+ #attr_reader :forced, :quiet, :noexec
312
+
313
+
314
+ def has_property?(name)
315
+ return @parameters.has_property?(name)
316
+ end
317
+
318
+ def has_variable?(name)
319
+ return @parameters.has_variable?(name)
320
+ end
321
+
322
+ def get_property(name)
323
+ return @parameters.get_property(name)
324
+ end
325
+
326
+ def get_variable(name)
327
+ return @parameters.get_variable(name)
328
+ end
329
+
330
+ def load_books(cookbooks)
331
+ cookboos.each do |cookbook| load_book(cookbook) end
332
+ end
333
+
334
+
335
+ def load_book(cookbook)
336
+ b = cookbook
337
+ # precooking
338
+ b.precookings.each do |hash|
339
+ add_precooking(hash['code'], b.bookname, hash['linenum'])
340
+ end if b.precooking
341
+ # properties
342
+ b.properties.each do |hash|
343
+ hash['bookname'] = b.bookname
344
+ add_property(hash, b.bookname)
345
+ end if b.properties
346
+ # variables
347
+ b.variables.each do |hash|
348
+ hash['bookname'] = b.bookname
349
+ add_variable(hash, b.bookname)
350
+ end if b.variables
351
+ # materials
352
+ b.materials.each do |nonprod|
353
+ add_nonproduct(nonprod)
354
+ end if b.materials
355
+ # recipes
356
+ b.recipes.each do |hash|
357
+ hash = @parameters.evaluate_value(hash)
358
+ hash['bookname'] = b.bookname
359
+ recipe = Recipe.new(hash)
360
+ add_recipe(recipe)
361
+ end if b.recipes
362
+ end
363
+
364
+
365
+ def load_script(filename)
366
+ self.instance_eval File.read(filename), filename, 1
367
+ end
368
+
369
+ def load_script!(script, filename)
370
+ self.instance_eval script, filename, 1
371
+ end
372
+
373
+
374
+ def add_precooking(code_str, bookname='', linenum=1)
375
+ @precookings << [code_str, bookname, linenum]
376
+ Util.evaluate(code_str, bookname, linenum) # or instance_eval?
377
+ end
378
+
379
+
380
+ def add_property(hash, bookname='')
381
+ hash['access'] ||= 'public'
382
+ name = hash['name']
383
+ if @parameters.has_property?(name)
384
+ value = @parameters.get_property(name)
385
+ else
386
+ if hash.key?('value')
387
+ value = @parameters.evaluate_value(hash['value'])
388
+ elsif hash.key?('expr') || hash.key?('value*')
389
+ expr = hash.key?('expr') ? hash['expr'] : hash['value*']
390
+ expr = @parameters.evaluate_value(expr)
391
+ value = @valuemap.evaluate_expr(expr, bookname, hash['linenum'])
392
+ else
393
+ raise RookError.new("property '#{name}': no value.")
394
+ end
395
+ @parameters.set_property(name, value)
396
+ hash['value'] = value
397
+ @properties << hash
398
+ end
399
+ #eval "$#{name} = value"
400
+ end
401
+
402
+
403
+ def add_variable(hash, bookname='')
404
+ name = hash['name']
405
+ if @parameters.has_variable?(name)
406
+ @variables.delete_if { |h| h['name'] == name }
407
+ end
408
+ if hash.key?('value')
409
+ value = @parameters.evaluate_value(hash['value'])
410
+ elsif hash.key?('expr') || hash.key?('value*')
411
+ expr = hash.key?('expr') ? hash['expr'] : hash['value*']
412
+ linenum = hash['linenum'] || 1
413
+ expr = @parameters.evaluate_value(expr)
414
+ value = @parameters.evaluate_expr(expr, bookname, linenum)
415
+ else
416
+ raise RookError.new("variable '#{name}': no value.")
417
+ end
418
+ @parameters.set_variable(name, value)
419
+ hash['value'] = value
420
+ @variables << hash
421
+ end
422
+
423
+
424
+ def add_material(material_str)
425
+ mat_str = @parameters.evaluate_value(material_str)
426
+ @materials << mat_str
427
+ end
428
+
429
+
430
+ def add_recipe_hash(hash)
431
+ %w[ingreds byprods coprods options].each do |key|
432
+ if hash.key?("#{key}*")
433
+ val = hash.delete("#{key}*")
434
+ assert val.is_a?(String), "val.class=#{val.class}"
435
+ val = @parameters.evaluate_expr(val)
436
+ val = [ val ] unless val.is_a?(Array)
437
+ hash[key] = val
438
+ elsif hash.key?(key)
439
+ val = @parameters.evaluate_expr(val)
440
+ hash[key] = val
441
+ end
442
+ end
443
+ r = Recipe.new(hash['product'])
444
+ add_recipe(r)
445
+ end
446
+
447
+ def add_recipe(recipe)
448
+ @recipes.delete_if { |r| r.product == recipe.product } if @recipe_table[recipe.product]
449
+ @recipe_table[recipe.product] = recipe
450
+ @recipes << recipe
451
+ end
452
+
453
+
454
+ def find_generic_recipe(product)
455
+ return @recipes.find { |r| r.kind == 'generic' && r.match?(product) }
456
+ end
457
+
458
+
459
+ def find_specific_recipe(product)
460
+ return @recipes.find { |r| r.kind == 'specific' && r.match?(product) }
461
+ end
462
+
463
+
464
+ def find_recipe(product)
465
+ return find_specific_recipe(product) || find_generic_recipe(product)
466
+ end
467
+
468
+
469
+ def start_cooking(product)
470
+ cooking = Cooking.new(product)
471
+ begin
472
+ cook(product, cooking, 0)
473
+ rescue Exception => ex
474
+ log(ex.message, 0, nil, '*** ')
475
+ raise ex
476
+ end
477
+ end
478
+
479
+
480
+ ##
481
+ ## cook product
482
+ ##
483
+ ## return true when product recipe is invoked, else return false.
484
+ ##
485
+ def cook(product, cooking, level=0, verbose=nil, parent_fingerprint=false)
486
+ ## check
487
+ if @materials.include?(product)
488
+ log("skip '#{Util.to_str(product)}': material.", level, verbose)
489
+ return false
490
+ end
491
+ if cooking.cooked?(product)
492
+ log("skip '#{Util.to_str(product)}': already cooked.", level, verbose)
493
+ return false
494
+ end
495
+ if cooking.now_cooking?(product)
496
+ raise RookError.new("'#{Util.to_str(product)}': recipe is recursively looped.")
497
+ end
498
+
499
+ ## find recipe
500
+ recipe = find_recipe(product)
501
+ unless recipe
502
+ if product.is_a?(String) && test(?e, product)
503
+ log("skip '#{Util.to_str(product)}': raw ingredient.", level, verbose)
504
+ return false
505
+ else
506
+ raise RookError.new("'#{Util.to_str(product)}': recipe not found.")
507
+ end
508
+ end
509
+ recipe = recipe.to_specific(product)
510
+
511
+ ## start cooking
512
+ cooking.start(recipe)
513
+ log("begin '#{Util.to_str(product)}'", level, recipe.verbose?)
514
+ flag_exec = @forced
515
+
516
+ ## ingredients
517
+ ingreds = recipe.ingreds ? recipe.ingreds.dup : []
518
+ ingreds.concat(recipe.options.find_all { |f| test(?e, f) }) if recipe.options
519
+ # ingreds.each do |ingred|
520
+ # flag = cook(ingred, cooking, level+1, recipe.verbose?, recipe.fingerprint)
521
+ # flag_exec = true if flag
522
+ # end
523
+
524
+ ## execute when
525
+ ## * command-line option -F specified
526
+ ## * executed at least one recipe of ingredients
527
+ ## * recipe attribute 'forced' is true
528
+ ## * recipe is symbolic and has howoto part
529
+ ## * there isn't product
530
+ ## * recipe has no ingredient
531
+ ## * there is any ingredient which is newer than product
532
+ unless flag_exec
533
+ flag_exec ||= recipe.forced?
534
+ flag_exec ||= recipe.symbolic? && (recipe.method || recipe.block)
535
+ flag_exec ||= !recipe.symbolic? && !test(?e, product)
536
+ flag_exec ||= ingreds.empty? && (recipe.method || recipe.block)
537
+ end
538
+ unless flag_exec || ingreds.empty?
539
+ prod_mtime = File.mtime(product)
540
+ flag_exec = ingreds.any? { |f| f.is_a?(String) && test(?e, f) && prod_mtime < File.mtime(f) }
541
+ #unless flag_exec
542
+ # log("skip '#{Util.to_str(product)}': newer than all ingredients.", level, recipe.verbose?)
543
+ #end
544
+ end
545
+
546
+ ## invoke ingredients' recipe
547
+ #ingreds = recipe.ingreds ? recipe.ingreds.dup : []
548
+ #ingreds.concat(recipe.options.find_all { |f| test(?e, f) }) if recipe.options
549
+ ingreds.each do |ingred|
550
+ flag = cook(ingred, cooking, level+1, recipe.verbose?, recipe.fingerprint)
551
+ flag_exec = true if flag
552
+ end
553
+
554
+ unless flag_exec || ingreds.empty?
555
+ log("skip '#{Util.to_str(product)}': newer than all ingredients.", level, recipe.verbose?)
556
+ end
557
+
558
+ ## execute method part
559
+ fingerprint_value = nil
560
+ if flag_exec
561
+ flag_fp = parent_fingerprint == 'ingreds' || recipe.fingerprint == 'product'
562
+ if flag_fp && test(?f, product)
563
+ fingerprint_value = Util.fingerprint(product)
564
+ end
565
+ report(product, level, recipe.verbose?)
566
+ begin
567
+ recipe.invoke(@parameters)
568
+ rescue => ex
569
+ prods = [ recipe.product ]
570
+ prods += recipe.coprods if recipe.coprods
571
+ prods.each do |file|
572
+ next unless file.is_a?(String) && test(?f, file)
573
+ log("removing '#{file}' because of #{ex.class.name} - #{ex.message}", level, true)
574
+ File.unlink(file)
575
+ end
576
+ raise ex
577
+ end
578
+ end
579
+
580
+ ## validate whether product is generated
581
+ unless recipe.symbolic? || test(?e, product)
582
+ raise RookError.new("product '#{Util.to_str(product)}': not generated")
583
+ end
584
+
585
+ ## fingerprint check
586
+ if fingerprint_value
587
+ fp1 = fingerprint_value
588
+ fp2 = Util.fingerprint(product)
589
+ op = fp1 == fp2 ? '==' : '!='
590
+ log("fingerprint of #{product}: #{fp1} #{op} #{fp2}", level, recipe.verbose?)
591
+ flag_exec = false if fp1 == fp2
592
+ end
593
+
594
+ ## finish cooking
595
+ log("end '#{Util.to_str(product)}'", level, recipe.verbose?)
596
+ cooking.finish(recipe)
597
+ return flag_exec
598
+
599
+ end
600
+
601
+
602
+ private
603
+
604
+
605
+ def log(mesg, level, verbose=nil, prompt='# ')
606
+ #flag = verbose.nil? ? @verbose == true : verbose
607
+ flag = verbose.nil? ? $rook_verbose == true : verbose
608
+ _puts(prompt + (' ' * level) + mesg) if flag
609
+ end
610
+
611
+
612
+ def report(product, level, verbose=nil)
613
+ #flag = verbose.nil? ? @verbose != false : verbose
614
+ flag = verbose.nil? ? $rook_verbose != false : verbose
615
+ str = Util.to_str(product)
616
+ _puts("### #{'*' * (level+1)} #{str}") if verbose || $rook_verbose != false
617
+ end
618
+
619
+
620
+ def _puts(str)
621
+ puts str
622
+ end
623
+
624
+
625
+ end
626
+
627
+
628
+
629
+ class Cooking #:nodoc:
630
+
631
+
632
+ def initialize(goal_product)
633
+ @goal_product = goal_product
634
+ @cooked = {}
635
+ @now_cooking = {}
636
+ end
637
+ attr_reader :goal_product, :cooked
638
+
639
+
640
+ def cooked?(product)
641
+ return @cooked.key?(product)
642
+ end
643
+
644
+
645
+ def now_cooking?(product)
646
+ return @now_cooking.key?(product)
647
+ end
648
+
649
+
650
+ def start(recipe)
651
+ recipe.all_products.each do |prod|
652
+ @now_cooking[prod] = recipe
653
+ end
654
+ end
655
+
656
+
657
+ def finish(recipe)
658
+ recipe.all_products.each do |prod|
659
+ @cooked[prod] = @now_cooking.delete(prod)
660
+ end
661
+ end
662
+
663
+
664
+ end
665
+
666
+
667
+
668
+ end