ratch 0.1 → 0.2.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.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ratch
2
+
3
+ # Load check all libs.
4
+
5
+ #
6
+
7
+ require 'benchmark'
8
+
9
+ $:.unshift('lib')
10
+
11
+ scripts_core, scripts_more = [], []
12
+ Dir.chdir('lib') do
13
+ scripts_more = glob('facets/*.rb')
14
+ scripts_more.collect!{ |s| File.expand_path(s) }
15
+ scripts_more.uniq!
16
+
17
+ scripts_core = glob('facets/*/*.rb')
18
+ scripts_core.collect!{ |s| File.expand_path(s) }
19
+ scripts_core.uniq!
20
+ end
21
+
22
+ $VERBOSE = nil
23
+
24
+ def require_scripts(scripts)
25
+ scripts.each do |file|
26
+ begin
27
+ require file
28
+ rescue Exception => e
29
+ puts file
30
+ puts e.message
31
+ end
32
+ end
33
+ end
34
+
35
+ Benchmark.bm do |x|
36
+ x.report("core"){ require_scripts(scripts_core) }
37
+ x.report("more"){ require_scripts(scripts_more) }
38
+ end
39
+
File without changes
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ratch
2
+
3
+ # Publish website to rubyforge
4
+ #
5
+ # This task publishes the source dir (deafult 'doc/site')
6
+ # to a rubyforge website.
7
+
8
+ main :publish do
9
+ config = configuration['publish']
10
+
11
+ project = config['project']
12
+ subdir = config['subdir']
13
+ source = config['source'] || "doc/site"
14
+ username = config['username']
15
+ protect = %w{usage statcvs statsvn robot.txt wiki}
16
+ exclude = %w{.svn}
17
+
18
+ abort "no project" unless project
19
+ abort "no username" unless username
20
+
21
+ if subdir
22
+ destination = File.join(project, subdir)
23
+ else
24
+ destination = project
25
+ end
26
+
27
+ dir = source.chomp('/') + '/'
28
+ url = "#{username}@rubyforge.org:/var/www/gforge-projects/#{destination}"
29
+
30
+ op = ['-rLvz', '--delete'] # maybe -p ?
31
+
32
+ # add filter options. The commandline version didn't seem
33
+ # to work, so I opted for creating an .rsync_filter file for
34
+ # all cases.
35
+
36
+ filter_file = File.join(source,'.rsync-filter')
37
+
38
+ unless file?(filter_file)
39
+ File.open(filter_file, 'w') do |f|
40
+ exclude.map{|e| f << "- #{e}\n"}
41
+ protect.map{|e| f << "P #{e}\n"}
42
+ end
43
+ end
44
+
45
+ op << "--filter='dir-merge #{filter_file}'"
46
+
47
+ #if file?(filter_file)
48
+ # op << "--filter='dir-merge #{filter_file}'"
49
+ #else # NOT WORKING?
50
+ # op.concat exclude.map{|e| "--filter='- #{e}'"}
51
+ # op.concat protect.map{|e| "--filter='P #{e}'"}
52
+ #end
53
+
54
+ args = op + [dir, url]
55
+
56
+ rsync(*args.to_params)
57
+ end
58
+
File without changes
File without changes
File without changes
data/dev/install ADDED
@@ -0,0 +1,89 @@
1
+ # Magic Rollerball Installer
2
+ #
3
+ #
4
+
5
+ PROJECT_NAME = 'multiton'
6
+ PROJECT_VERSION = '2.1.0'
7
+
8
+ ##################
9
+
10
+ require 'fileutils'
11
+ require 'rbconfig'
12
+
13
+ include FileUtils::DryRun
14
+
15
+
16
+ rubyprefix = Config::CONFIG['prefix']
17
+ sitelibdir = Config::CONFIG['sitelibdir']
18
+
19
+
20
+ PREFIX = ENV['PREFIX'] || rubyprefix
21
+
22
+ RUBYLIB = if PREFIX == rubyprefix then
23
+ sitelibdir
24
+ else
25
+ File.join(PREFIX, sitelibdir[rubyprefix.size..-1])
26
+ end
27
+
28
+ ROLLLIB = File.join(File.dirname(RUBYLIB), "rolls", File.basename(RUBYLIB))
29
+
30
+ RUBY_DEBUG = ENV['RUBY_DEBUG']
31
+ RUBY_FLAGS = ENV['RUBY_FLAGS'] ||
32
+ "-w -I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}" +
33
+ (RUBY_DEBUG ? " #{RUBY_DEBUG}" : '')
34
+
35
+ p PREFIX
36
+ p RUBYLIB
37
+ p ROLLLIB
38
+ #p RUBY_DEBUG
39
+ #p RUBY_FLAGS
40
+
41
+ HERE = File.expand_path(File.dirname(__FILE__))
42
+ DEST = File.join(ROLLLIB, PROJECT_NAME, PROJECT_VERSION)
43
+
44
+ files = Dir.glob("**/*")
45
+ files -= Dir.glob("INSTALL")
46
+ files -= Dir.glob("pkg/**/*") + ['pkg']
47
+
48
+ p HERE
49
+ p DEST
50
+ p files
51
+
52
+ mkdir_p DEST unless test ?d, DEST
53
+
54
+
55
+ # Install libs
56
+
57
+ def project_install(files)
58
+ bin_files = files.grep(/^bin/)
59
+
60
+ (files - bin_files).each do |file|
61
+ install file, DEST, :mode => 0444
62
+ end
63
+
64
+ bin_files.each do |file|
65
+ install file, DEST, :mode => 0555
66
+ end
67
+ end
68
+
69
+
70
+ # Change modes
71
+
72
+ def project_chmod(files)
73
+ bin_files = Files.grep(/^bin/)
74
+
75
+ (files - bin_files).each do |file|
76
+ chmod File.join(DEST, file), 0444
77
+ end
78
+
79
+ bin_files.each do |file|
80
+ chmod File.join(DEST, file), 0555
81
+ end
82
+ end
83
+
84
+
85
+ if HERE == DEST
86
+ project_chmod(files)
87
+ else
88
+ project_install(files)
89
+ end
data/dev/ludo ADDED
@@ -0,0 +1,25 @@
1
+ #! /usr/bin/ruby
2
+
3
+ #--
4
+ # Special Thanks to Jeffrey Schwab for #root?
5
+ #++
6
+
7
+ # Is the specified directory the root directory?
8
+
9
+ def FileTest.root?(dir)
10
+ pth = File.expand_path(dir)
11
+ return true if pth == '/'
12
+ return true if pth =~ /^(\w:)?\/$/
13
+ false
14
+ end
15
+
16
+ name = ARGV[0]
17
+
18
+ if name
19
+ Dir.chdir '..' until FileTest.executable?(name) or FileTest.root?(Dir.pwd)
20
+ if FileTest.executable?( name )
21
+ system name
22
+ end
23
+ else
24
+ puts "Script #{name} not found."
25
+ end
@@ -0,0 +1,573 @@
1
+ # TITLE:
2
+ #
3
+ # Taskable
4
+ #
5
+ # COPYRIGHT:
6
+ #
7
+ # Copyright (c) 2006 Thomas Sawyer
8
+ #
9
+ # LICENSE:
10
+ #
11
+ # Ruby License
12
+ #
13
+ # This module is free software. You may use, modify, and/or redistribute this
14
+ # software under the same terms as Ruby.
15
+ #
16
+ # This program is distributed in the hope that it will be useful, but WITHOUT
17
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
+ # FOR A PARTICULAR PURPOSE.
19
+ #
20
+ # AUTHORS:
21
+ #
22
+ # - Thomas Sawyer
23
+ #
24
+ # NOTES:
25
+ #
26
+ # - TODO The included call back does a comparison to Object.
27
+ # This is a bit of a hack b/c there is actually no way to
28
+ # check if it is the toplevel --a flaw w/ Ruby's toplevel proxy.
29
+ #
30
+ # - TODO Should Rake's namespace feature be added? This could interfer
31
+ # with other definitions of #namespace.
32
+ #
33
+ # - TODO The only reason the :exec method is defined is b/c instance_exec
34
+ # is not in Ruby yet, so until then this is the working hack.
35
+ #
36
+ # LOG:
37
+ #
38
+ # - CHANGE 2006-11-14 trans
39
+ #
40
+ # Taskable has been completely rewritten. While it is essentially
41
+ # compatible with the previous implementation, it is not 100% the
42
+ # same; mainly in that tasks are not defined as methods any longer.
43
+ # This new implementation is now nearly 100% compatible with Rake's
44
+ # design. Note, for a basic "taskable" system, more like the old
45
+ # version, see depend.rb.
46
+
47
+ require 'facets/class_extension'
48
+
49
+ $toplevel = self
50
+
51
+ # = Taskable
52
+ #
53
+ # The Taskable module provides a generic task system
54
+ # patterned after Rake, but useable in any
55
+ # code context --not just with the Rake tool. In other
56
+ # words one can create methods with dependencies.
57
+ #
58
+ # NOTE Unlike methods, tasks can't take independent parameters
59
+ # if they are to be used as prerequisites. The arguments passed
60
+ # to a task call will also be passed to it's prequisites.
61
+ #
62
+ # To use Taskable at the toplevel use:
63
+ #
64
+ # include Taskable
65
+ #
66
+ # Or if you want all modules to be "taskable":
67
+ #
68
+ # class Module
69
+ # include Taskable
70
+ # end
71
+
72
+ module Taskable
73
+
74
+ def self.included( base )
75
+ if base == Object #$toplevel
76
+ require 'facets/more/main_as_module.rb'
77
+ Module.module_eval{ include TaskableDSL }
78
+ else
79
+ base.extend TaskableDSL
80
+ end
81
+ end
82
+
83
+ ### CLASS LEVEL ###
84
+
85
+ module TaskableDSL
86
+
87
+ #--
88
+ # TODO Add task namespace functionality ???
89
+ #++
90
+ #def namespace
91
+ #end
92
+
93
+ # Define description for subsequent task.
94
+
95
+ def desc(line=nil)
96
+ return @_last_description unless line
97
+ @_last_description = line.gsub("\n",'')
98
+ end
99
+
100
+ # Use up the description for subsequent task.
101
+
102
+ def desc!
103
+ l, @_last_description = @_last_description, nil
104
+ l
105
+ end
106
+
107
+ # <b>Task</b>
108
+ #
109
+ #
110
+
111
+ def task( target_to_source, &build )
112
+ target, source = *Task.parse(target_to_source)
113
+ define_method("#{target}:exec",&build) if build
114
+ (@task||={})[target] = Task.new(target, source, desc!, &build)
115
+ end
116
+
117
+ # <b>File task</b>
118
+ #
119
+ # Task must be provide instructions for building the file.
120
+
121
+ def file( file_to_source, &build )
122
+ file, source = *Task.parse(file_to_source)
123
+ define_method("#{file}:exec",&build) if build
124
+ (@task||={})[file] = FileTask.new(file, source, desc!, &build)
125
+ end
126
+
127
+ # <b>Rule task</b>
128
+ #
129
+ # Task must be provide instructions for building the file(s).
130
+
131
+ def rule( pattern_to_source, &build )
132
+ pattern, source = *Task.parse(pattern_to_source)
133
+ define_method("#{pattern}:exec",&build) if build
134
+ (@task||={})[pattern] = RuleTask.new(pattern, source, desc!, &build)
135
+ end
136
+
137
+ #
138
+
139
+ def instance_tasks( ancestry=true )
140
+ @task ||= {}
141
+ if ancestry
142
+ ancestors.inject(@task.keys) do |m,a|
143
+ t = a.instance_variable_get("@task")
144
+ m |= t.keys if t
145
+ m
146
+ end
147
+ else
148
+ @task.keys
149
+ end
150
+ end
151
+
152
+ # List of task names with descriptions.
153
+
154
+ def described_tasks( ancestry=true )
155
+ memo = []
156
+ instance_tasks(ancestry).each do |name|
157
+ memo << name if @task[name].desc
158
+ end
159
+ return memo
160
+ end
161
+
162
+ # List of task names without descriptions.
163
+
164
+ def undescribed_tasks( ancestry=true )
165
+ memo = []
166
+ instance_tasks(ancestry).each do |name|
167
+ memo << name unless @task[name].desc
168
+ end
169
+ return memo
170
+ end
171
+
172
+ # Find matching task.
173
+ #--
174
+ # TODO Maybe this isn't really needed here and can be moved to Task class ???
175
+ #++
176
+
177
+ def instance_task( match )
178
+ hit = (@task||={}).values.find do |task|
179
+ task.match(match)
180
+ end
181
+ return hit if hit
182
+ ancestors.each do |a|
183
+ task_table = a.instance_variable_get("@task")
184
+ next unless task_table
185
+ hit = task_table.values.find do |task|
186
+ task.match(match)
187
+ end
188
+ break hit if hit
189
+ end
190
+ hit
191
+ end
192
+
193
+ end
194
+
195
+ ### INSTANCE LEVEL ###
196
+
197
+ #
198
+
199
+ def tasks
200
+ (class << self; self; end).instance_tasks
201
+ end
202
+
203
+ #
204
+
205
+ def task(name)
206
+ (class << self; self; end).instance_task(name)
207
+ end
208
+
209
+ # FIXME, THIS STILL WONT WORK AT TOPLEVEL!!!!
210
+
211
+ def method_missing(t, *a, &b)
212
+ p t
213
+ p tasks
214
+ p task(t)
215
+ #if self.class.respond_to?(:instance_task) && (task = self.class.instance_task(t))
216
+ if tsk = task(t)
217
+ tsk.run(self, t)
218
+ else
219
+ super(t.to_sym,*a,&b)
220
+ end
221
+ end
222
+
223
+ end
224
+
225
+ #
226
+
227
+ class Taskable::Task
228
+
229
+ # Parse target => [source,...] argument.
230
+
231
+ def self.parse(target_to_source)
232
+ if Hash === target_to_source
233
+ target = target_to_source.keys[0]
234
+ source = target_to_source.values[0]
235
+ else
236
+ target = target_to_source
237
+ source = []
238
+ end
239
+ return target.to_sym, source.collect{|s| s.to_sym}
240
+ end
241
+
242
+ #
243
+
244
+ attr_reader :target, :source, :desc, :build
245
+
246
+ alias :name :target
247
+ alias :description :desc
248
+
249
+ # New task.
250
+
251
+ def initialize( target, source, desc=nil, &build )
252
+ @target = target
253
+ @source = source
254
+ @desc = desc
255
+ @build = build
256
+ end
257
+
258
+ # Run task in given context.
259
+
260
+ def run( context, target )
261
+ task = self
262
+ source = @source
263
+ build = @build
264
+
265
+ presource(context).each do |d|
266
+ d.call(context)
267
+ end
268
+
269
+ call(context)
270
+ end
271
+
272
+ # Call build exec of task. Note that the use of :exec method
273
+ # is due to the lack of #instance_exec which will come wiht Ruby 1.9.
274
+
275
+ def call( context )
276
+ context.send("#{@target}:exec", self) if @build
277
+ end
278
+
279
+ #
280
+
281
+ def match( target )
282
+ @target.to_s == target.to_s
283
+ end
284
+
285
+ # Compile list of all unique prerequisite sources.
286
+
287
+ def presource( context, build=[] )
288
+ @source.each do |s|
289
+ t = context.class.instance_task(s)
290
+ raise NoMethodError, 'undefined source' unless t
291
+ build.unshift(t)
292
+ t.presource(context,build)
293
+ end
294
+ build.uniq!
295
+ build
296
+ end
297
+
298
+ end
299
+
300
+ #
301
+
302
+ class Taskable::FileTask < Taskable::Task
303
+
304
+ # Run file task in a given context.
305
+
306
+ def run( context, target )
307
+ task = self
308
+ source = @source
309
+ build = @build
310
+
311
+ context.instance_eval do
312
+ needed = false
313
+ if File.exist?(file)
314
+ #source.each { |s| send(s) if respond_to?(s) }
315
+ timestamp = File.mtime(file)
316
+ needed = source.any? { |f| File.mtime(f.to_s) > timestamp }
317
+ else
318
+ timestamp = Time.now - 1
319
+ needed = true
320
+ end
321
+ if needed
322
+ build.call(task)
323
+ unless File.exist?(file) and File.mtime(file) > timestamp
324
+ raise "failed to build -- #{file}"
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ #
331
+
332
+ def match(target)
333
+ @target.to_s == target.to_s
334
+ end
335
+
336
+ end
337
+
338
+ #
339
+
340
+ class Taskable::RuleTask < Taskable::FileTask
341
+
342
+ # Run rule task in given context.
343
+
344
+ def run( context, target )
345
+ @target = target
346
+ super(context)
347
+ end
348
+
349
+ #
350
+
351
+ def match(target)
352
+ case @target
353
+ when Regexp
354
+ @target =~ target.to_s
355
+ when String
356
+ #if @target.index('*') #TODO
357
+ # /#{@target.gsub('*', '.*?')}/ =~ target
358
+ if @target.index('.') == 0
359
+ /#{Regexp.escape(@target)}$/ =~ target
360
+ else
361
+ super
362
+ end
363
+ else
364
+ super
365
+ end
366
+ end
367
+
368
+ end
369
+
370
+
371
+
372
+ # _____ _
373
+ # |_ _|__ ___| |_
374
+ # | |/ _ \/ __| __|
375
+ # | | __/\__ \ |_
376
+ # |_|\___||___/\__|
377
+ #
378
+ =begin ##test
379
+
380
+ require 'test/unit'
381
+
382
+ class TestTaskable1 < Test::Unit::TestCase
383
+
384
+ module M
385
+ include Taskable
386
+ task :m1 => [ :c1 ] do @x << "m1" end
387
+ task :m2 => [ :c2 ] do @x << "m2" end
388
+ task :m3 => [ :c3 ] do @x << "m3" end
389
+ task :m4 => [ :c1, :c2, :c3 ] do @x << "m4" end
390
+ task :m5 do @x << 'm5' end
391
+ end
392
+
393
+ class B
394
+ include Taskable
395
+ attr :x
396
+ def initialize ; @x = [] ; end
397
+
398
+ desc "test-b1"
399
+ task :b1 do @x << "b1" end
400
+ task :b2 => [ :b1 ]
401
+ end
402
+
403
+ class C
404
+ include M
405
+ attr :x
406
+ def initialize ; @x = [] ; end
407
+
408
+ task :c1 do @x << "c1" end
409
+ task :c2 => [ :c1, :c1 ] do @x << "c2" end
410
+ task :c3 => [ :c1, :c2 ] do @x << "c3" end
411
+ task :c4 => [ :m1 ] do @x << "c4" end
412
+ task :c5 => [ :c5 ] do @x << "c5" end
413
+ task :c6 => [ :c7 ] do @x << "c6" end
414
+ task :c7 => [ :c6 ] do @x << "c7" end
415
+ end
416
+
417
+ class D < C
418
+ task :d1 => [ :c1 ] do @x << "d1" ; end
419
+ task :d2 => [ :m1 ] do @x << "d2" ; end
420
+ end
421
+
422
+ module N
423
+ include M
424
+ end
425
+
426
+ class E
427
+ include N
428
+ attr :x
429
+ def initialize ; @x = [] ; end
430
+
431
+ task :e1 => [ :c1 ] do @x << "e1" ; end
432
+ task :e2 => [ :m1 ] do @x << "e2" ; end
433
+ task :e3 => [ :m5 ] do @x << "e3" ; end
434
+ end
435
+
436
+ module O
437
+ include Taskable
438
+ attr :x
439
+ task :o1 do (@x||=[]) << "o1" end
440
+ task :o2 => [ :o1 ] do (@x||=[]) << "o2" end
441
+ end
442
+
443
+ # tests
444
+
445
+ def test_001
446
+ assert( B.described_tasks.include?(:b1) )
447
+ end
448
+
449
+ def test_B1
450
+ b = B.new ; b.b1
451
+ assert_equal( [ 'b1' ], b.x )
452
+ end
453
+
454
+ def test_B2
455
+ b = B.new ; b.b2
456
+ assert_equal( [ 'b1' ], b.x )
457
+ end
458
+
459
+ def test_C1
460
+ c = C.new ; c.c1
461
+ assert_equal( [ 'c1' ], c.x )
462
+ end
463
+
464
+ def test_C2
465
+ c = C.new ; c.c2
466
+ assert_equal( [ 'c1', 'c2' ], c.x )
467
+ end
468
+
469
+ def test_C3
470
+ c = C.new ; c.c3
471
+ assert_equal( [ 'c1', 'c2', 'c3' ], c.x )
472
+ end
473
+
474
+ def test_C4
475
+ c = C.new ; c.c4
476
+ assert_equal( [ 'c1', 'm1', 'c4' ], c.x )
477
+ end
478
+
479
+ def test_M1
480
+ c = C.new ; c.m1
481
+ assert_equal( [ 'c1', 'm1' ], c.x )
482
+ end
483
+
484
+ def test_M2
485
+ c = C.new ; c.m2
486
+ assert_equal( [ 'c1', 'c2', 'm2' ], c.x )
487
+ end
488
+
489
+ def test_M3
490
+ c = C.new ; c.m3
491
+ assert_equal( [ 'c1', 'c2', 'c3', 'm3' ], c.x )
492
+ end
493
+
494
+ def test_M4
495
+ c = C.new ; c.m4
496
+ assert_equal( [ 'c1', 'c2', 'c3', 'm4' ], c.x )
497
+ end
498
+
499
+ def test_D1
500
+ d = D.new ; d.d1
501
+ assert_equal( [ 'c1', 'd1' ], d.x )
502
+ end
503
+
504
+ def test_D2
505
+ d = D.new ; d.d2
506
+ assert_equal( [ 'c1', 'm1', 'd2' ], d.x )
507
+ end
508
+
509
+ def test_E1
510
+ e = E.new
511
+ assert_raises( NoMethodError ) { e.e1 }
512
+ #assert_equal( [ 'c1', 'e1' ], e.x )
513
+ end
514
+
515
+ def test_E2
516
+ e = E.new
517
+ assert_raises( NoMethodError ) { e.e2 }
518
+ #assert_equal( [ 'c1', 'm1', 'e2' ], e.x )
519
+ end
520
+
521
+ def test_E3
522
+ e = E.new ; e.e3
523
+ assert_equal( [ 'm5', 'e3' ], e.x )
524
+ end
525
+
526
+ # def test_F1
527
+ # F.o1
528
+ # assert_equal( [ 'o1' ], F.x )
529
+ # end
530
+ #
531
+ # def test_F2
532
+ # F.o2
533
+ # assert_equal( [ 'o1', 'o1', 'o2' ], F.x )
534
+ # end
535
+
536
+ end
537
+
538
+ =end
539
+
540
+ ##
541
+ # Test toplevel usage.
542
+ #
543
+
544
+ include Taskable
545
+
546
+ p Object.ancestors
547
+
548
+ task :foo do
549
+ "foo"
550
+ end
551
+
552
+ task :bar => [ :foo ] do
553
+ "bar"
554
+ end
555
+
556
+ #class TestTaskable2 #< Test::Unit::TestCase
557
+ def test_01
558
+ puts foo
559
+ end
560
+
561
+ def test_02
562
+ puts bar
563
+ end
564
+ #end
565
+
566
+ test_01
567
+ test_02
568
+
569
+ #=end
570
+
571
+ # Author:: Thomas Sawyer
572
+ # Copyright:: Copyright (c) 2006 Thomas Sawyer
573
+ # License:: Ruby License