ratch 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/bin/ratch +60 -47
  2. data/bin/ratch-find +21 -0
  3. data/demo/{README → XR} +0 -0
  4. data/demo/task/stats +0 -2
  5. data/doc/images/clipboard.jpg +0 -0
  6. data/doc/images/clipboard2.png +0 -0
  7. data/doc/images/milles-tn.jpg +0 -0
  8. data/doc/images/mints.png +0 -0
  9. data/doc/images/ratch2.png +0 -0
  10. data/doc/images/ruby-sm.png +0 -0
  11. data/doc/images/silver.gif +0 -0
  12. data/doc/images/toolbox.jpg +0 -0
  13. data/doc/index.html +181 -0
  14. data/doc/notes/original.rb +308 -0
  15. data/doc/rdoc/classes/Array.html +194 -0
  16. data/doc/rdoc/classes/Dir.html +317 -0
  17. data/doc/rdoc/classes/Hash.html +217 -0
  18. data/doc/rdoc/classes/Ratch.html +201 -0
  19. data/doc/rdoc/classes/Ratch/ArgvUtils.html +173 -0
  20. data/doc/rdoc/classes/Ratch/ArgvUtils/Ext.html +285 -0
  21. data/doc/rdoc/classes/Ratch/BatchFile.html +207 -0
  22. data/doc/rdoc/classes/Ratch/BatchManager.html +250 -0
  23. data/doc/rdoc/classes/Ratch/BatchScript.html +127 -0
  24. data/doc/rdoc/classes/Ratch/Batchable.html +373 -0
  25. data/doc/rdoc/classes/Ratch/Build.html +321 -0
  26. data/doc/rdoc/classes/Ratch/BuildManager.html +319 -0
  27. data/doc/rdoc/classes/Ratch/Buildable.html +202 -0
  28. data/doc/rdoc/classes/Ratch/ConfigUtils.html +281 -0
  29. data/doc/rdoc/classes/Ratch/ConsoleUtils.html +189 -0
  30. data/doc/rdoc/classes/Ratch/EmailUtils.html +209 -0
  31. data/doc/rdoc/classes/Ratch/FileUtils.html +674 -0
  32. data/doc/rdoc/classes/Ratch/GeneralOptions.html +430 -0
  33. data/doc/rdoc/classes/Ratch/Task.html +201 -0
  34. data/doc/rdoc/classes/Ratch/TaskManager.html +330 -0
  35. data/doc/rdoc/classes/Ratch/Taskable.html +231 -0
  36. data/doc/rdoc/classes/Ratch/UploadUtils.html +566 -0
  37. data/doc/rdoc/created.rid +1 -0
  38. data/doc/rdoc/files/COPYING.html +1003 -0
  39. data/{demo/doc → doc}/rdoc/files/README.html +36 -5
  40. data/doc/rdoc/files/lib/ratch/argvutils_rb.html +131 -0
  41. data/doc/rdoc/files/lib/ratch/batch_rb.html +155 -0
  42. data/doc/rdoc/files/lib/ratch/batchable_rb.html +131 -0
  43. data/doc/rdoc/files/lib/ratch/batchfile_rb.html +148 -0
  44. data/doc/rdoc/files/lib/ratch/buildable_rb.html +131 -0
  45. data/doc/rdoc/files/lib/ratch/consoleutils_rb.html +131 -0
  46. data/{demo/doc/rdoc/files/lib/foo/foo_rb.html → doc/rdoc/files/lib/ratch/emailutils_rb.html} +35 -41
  47. data/doc/rdoc/files/lib/ratch/facets/multiglob_rb.html +137 -0
  48. data/doc/rdoc/files/lib/ratch/fileutils_rb.html +139 -0
  49. data/doc/rdoc/files/lib/ratch/options_rb.html +131 -0
  50. data/doc/rdoc/files/lib/ratch/taskable_rb.html +131 -0
  51. data/doc/rdoc/files/lib/ratch/uploadutils_rb.html +150 -0
  52. data/doc/rdoc/fr_class_index.html +48 -0
  53. data/doc/rdoc/fr_file_index.html +41 -0
  54. data/doc/rdoc/fr_method_index.html +133 -0
  55. data/{demo/doc → doc}/rdoc/index.html +1 -1
  56. data/{demo/doc → doc}/rdoc/rdoc-style.css +0 -0
  57. data/doc/scrap/flexihead-flip.jpg +0 -0
  58. data/doc/scrap/flexihead.jpg +0 -0
  59. data/doc/scrap/head1.jpg +0 -0
  60. data/doc/scrap/ratch.jpg +0 -0
  61. data/doc/scrap/ratch1.png +0 -0
  62. data/doc/scrap/ratch2.jpg +0 -0
  63. data/doc/scrap/ratch3.png +0 -0
  64. data/doc/scrap/red-ratch.jpg +0 -0
  65. data/doc/scrap/redratchet.jpg +0 -0
  66. data/doc/scrap/ruby-kit/ruby.png +0 -0
  67. data/doc/scrap/scrap.red +256 -0
  68. data/doc/sitemap.yaml +10 -0
  69. data/doc/siteparts/index.red +100 -0
  70. data/doc/siteparts/layout.rhtml +56 -0
  71. data/doc/siteparts/tutorial.red +578 -0
  72. data/doc/style.css +112 -0
  73. data/doc/tutorial.html +722 -0
  74. data/lib/ratch/batch.rb +417 -30
  75. data/lib/ratch/{argvutils.rb → batch/argvutils.rb} +27 -19
  76. data/lib/ratch/batch/build.rb +95 -0
  77. data/lib/ratch/{consoleutils.rb → batch/consoleutils.rb} +0 -0
  78. data/lib/ratch/{emailutils.rb → batch/emailutils.rb} +0 -0
  79. data/lib/ratch/{fileutils.rb → batch/fileutils.rb} +32 -32
  80. data/lib/ratch/{options.rb → batch/options.rb} +0 -0
  81. data/lib/ratch/batch/task.rb +43 -0
  82. data/lib/ratch/manager.rb +34 -0
  83. data/lib/ratch/project/information.rb +257 -0
  84. data/lib/ratch/project/package.rb +82 -0
  85. data/lib/ratch/project/project.rb +531 -0
  86. data/lib/ratch/project/release.rb +112 -0
  87. data/lib/ratch/support/filetest.rb +29 -0
  88. data/lib/ratch/support/setuputils.rb +124 -0
  89. data/lib/ratch/support/signiture.rb +252 -0
  90. data/lib/ratch/support/stage.rb +292 -0
  91. data/lib/ratch/toolset/ruby/pack/gem +85 -0
  92. data/lib/ratch/toolset/ruby/pack/tgz +85 -0
  93. data/lib/ratch/toolset/ruby/{crosstest → test/crosstest} +0 -0
  94. data/lib/ratch/toolset/ruby/{extest → test/extest} +0 -0
  95. data/lib/ratch/toolset/ruby/{isotest → test/isotest} +0 -0
  96. data/lib/ratch/toolset/ruby/{load → test/load} +0 -0
  97. data/lib/ratch/toolset/ruby/{loadtest → test/loadtest} +0 -0
  98. data/lib/ratch/toolset/ruby/{syntax → test/syntax} +0 -0
  99. data/lib/ratch/toolset/ruby/{test → test/test} +0 -0
  100. data/log/{history.rd → history} +6 -0
  101. data/log/{todo.rd → todo} +0 -0
  102. data/meta/MANIFEST +52 -36
  103. data/meta/ROLLRC +2 -0
  104. data/meta/icli.yaml +16 -0
  105. data/meta/{ratch-0.2.3.roll → project.yaml} +1 -7
  106. data/task/release +12 -0
  107. data/{lib/ratch → work/old}/batchfile.rb +0 -0
  108. data/work/project-old.rb +67 -0
  109. data/work/scrap/install +89 -0
  110. data/work/scrap/install.0 +49 -0
  111. data/work/scrap/install.1 +63 -0
  112. data/work/scrap/ludo +25 -0
  113. data/work/scrap/oldtaskable.rb +573 -0
  114. data/work/scrap/ratch.man +39 -0
  115. data/work/scrap/taskable-simple.rb +42 -0
  116. data/work/scrap/taskable.rb +120 -0
  117. metadata +170 -72
  118. data/demo/doc/rdoc/created.rid +0 -1
  119. data/demo/doc/rdoc/fr_class_index.html +0 -26
  120. data/demo/doc/rdoc/fr_file_index.html +0 -28
  121. data/demo/doc/rdoc/fr_method_index.html +0 -27
  122. data/demo/task/config.yaml +0 -2
  123. data/lib/ratch/batchable.rb +0 -169
  124. data/lib/ratch/buildable.rb +0 -182
  125. data/lib/ratch/configutils.rb +0 -132
  126. data/lib/ratch/facets/multiglob.rb +0 -160
  127. data/lib/ratch/taskable.rb +0 -152
  128. data/log/recent.rd +0 -8
  129. data/task/config.yaml +0 -10
