ratch 0.2.3 → 0.3.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 (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