ratch 0.1 → 0.2.1

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