@@ -1,8 +1,8 @@
1
- # TITLE:
1
+ # = TITLE:
2
2
  #
3
3
  # BatchFile
4
4
  #
5
- # COPYING:
5
+ # = COPYING:
6
6
  #
7
7
  # Copyright (c) 2007 Psi T Corp.
8
8
  #
@@ -26,76 +26,463 @@ require 'yaml'
26
26
  require 'rbconfig' # replace with facets/rbsystem in future ?
27
27
  #require 'facets/hash/merge' # for reverse_merge
28
28
 
29
- require 'ratch/options'
29
+ require 'ratch/batch/options'
30
30
 
31
- require 'ratch/consoleutils'
32
- require 'ratch/configutils'
33
- require 'ratch/emailutils'
34
- require 'ratch/fileutils'
35
- require 'ratch/argvutils'
31
+ require 'ratch/batch/consoleutils'
32
+ require 'ratch/batch/configutils'
33
+ require 'ratch/batch/emailutils'
34
+ require 'ratch/batch/fileutils'
35
+ require 'ratch/batch/argvutils'
36
36
 
37
- require 'ratch/taskable'
38
- require 'ratch/buildable'
39
- require 'ratch/batchable'
37
+ require 'ratch/batch/task'
38
+ require 'ratch/batch/build'
40
39
 
