rook 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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