41
40
 
42
41
  module Ratch
43
42
 
43
+ # If no batch file is found.
44
+
45
+ class NoBatchError < Exception
46
+ end
47
+
48
+ # This is a type of functor, that allows for calling batch files
49
+ # that are in subdirectories using "dir.file" notation. Eg.
50
+ #
51
+ # svn.log
52
+ #
53
+ # could run the svn/log ratch file.
54
+
55
+ class BatchDirectory
56
+ private *instance_methods.select{ |m| m !~ /^__/ }
57
+
58
+ def initialize(manager, directory)
59
+ @manager = manager
60
+ @directory = directory
61
+ end
62
+
63
+ def method_missing(sym, *args)
64
+ path = File.join(@directory, sym.to_s)
65
+ @manager.open_batch(path, *args)
66
+ end
67
+ end
68
+
44
69
  # BatchScript module defines the DSL available to a ratch script.
45
70
 
46
71
  module BatchScript #< Module
47
72
 
48
73
  include GeneralOptions
49
-
50
74
  include ConsoleUtils
51
75
  include ArgvUtils
52
76
  include FileUtils
53
77
  include ConfigUtils
54
78
  include EmailUtils
55
79
 
56
- include Buildable
57
- include Taskable
58
- include Batchable
80
+ # Shell runner.
59
81
 
60
- # Quick start, equivalent to calling new.run(file).
82
+ def sh(cmd)
83
+ if noharm?
84
+ puts cmd
85
+ true
86
+ else
87
+ puts "--> system call: #{cmd}" if trace?
88
+ system(cmd)
89
+ end
90
+ end
91
+
92
+ # Abort running.
93
+ #def abort(msg=nil)
94
+ # puts msg if msg
95
+ # exit 0
96
+ #end
97
+
98
+ def root_directory
99
+ @root_directory ||= Dir.pwd
100
+ end
101
+
102
+ def call_directory
103
+ @call_directory ||= File.expand_path(File.dirname($0))
104
+ end
105
+
106
+ # TODO Better name? Better definition? (Won't handle task subdirs!).
107
+
108
+ def batch_directory
109
+ @batch_directory ||= (
110
+ dir = call_directory.sub(root_directory + '/', '').split('/').first
111
+ File.join(root_directory, dir)
112
+ )
113
+ end
114
+
115
+ # Run batch file and cache result.
116
+ #
117
+ # Usually this can be taken care of by method_missing.
118
+ # But, in some cases, built in method names block batch
119
+ # calls, so you have to use #batch to invoke those.
120
+
121
+ def batch(batchfile, arguments=nil)
122
+ batch_cache[batchfile] ||= launch(batchfile, arguments)
123
+ end
124
+
125
+ # Lauch a batch file. Like #batch but not-cached.
126
+ # Run a batch file.
127
+ # TODO: How to handle arguments?
128
+
129
+ def launch(batchfile, arguments=nil)
130
+ # # TODO probably should raise error instead
131
+ # abort "missing batch file -- #{batchfile}" unless File.file?(batchfile)
132
+
133
+ #BatchFile.new(batchfile).call # Old way with batch execution context object.
134
+ script = File.read($0 = batchfile)
135
+ #eval(script, $batch_binding, $0)
136
+ eval(script, TOPLEVEL_BINDING, $0)
137
+
138
+ batch_file = File.expand_path($0).sub(batch_directory + '/', '')
139
+ call_task(batch_file)
140
+ end
141
+
142
+ # Is a path a local batch directory?
143
+
144
+ def batch_directory?(path)
145
+ b = File.dirname($0) + "/#{path}"
146
+ b if FileTest.directory?(b)
147
+ end
148
+
149
+ # Is a file a local batch file?
150
+
151
+ def batch?(path)
152
+ b = File.dirname($0) + "/#{path}" #.chomp!('!')
153
+ b if FileTest.file?(b) && FileTest.executable?(b)
154
+ end
155
+
156
+ # Is a batch run complete or in the process of being completed?
157
+ # Has the batch file been executed before?
158
+
159
+ def done?(batchfile)
160
+ batchfile == $0 || batch_cache.key?(batchfile)
161
+ end
162
+
163
+ # Batch cache, which prevents batch runs from re-executing.
164
+
165
+ def batch_cache
166
+ @batch_cache ||= {}
167
+ end
168
+
169
+ # If method is missing try to run an external task
170
+ # or binary by that name. If it is a binary, arguments
171
+ # translate into commandline parameters. For example:
172
+ #
173
+ # tar 'foo/', :x=>true, :v=>true, :z=>true, :f=>'foo.tar.gz'
174
+ #
175
+ # or
176
+ #
177
+ # tar '-xvzf', "foo.tar.gz", "foo/"
178
+ #
179
+ # becomes
180
+ #
181
+ # tar -x -v -z -f foo.tar.gz foo/
182
+ #
183
+ # If it is a task, it will be cached. Tasks only ever run once.
184
+ # To run them more than once you can manually execute them with #run.
185
+ # Likewise you can manually run and cache by calling #batch.
186
+ # This is good to know, b/c in some cases built in method names
187
+ # block task calls, so you have to #batch to invoke them.
188
+
189
+ def method_missing(sym,*args)
190
+ puts "method_missing: #{sym}" if debug?
191
+ #begin
192
+ open_batch(sym,*args)
193
+ #rescue NoBatchError
194
+ # super
195
+ #end
196
+ end
197
+
198
+ private
199
+
200
+ #
201
+
202
+ def open_batch(name, *args)
203
+ name = name.to_s
204
+ force = name.chomp!('!')
205
+
206
+ # is this a batch directory?
207
+ if dir = batch_directory?(name)
208
+ return BatchDirectory.new(self, dir)
209
+ end
210
+
211
+ params = args.to_params
212
+
213
+ # is this a batch file?
214
+ if bat = batch?(name)
215
+ if force
216
+ cmd = "./#{bat} #{params}"
217
+ puts "--> non-cached execution: #{cmd}" if trace?
218
+ return launch(bat, args)
219
+ else
220
+ if done?(bat)
221
+ return nil unless bin?(name) # return cache?
222
+ else
223
+ cmd = "./#{bat} #{params}"
224
+ puts "--> cached execution: #{cmd}" if trace?
225
+ return batch(bat, args)
226
+ end
227
+ end
228
+ end
229
+
230
+ # is this a bin file?
231
+ if bin = bin?(name)
232
+ cmd = "#{File.basename(bin)} #{params}"
233
+ return sh(cmd)
234
+ end
235
+
236
+ raise NoBatchError, "no extecutable file found -- #{name}"
237
+ end
238
+
239
+ public
240
+
241
+ # Define main task.
242
+
243
+ def main(name, &block)
244
+ name, deps, block = *parse_task_dependencies(name, &block)
245
+ define_main(name, *deps, &block)
246
+ end
247
+
248
+ # Define a task.
249
+
250
+ def task(name, &block)
251
+ name, deps, block = *parse_task_dependencies(name, &block)
252
+ define_task(name, *deps, &block)
253
+ end
254
+
255
+ # Run a task.
256
+
257
+ def run(name, arguments=nil)
258
+ call_task(name)
259
+ end
61
260
 
261
+ private
262
+
263
+ def tasks ; @tasks ||= {} ; end
264
+
265
+ # TODO If @main is nil try task by same name a file (?)
266
+
267
+ def main_task
268
+ @main
269
+ end
270
+
271
+ #
272
+
273
+ def parse_task_dependencies(name_deps, &block)
274
+ if Hash===name_deps
275
+ name = name_deps.keys[0]
276
+ deps = name_deps.values[0]
277
+ else
278
+ name = name_deps
279
+ deps = []
280
+ end
281
+ [name, deps, block]
282
+ end
283
+
284
+ def define_main(name=nil, *depend, &block)
285
+ @main = define_task(name, *depend, &block)
286
+ #@main = Task.new(name, *depend, &block)
287
+ #tasks[@main.name] = @main
288
+ end
289
+
290
+ def define_task(name, *depend, &block)
291
+ task = Task.new(name, *depend, &block)
292
+ tasks[task.name] = task
293
+ end
294
+
295
+ # Call main task.
296
+
297
+ def call_main #(task=nil)
298
+ #@main ||= task
299
+ #return unless @main || task
300
+ call_task(main_task.name)
301
+ end
302
+
303
+ # Call task.
304
+
305
+ def call_task(name)
306
+ task_plan(name).each{ |name| tasks[name].call }
307
+ end
308
+
309
+ # Prepare plan, checking for circular dependencies.
310
+
311
+ def task_plan(name, list=[])
312
+ if list.include?(name)
313
+ raise "Circular dependency #{name}."
314
+ end
315
+ if task = tasks[name]
316
+ task.needs.each do |need|
317
+ need = need.to_s
318
+ next if list.include?(need)
319
+ #@tasks[need].task_plan(need, list)
320
+ task_plan(need, list)
321
+ end
322
+ list << task.name
323
+ else
324
+ # TODO THIS TIES TASKS INTO BATCH, BETTER WAY?
325
+ if name != main_task && fname = batch?(name)
326
+ task = Task.new(name) do
327
+ batch(fname)
328
+ end
329
+ tasks[name] = task
330
+ list << task.name
331
+ else
332
+ abort "no task -- #{name}"
333
+ end
334
+ end
335
+ return list
336
+ end
337
+
338
+ public
339
+
340
+ # Define a build target.
341
+
342
+ def file(name, &block)
343
+ name, deps, block = *parse_build_dependencies(name, &block)
344
+ define_file(name, *deps, &block)
345
+ end
346
+
347
+ # Build target(s).
348
+
349
+ def build(file)
350
+ call_build(file)
351
+ end
352
+
353
+ private
354
+
355
+ def builds; @builds ||= [] ; end
356
+
357
+ #
358
+ def parse_build_dependencies(name_deps, &block)
359
+ if Hash===name_deps
360
+ name = name_deps.keys[0]
361
+ deps = name_deps.values[0]
362
+ else
363
+ name = name_deps
364
+ deps = []
365
+ end
366
+ [name, deps, block]
367
+ end
368
+
369
+ # Define a file build task.
370
+
371
+ def define_file(name, *depend, &block)
372
+ build = Build.new(name, *depend, &block)
373
+ builds << build
374
+ end
375
+
376
+ # Call build.
377
+
378
+ def call_build(path)
379
+ # TODO How to handle more than one matching means of building?
380
+ #warn "More than one build definition matches #{path} using #{means.first}" if means.size > 1
381
+ if build = find(path)
382
+ if build.needed_for?(path) || force?
383
+ list, todo = *build_plan(build, path)
384
+ todo.each{|bld, pth| bld.call(pth) } #@builds[name].call }
385
+ build.call(path)
386
+ end
387
+ else
388
+ raise "build not found -- #{path}"
389
+ end
390
+ end
391
+
392
+ def find(path)
393
+ builds.find{ |b| b.match?(path) }
394
+ end
395
+
396
+ # Prepare build plan, checking for circular dependencies.
397
+
398
+ def build_plan(build, path, list=[], todo=[])
399
+ #if list.include?(build)
400
+ # raise "Circular build dependency #{build.name}."
401
+ #end
402
+
403
+ build.needed_paths.each do |npath|
404
+ next if list.include?(npath)
405
+ if nbuild = find(npath)
406
+ build_plan(nbuild, npath, list, todo)
407
+ todo << [nbuild, npath]
408
+ else
409
+ list << npath
410
+ end
411
+ end
412
+
413
+ return list, todo
414
+ end
415
+
416
+
417
+ # OLD WAY
418
+ # def method_missing(sym,*args)
419
+ # name = sym.to_s
420
+ #
421
+ # bat = batch?(name) # is this a batch file?
422
+ # done = bat && done?(bat)
423
+ # cache = bat && !done && name[1,-1] != '!'
424
+ # bin = bin?(name) if (!bat || done)
425
+ # none = bat && done && !bin
426
+ # #bat = name if bin
427
+ #
428
+ # return super unless bat || bin
429
+ #
430
+ # return if none # nothing to do
431
+ #
432
+ # params = args.to_params
433
+ #
434
+ # if bin
435
+ # cmd = "#{File.basename(bin)} #{params}"
436
+ # res = sh(cmd)
437
+ # elsif bat
438
+ # cmd = "./#{bat} #{params}"
439
+ # puts "--> #{cache ? '' : 'not-'}cached execution: #{cmd}" if trace?
440
+ # res = batch(bat, args)
441
+ # if cache
442
+ # #@batch_catch[bat] ||= (system(cmd); true)
443
+ # #batch_cache[bat] ||= res
444
+ # batch_manager.cache ||= res
445
+ # end
446
+ # end
447
+ #
448
+ # return res
449
+
450
+
451
+ # Quick start, equivalent to calling new.run(file).
62
452
  #def self.start(file)
63
453
  # new(file).call
64
454
  #end
65
455
 
66
456
  # New Batch File
67
-
68
457
  #def initialize(file)
69
458
  # abort "missing batch file -- #{file}" unless File.file?(file)
70
459
  # @file = file
71
460
  #end
72
461
 
73
462
  # TODO What todo about arguments?
74
-
75
463
  #def call(arguments=nil)
76
464
  # script = File.read($0 = @file)
77
- #puts script
78
- #p $0
79
- #puts
80
- # eval(script, binding, $0) #instance_eval(script)
81
- # #@main.call if @main
82
- # task_manager.call_main
83
- # #run(:main) if task_manager.main
84
- # end
465
+ # eval(script, binding, $0) #instance_eval(script)
466
+ # #@main.call if @main
467
+ # call_main
468
+ # #run(:main) if task_manager.main
469
+ # end
85
470
 
86
471
  end
87
472
 
88
473
  end
89
474
 
90
- # Load BatchScript into to main runspace.
475
+ # Load BatchScript into to toplevel.
91
476
  #
92
477
  # TODO: Should this be in all Object space (ie. no class << self)?
478
+
93
479
  class << self
94
480
  include Ratch::BatchScript
95
481
  end
96
482
 
97
- $batch_binding = binding
98
-
99
483
  END {
100
- task_manager.call_main
484
+ #task = File.expand_path($0).sub(batch_directory + '/', '')
485
+ call_main #(task)
101
486
  }
487
+
488
+ #$batch_binding = binding