roll 0.8.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/{LICENSE → COPYING} +1 -1
  2. data/HISTORY +62 -0
  3. data/README.rdoc +169 -0
  4. data/TODO +4 -0
  5. data/bin/roll +3 -44
  6. data/lib/oll.rb +1 -2
  7. data/lib/roll.rb +87 -0
  8. data/lib/roll/command.rb +207 -0
  9. data/lib/roll/config.rb +80 -0
  10. data/lib/roll/environment.rb +317 -0
  11. data/lib/roll/errors.rb +13 -0
  12. data/lib/roll/kernel.rb +41 -0
  13. data/lib/roll/ledger.rb +299 -0
  14. data/lib/roll/library.rb +241 -558
  15. data/lib/roll/locals.rb +96 -0
  16. data/lib/roll/metadata.rb +112 -0
  17. data/lib/roll/original.rb +10 -0
  18. data/lib/roll/version.rb +91 -101
  19. data/meta/active +1 -0
  20. data/meta/authors +1 -0
  21. data/meta/contact +1 -0
  22. data/meta/created +1 -0
  23. data/meta/description +5 -0
  24. data/meta/homepage +1 -0
  25. data/meta/maintainer +1 -0
  26. data/meta/name +1 -0
  27. data/meta/repository +1 -0
  28. data/meta/ruby +2 -0
  29. data/meta/suite +1 -0
  30. data/meta/summary +1 -0
  31. data/meta/version +1 -0
  32. data/script/rdoc +4 -0
  33. data/script/setup +1344 -0
  34. data/script/test +23 -0
  35. data/test/benchmarks/vsgems.rb +11 -0
  36. data/test/benchmarks/vsgems_bm.rb +17 -0
  37. data/test/demonstrations/01_library.rdoc +33 -0
  38. data/test/demonstrations/04_version.rdoc +56 -0
  39. data/test/fixtures/env.list +1 -0
  40. data/{demo/sample → test/fixtures}/inspect.rb +0 -0
  41. data/test/fixtures/tryme/1.0/lib/tryme.rb +1 -0
  42. data/test/fixtures/tryme/1.0/meta/homepage +1 -0
  43. data/test/fixtures/tryme/1.0/meta/name +1 -0
  44. data/test/fixtures/tryme/1.0/meta/version +1 -0
  45. data/test/fixtures/tryme/1.1/lib/tryme.rb +1 -0
  46. data/test/fixtures/tryme/1.1/meta/homepage +1 -0
  47. data/test/fixtures/tryme/1.1/meta/name +1 -0
  48. data/test/fixtures/tryme/1.1/meta/version +1 -0
  49. data/test/{test_version.rb → unit/version_test.rb} +21 -21
  50. data/test/unitcases/version_case.rb +69 -0
  51. metadata +102 -65
  52. data/README +0 -17
  53. data/demo/bench/bench_load.rb +0 -7
  54. data/demo/sample/tryme/1.0/lib/tryme.rb +0 -1
  55. data/demo/sample/tryme/1.1/lib/tryme.rb +0 -1
  56. data/lib/roll/attributes.rb +0 -72
  57. data/lib/roll/package.rb +0 -300
  58. data/lib/roll/remote.rb +0 -37
  59. data/meta/ROLL-0.8.0.roll +0 -21
  60. data/task/rdoc +0 -9
  61. data/task/setup +0 -1616
  62. data/task/test +0 -5
  63. data/test/test_library.rb +0 -10
data/task/rdoc DELETED
@@ -1,9 +0,0 @@
1
- #!/bin/sh
2
-
3
- rdoc -o doc/rdoc \
4
- -m README \
5
- -t "Facets Core" \
6
- -x work \
7
- -x script \
8
- -x setup.rb
9
-
data/task/setup DELETED
@@ -1,1616 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Setup and install.
4
- #
5
- # setup.rb
6
- #
7
- # Copyright (c) 2000-2005 Minero Aoki
8
- #
9
- # This program is free software.
10
- # You can distribute/modify this program under the terms of
11
- # the GNU LGPL, Lesser General Public License version 2.1.
12
-
13
- #
14
- # Was hardcoded as 'InstalledFiles'
15
- #
16
-
17
- INSTALLED_MANIFEST = '.installed'
18
-
19
- #
20
- # Was hardcoded as 'packages'.
21
- #
22
-
23
- PACKAGES_DIRECTORY = 'src'
24
-
25
- #
26
- # Locate and move to the root dir of the project/package.
27
- # This is setup to put setup in a utilities subdir.
28
- #
29
- # TODO Make more robust.
30
- #
31
-
32
- ROOT_DIRECTORY = File.dirname(File.dirname(File.expand_path($0)))
33
-
34
- Dir.chdir(ROOT_DIRECTORY)
35
-
36
- #
37
- # Deal with Ruby version issues.
38
- #
39
-
40
- unless Enumerable.method_defined?(:map) # Ruby 1.4.6
41
- module Enumerable
42
- alias map collect
43
- end
44
- end
45
-
46
- unless File.respond_to?(:read) # Ruby 1.6
47
- def File.read(fname)
48
- open(fname) {|f|
49
- return f.read
50
- }
51
- end
52
- end
53
-
54
- unless Errno.const_defined?(:ENOTEMPTY) # Windows?
55
- module Errno
56
- class ENOTEMPTY
57
- # We do not raise this exception, implementation is not needed.
58
- end
59
- end
60
- end
61
-
62
- def File.binread(fname)
63
- open(fname, 'rb') {|f|
64
- return f.read
65
- }
66
- end
67
-
68
- # for corrupted Windows' stat(2)
69
- def File.dir?(path)
70
- File.directory?((path[-1,1] == '/') ? path : path + '/')
71
- end
72
-
73
-
74
- class ConfigTable
75
-
76
- include Enumerable
77
-
78
- def initialize(rbconfig)
79
- @rbconfig = rbconfig
80
- @items = []
81
- @table = {}
82
- # options
83
- @install_prefix = nil
84
- @config_opt = nil
85
- @verbose = true
86
- @no_harm = false
87
- end
88
-
89
- attr_accessor :install_prefix
90
- attr_accessor :config_opt
91
-
92
- attr_writer :verbose
93
-
94
- def verbose?
95
- @verbose
96
- end
97
-
98
- attr_writer :no_harm
99
-
100
- def no_harm?
101
- @no_harm
102
- end
103
-
104
- def [](key)
105
- lookup(key).resolve(self)
106
- end
107
-
108
- def []=(key, val)
109
- lookup(key).set val
110
- end
111
-
112
- def names
113
- @items.map {|i| i.name }
114
- end
115
-
116
- def each(&block)
117
- @items.each(&block)
118
- end
119
-
120
- def key?(name)
121
- @table.key?(name)
122
- end
123
-
124
- def lookup(name)
125
- @table[name] or setup_rb_error "no such config item: #{name}"
126
- end
127
-
128
- def add(item)
129
- @items.push item
130
- @table[item.name] = item
131
- end
132
-
133
- def remove(name)
134
- item = lookup(name)
135
- @items.delete_if {|i| i.name == name }
136
- @table.delete_if {|name, i| i.name == name }
137
- item
138
- end
139
-
140
- def load_script(path, inst = nil)
141
- if File.file?(path)
142
- MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
143
- end
144
- end
145
-
146
- def savefile
147
- '.config'
148
- end
149
-
150
- def load_savefile
151
- begin
152
- File.foreach(savefile()) do |line|
153
- k, v = *line.split(/=/, 2)
154
- self[k] = v.strip
155
- end
156
- rescue Errno::ENOENT
157
- setup_rb_error $!.message + "\n#{File.basename($0)} config first"
158
- end
159
- end
160
-
161
- def save
162
- @items.each {|i| i.value }
163
- File.open(savefile(), 'w') {|f|
164
- @items.each do |i|
165
- f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
166
- end
167
- }
168
- end
169
-
170
- def load_standard_entries
171
- standard_entries(@rbconfig).each do |ent|
172
- add ent
173
- end
174
- end
175
-
176
- def standard_entries(rbconfig)
177
- c = rbconfig
178
-
179
- rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
180
-
181
- major = c['MAJOR'].to_i
182
- minor = c['MINOR'].to_i
183
- teeny = c['TEENY'].to_i
184
- version = "#{major}.#{minor}"
185
-
186
- # ruby ver. >= 1.4.4?
187
- newpath_p = ((major >= 2) or
188
- ((major == 1) and
189
- ((minor >= 5) or
190
- ((minor == 4) and (teeny >= 4)))))
191
-
192
- if c['rubylibdir']
193
- # V > 1.6.3
194
- libruby = "#{c['prefix']}/lib/ruby"
195
- librubyver = c['rubylibdir']
196
- librubyverarch = c['archdir']
197
- siteruby = c['sitedir']
198
- siterubyver = c['sitelibdir']
199
- siterubyverarch = c['sitearchdir']
200
- elsif newpath_p
201
- # 1.4.4 <= V <= 1.6.3
202
- libruby = "#{c['prefix']}/lib/ruby"
203
- librubyver = "#{c['prefix']}/lib/ruby/#{version}"
204
- librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
205
- siteruby = c['sitedir']
206
- siterubyver = "$siteruby/#{version}"
207
- siterubyverarch = "$siterubyver/#{c['arch']}"
208
- else
209
- # V < 1.4.4
210
- libruby = "#{c['prefix']}/lib/ruby"
211
- librubyver = "#{c['prefix']}/lib/ruby/#{version}"
212
- librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
213
- siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
214
- siterubyver = siteruby
215
- siterubyverarch = "$siterubyver/#{c['arch']}"
216
- end
217
- parameterize = lambda {|path|
218
- path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
219
- }
220
-
221
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
222
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
223
- else
224
- makeprog = 'make'
225
- end
226
-
227
- [
228
- ExecItem.new('installdirs', 'std/site/home',
229
- 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
230
- {|val, table|
231
- case val
232
- when 'std'
233
- table['rbdir'] = '$librubyver'
234
- table['sodir'] = '$librubyverarch'
235
- when 'site'
236
- table['rbdir'] = '$siterubyver'
237
- table['sodir'] = '$siterubyverarch'
238
- when 'home'
239
- setup_rb_error '$HOME was not set' unless ENV['HOME']
240
- table['prefix'] = ENV['HOME']
241
- table['rbdir'] = '$libdir/ruby'
242
- table['sodir'] = '$libdir/ruby'
243
- end
244
- },
245
- PathItem.new('prefix', 'path', c['prefix'],
246
- 'path prefix of target environment'),
247
- PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
248
- 'the directory for commands'),
249
- PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
250
- 'the directory for libraries'),
251
- PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
252
- 'the directory for shared data'),
253
- PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
254
- 'the directory for man pages'),
255
- PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
256
- 'the directory for system configuration files'),
257
- PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
258
- 'the directory for local state data'),
259
- PathItem.new('libruby', 'path', libruby,
260
- 'the directory for ruby libraries'),
261
- PathItem.new('librubyver', 'path', librubyver,
262
- 'the directory for standard ruby libraries'),
263
- PathItem.new('librubyverarch', 'path', librubyverarch,
264
- 'the directory for standard ruby extensions'),
265
- PathItem.new('siteruby', 'path', siteruby,
266
- 'the directory for version-independent aux ruby libraries'),
267
- PathItem.new('siterubyver', 'path', siterubyver,
268
- 'the directory for aux ruby libraries'),
269
- PathItem.new('siterubyverarch', 'path', siterubyverarch,
270
- 'the directory for aux ruby binaries'),
271
- PathItem.new('rbdir', 'path', '$siterubyver',
272
- 'the directory for ruby scripts'),
273
- PathItem.new('sodir', 'path', '$siterubyverarch',
274
- 'the directory for ruby extentions'),
275
- PathItem.new('rubypath', 'path', rubypath,
276
- 'the path to set to #! line'),
277
- ProgramItem.new('rubyprog', 'name', rubypath,
278
- 'the ruby program using for installation'),
279
- ProgramItem.new('makeprog', 'name', makeprog,
280
- 'the make program to compile ruby extentions'),
281
- SelectItem.new('shebang', 'all/ruby/never', 'ruby',
282
- 'shebang line (#!) editing mode'),
283
- BoolItem.new('without-ext', 'yes/no', 'no',
284
- 'does not compile/install ruby extentions')
285
- ]
286
- end
287
- private :standard_entries
288
-
289
- def load_multipackage_entries
290
- multipackage_entries().each do |ent|
291
- add ent
292
- end
293
- end
294
-
295
- def multipackage_entries
296
- [
297
- PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
298
- 'package names that you want to install'),
299
- PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
300
- 'package names that you do not want to install')
301
- ]
302
- end
303
- private :multipackage_entries
304
-
305
- ALIASES = {
306
- 'std-ruby' => 'librubyver',
307
- 'stdruby' => 'librubyver',
308
- 'rubylibdir' => 'librubyver',
309
- 'archdir' => 'librubyverarch',
310
- 'site-ruby-common' => 'siteruby', # For backward compatibility
311
- 'site-ruby' => 'siterubyver', # For backward compatibility
312
- 'bin-dir' => 'bindir',
313
- 'bin-dir' => 'bindir',
314
- 'rb-dir' => 'rbdir',
315
- 'so-dir' => 'sodir',
316
- 'data-dir' => 'datadir',
317
- 'ruby-path' => 'rubypath',
318
- 'ruby-prog' => 'rubyprog',
319
- 'ruby' => 'rubyprog',
320
- 'make-prog' => 'makeprog',
321
- 'make' => 'makeprog'
322
- }
323
-
324
- def fixup
325
- ALIASES.each do |ali, name|
326
- @table[ali] = @table[name]
327
- end
328
- @items.freeze
329
- @table.freeze
330
- @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
331
- end
332
-
333
- def parse_opt(opt)
334
- m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
335
- m.to_a[1,2]
336
- end
337
-
338
- def dllext
339
- @rbconfig['DLEXT']
340
- end
341
-
342
- def value_config?(name)
343
- lookup(name).value?
344
- end
345
-
346
- class Item
347
- def initialize(name, template, default, desc)
348
- @name = name.freeze
349
- @template = template
350
- @value = default
351
- @default = default
352
- @description = desc
353
- end
354
-
355
- attr_reader :name
356
- attr_reader :description
357
-
358
- attr_accessor :default
359
- alias help_default default
360
-
361
- def help_opt
362
- "--#{@name}=#{@template}"
363
- end
364
-
365
- def value?
366
- true
367
- end
368
-
369
- def value
370
- @value
371
- end
372
-
373
- def resolve(table)
374
- @value.gsub(%r<\$([^/]+)>) { table[$1] }
375
- end
376
-
377
- def set(val)
378
- @value = check(val)
379
- end
380
-
381
- private
382
-
383
- def check(val)
384
- setup_rb_error "config: --#{name} requires argument" unless val
385
- val
386
- end
387
- end
388
-
389
- class BoolItem < Item
390
- def config_type
391
- 'bool'
392
- end
393
-
394
- def help_opt
395
- "--#{@name}"
396
- end
397
-
398
- private
399
-
400
- def check(val)
401
- return 'yes' unless val
402
- case val
403
- when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
404
- when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
405
- else
406
- setup_rb_error "config: --#{@name} accepts only yes/no for argument"
407
- end
408
- end
409
- end
410
-
411
- class PathItem < Item
412
- def config_type
413
- 'path'
414
- end
415
-
416
- private
417
-
418
- def check(path)
419
- setup_rb_error "config: --#{@name} requires argument" unless path
420
- path[0,1] == '$' ? path : File.expand_path(path)
421
- end
422
- end
423
-
424
- class ProgramItem < Item
425
- def config_type
426
- 'program'
427
- end
428
- end
429
-
430
- class SelectItem < Item
431
- def initialize(name, selection, default, desc)
432
- super
433
- @ok = selection.split('/')
434
- end
435
-
436
- def config_type
437
- 'select'
438
- end
439
-
440
- private
441
-
442
- def check(val)
443
- unless @ok.include?(val.strip)
444
- setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
445
- end
446
- val.strip
447
- end
448
- end
449
-
450
- class ExecItem < Item
451
- def initialize(name, selection, desc, &block)
452
- super name, selection, nil, desc
453
- @ok = selection.split('/')
454
- @action = block
455
- end
456
-
457
- def config_type
458
- 'exec'
459
- end
460
-
461
- def value?
462
- false
463
- end
464
-
465
- def resolve(table)
466
- setup_rb_error "$#{name()} wrongly used as option value"
467
- end
468
-
469
- undef set
470
-
471
- def evaluate(val, table)
472
- v = val.strip.downcase
473
- unless @ok.include?(v)
474
- setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
475
- end
476
- @action.call v, table
477
- end
478
- end
479
-
480
- class PackageSelectionItem < Item
481
- def initialize(name, template, default, help_default, desc)
482
- super name, template, default, desc
483
- @help_default = help_default
484
- end
485
-
486
- attr_reader :help_default
487
-
488
- def config_type
489
- 'package'
490
- end
491
-
492
- private
493
-
494
- def check(val)
495
- unless File.dir?("#{PACKAGES_DIRECTORY}/#{val}")
496
- setup_rb_error "config: no such package: #{val}"
497
- end
498
- val
499
- end
500
- end
501
-
502
- class MetaConfigEnvironment
503
- def initialize(config, installer)
504
- @config = config
505
- @installer = installer
506
- end
507
-
508
- def config_names
509
- @config.names
510
- end
511
-
512
- def config?(name)
513
- @config.key?(name)
514
- end
515
-
516
- def bool_config?(name)
517
- @config.lookup(name).config_type == 'bool'
518
- end
519
-
520
- def path_config?(name)
521
- @config.lookup(name).config_type == 'path'
522
- end
523
-
524
- def value_config?(name)
525
- @config.lookup(name).config_type != 'exec'
526
- end
527
-
528
- def add_config(item)
529
- @config.add item
530
- end
531
-
532
- def add_bool_config(name, default, desc)
533
- @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
534
- end
535
-
536
- def add_path_config(name, default, desc)
537
- @config.add PathItem.new(name, 'path', default, desc)
538
- end
539
-
540
- def set_config_default(name, default)
541
- @config.lookup(name).default = default
542
- end
543
-
544
- def remove_config(name)
545
- @config.remove(name)
546
- end
547
-
548
- # For only multipackage
549
- def packages
550
- raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
551
- @installer.packages
552
- end
553
-
554
- # For only multipackage
555
- def declare_packages(list)
556
- raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
557
- @installer.packages = list
558
- end
559
- end
560
-
561
- end # class ConfigTable
562
-
563
-
564
- # This module requires: #verbose?, #no_harm?
565
- module FileOperations
566
-
567
- def mkdir_p(dirname, prefix = nil)
568
- dirname = prefix + File.expand_path(dirname) if prefix
569
- $stderr.puts "mkdir -p #{dirname}" if verbose?
570
- return if no_harm?
571
-
572
- # Does not check '/', it's too abnormal.
573
- dirs = File.expand_path(dirname).split(%r<(?=/)>)
574
- if /\A[a-z]:\z/i =~ dirs[0]
575
- disk = dirs.shift
576
- dirs[0] = disk + dirs[0]
577
- end
578
- dirs.each_index do |idx|
579
- path = dirs[0..idx].join('')
580
- Dir.mkdir path unless File.dir?(path)
581
- end
582
- end
583
-
584
- def rm_f(path)
585
- $stderr.puts "rm -f #{path}" if verbose?
586
- return if no_harm?
587
- force_remove_file path
588
- end
589
-
590
- def rm_rf(path)
591
- $stderr.puts "rm -rf #{path}" if verbose?
592
- return if no_harm?
593
- remove_tree path
594
- end
595
-
596
- def remove_tree(path)
597
- if File.symlink?(path)
598
- remove_file path
599
- elsif File.dir?(path)
600
- remove_tree0 path
601
- else
602
- force_remove_file path
603
- end
604
- end
605
-
606
- def remove_tree0(path)
607
- Dir.foreach(path) do |ent|
608
- next if ent == '.'
609
- next if ent == '..'
610
- entpath = "#{path}/#{ent}"
611
- if File.symlink?(entpath)
612
- remove_file entpath
613
- elsif File.dir?(entpath)
614
- remove_tree0 entpath
615
- else
616
- force_remove_file entpath
617
- end
618
- end
619
- begin
620
- Dir.rmdir path
621
- rescue Errno::ENOTEMPTY
622
- # directory may not be empty
623
- end
624
- end
625
-
626
- def move_file(src, dest)
627
- force_remove_file dest
628
- begin
629
- File.rename src, dest
630
- rescue
631
- File.open(dest, 'wb') {|f|
632
- f.write File.binread(src)
633
- }
634
- File.chmod File.stat(src).mode, dest
635
- File.unlink src
636
- end
637
- end
638
-
639
- def force_remove_file(path)
640
- begin
641
- remove_file path
642
- rescue
643
- end
644
- end
645
-
646
- def remove_file(path)
647
- File.chmod 0777, path
648
- File.unlink path
649
- end
650
-
651
- def install(from, dest, mode, prefix = nil)
652
- $stderr.puts "install #{from} #{dest}" if verbose?
653
- return if no_harm?
654
-
655
- realdest = prefix ? prefix + File.expand_path(dest) : dest
656
- realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
657
- str = File.binread(from)
658
- if diff?(str, realdest)
659
- verbose_off {
660
- rm_f realdest if File.exist?(realdest)
661
- }
662
- File.open(realdest, 'wb') {|f|
663
- f.write str
664
- }
665
- File.chmod mode, realdest
666
-
667
- File.open("#{objdir_root()}/#{INSTALLED_MANIFEST}", 'a') {|f|
668
- if prefix
669
- f.puts realdest.sub(prefix, '')
670
- else
671
- f.puts realdest
672
- end
673
- }
674
- end
675
- end
676
-
677
- def diff?(new_content, path)
678
- return true unless File.exist?(path)
679
- new_content != File.binread(path)
680
- end
681
-
682
- def command(*args)
683
- $stderr.puts args.join(' ') if verbose?
684
- system(*args) or raise RuntimeError,
685
- "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
686
- end
687
-
688
- def ruby(*args)
689
- command config('rubyprog'), *args
690
- end
691
-
692
- def make(task = nil)
693
- command(*[config('makeprog'), task].compact)
694
- end
695
-
696
- def extdir?(dir)
697
- File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
698
- end
699
-
700
- def files_of(dir)
701
- Dir.open(dir) {|d|
702
- return d.select {|ent| File.file?("#{dir}/#{ent}") }
703
- }
704
- end
705
-
706
- DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
707
-
708
- def directories_of(dir)
709
- Dir.open(dir) {|d|
710
- return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
711
- }
712
- end
713
-
714
- end
715
-
716
-
717
- # This module requires: #srcdir_root, #objdir_root, #relpath
718
- module HookScriptAPI
719
-
720
- def get_config(key)
721
- @config[key]
722
- end
723
-
724
- alias config get_config
725
-
726
- # obsolete: use metaconfig to change configuration
727
- def set_config(key, val)
728
- @config[key] = val
729
- end
730
-
731
- #
732
- # srcdir/objdir (works only in the package directory)
733
- #
734
-
735
- def curr_srcdir
736
- "#{srcdir_root()}/#{relpath()}"
737
- end
738
-
739
- def curr_objdir
740
- "#{objdir_root()}/#{relpath()}"
741
- end
742
-
743
- def srcfile(path)
744
- "#{curr_srcdir()}/#{path}"
745
- end
746
-
747
- def srcexist?(path)
748
- File.exist?(srcfile(path))
749
- end
750
-
751
- def srcdirectory?(path)
752
- File.dir?(srcfile(path))
753
- end
754
-
755
- def srcfile?(path)
756
- File.file?(srcfile(path))
757
- end
758
-
759
- def srcentries(path = '.')
760
- Dir.open("#{curr_srcdir()}/#{path}") {|d|
761
- return d.to_a - %w(. ..)
762
- }
763
- end
764
-
765
- def srcfiles(path = '.')
766
- srcentries(path).select {|fname|
767
- File.file?(File.join(curr_srcdir(), path, fname))
768
- }
769
- end
770
-
771
- def srcdirectories(path = '.')
772
- srcentries(path).select {|fname|
773
- File.dir?(File.join(curr_srcdir(), path, fname))
774
- }
775
- end
776
-
777
- end
778
-
779
-
780
- class ToplevelInstaller
781
-
782
- Version = '3.4.1'
783
- Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
784
-
785
- TASKS = [
786
- [ 'all', 'do config, setup, then install' ],
787
- [ 'config', 'saves your configurations' ],
788
- [ 'show', 'shows current configuration' ],
789
- [ 'setup', 'compiles ruby extentions and others' ],
790
- [ 'install', 'installs files' ],
791
- [ 'test', 'run all tests in test/' ],
792
- [ 'clean', "does `make clean' for each extention" ],
793
- [ 'distclean',"does `make distclean' for each extention" ]
794
- ]
795
-
796
- def ToplevelInstaller.invoke
797
- config = ConfigTable.new(load_rbconfig())
798
- config.load_standard_entries
799
- config.load_multipackage_entries if multipackage?
800
- config.fixup
801
- klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
802
- #klass.new(File.dirname($0), config).invoke
803
- klass.new(ROOT_DIRECTORY, config).invoke
804
- end
805
-
806
- def ToplevelInstaller.multipackage?
807
- #File.dir?(File.dirname($0) + '/#{PACKAGES_DIRECTORY}')
808
- File.dir?(ROOT_DIRECTORY + "/#{PACKAGES_DIRECTORY}")
809
- end
810
-
811
- def ToplevelInstaller.load_rbconfig
812
- if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
813
- ARGV.delete(arg)
814
- load File.expand_path(arg.split(/=/, 2)[1])
815
- $".push 'rbconfig.rb'
816
- else
817
- require 'rbconfig'
818
- end
819
- ::Config::CONFIG
820
- end
821
-
822
- def initialize(ardir_root, config)
823
- @ardir = File.expand_path(ardir_root)
824
- @config = config
825
- # cache
826
- @valid_task_re = nil
827
- end
828
-
829
- def config(key)
830
- @config[key]
831
- end
832
-
833
- def inspect
834
- "#<#{self.class} #{__id__()}>"
835
- end
836
-
837
- def invoke
838
- run_metaconfigs
839
- case task = parsearg_global()
840
- when nil, 'all'
841
- parsearg_config
842
- init_installers
843
- exec_config
844
- exec_setup
845
- exec_install
846
- else
847
- case task
848
- when 'config', 'test'
849
- ;
850
- when 'clean', 'distclean'
851
- @config.load_savefile if File.exist?(@config.savefile)
852
- else
853
- @config.load_savefile
854
- end
855
- __send__ "parsearg_#{task}"
856
- init_installers
857
- __send__ "exec_#{task}"
858
- end
859
- end
860
-
861
- def run_metaconfigs
862
- @config.load_script "#{@ardir}/metaconfig"
863
- end
864
-
865
- def init_installers
866
- @installer = Installer.new(@config, @ardir, File.expand_path('.'))
867
- end
868
-
869
- #
870
- # Hook Script API bases
871
- #
872
-
873
- def srcdir_root
874
- @ardir
875
- end
876
-
877
- def objdir_root
878
- '.'
879
- end
880
-
881
- def relpath
882
- '.'
883
- end
884
-
885
- #
886
- # Option Parsing
887
- #
888
-
889
- def parsearg_global
890
- while arg = ARGV.shift
891
- case arg
892
- when /\A\w+\z/
893
- setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
894
- return arg
895
- when '-q', '--quiet'
896
- @config.verbose = false
897
- when '--verbose'
898
- @config.verbose = true
899
- when '--help'
900
- print_usage $stdout
901
- exit 0
902
- when '--version'
903
- puts "#{File.basename($0)} version #{Version}"
904
- exit 0
905
- when '--copyright'
906
- puts Copyright
907
- exit 0
908
- else
909
- setup_rb_error "unknown global option '#{arg}'"
910
- end
911
- end
912
- nil
913
- end
914
-
915
- def valid_task?(t)
916
- valid_task_re() =~ t
917
- end
918
-
919
- def valid_task_re
920
- @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
921
- end
922
-
923
- def parsearg_no_options
924
- unless ARGV.empty?
925
- task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
926
- setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
927
- end
928
- end
929
-
930
- alias parsearg_show parsearg_no_options
931
- alias parsearg_setup parsearg_no_options
932
- alias parsearg_test parsearg_no_options
933
- alias parsearg_clean parsearg_no_options
934
- alias parsearg_distclean parsearg_no_options
935
-
936
- def parsearg_config
937
- evalopt = []
938
- set = []
939
- @config.config_opt = []
940
- while i = ARGV.shift
941
- if /\A--?\z/ =~ i
942
- @config.config_opt = ARGV.dup
943
- break
944
- end
945
- name, value = *@config.parse_opt(i)
946
- if @config.value_config?(name)
947
- @config[name] = value
948
- else
949
- evalopt.push [name, value]
950
- end
951
- set.push name
952
- end
953
- evalopt.each do |name, value|
954
- @config.lookup(name).evaluate value, @config
955
- end
956
- # Check if configuration is valid
957
- set.each do |n|
958
- @config[n] if @config.value_config?(n)
959
- end
960
- end
961
-
962
- def parsearg_install
963
- @config.no_harm = false
964
- @config.install_prefix = ''
965
- while a = ARGV.shift
966
- case a
967
- when '--no-harm'
968
- @config.no_harm = true
969
- when /\A--prefix=/
970
- path = a.split(/=/, 2)[1]
971
- path = File.expand_path(path) unless path[0,1] == '/'
972
- @config.install_prefix = path
973
- else
974
- setup_rb_error "install: unknown option #{a}"
975
- end
976
- end
977
- end
978
-
979
- def print_usage(out)
980
- out.puts 'Typical Installation Procedure:'
981
- out.puts " $ ruby #{File.basename $0} config"
982
- out.puts " $ ruby #{File.basename $0} setup"
983
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
984
- out.puts
985
- out.puts 'Detailed Usage:'
986
- out.puts " ruby #{File.basename $0} <global option>"
987
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
988
-
989
- fmt = " %-24s %s\n"
990
- out.puts
991
- out.puts 'Global options:'
992
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
993
- out.printf fmt, ' --verbose', 'output messages verbosely'
994
- out.printf fmt, ' --help', 'print this message'
995
- out.printf fmt, ' --version', 'print version and quit'
996
- out.printf fmt, ' --copyright', 'print copyright and quit'
997
- out.puts
998
- out.puts 'Tasks:'
999
- TASKS.each do |name, desc|
1000
- out.printf fmt, name, desc
1001
- end
1002
-
1003
- fmt = " %-24s %s [%s]\n"
1004
- out.puts
1005
- out.puts 'Options for CONFIG or ALL:'
1006
- @config.each do |item|
1007
- out.printf fmt, item.help_opt, item.description, item.help_default
1008
- end
1009
- out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
1010
- out.puts
1011
- out.puts 'Options for INSTALL:'
1012
- out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
1013
- out.printf fmt, '--prefix=path', 'install path prefix', ''
1014
- out.puts
1015
- end
1016
-
1017
- #
1018
- # Task Handlers
1019
- #
1020
-
1021
- def exec_config
1022
- @installer.exec_config
1023
- @config.save # must be final
1024
- end
1025
-
1026
- def exec_setup
1027
- @installer.exec_setup
1028
- end
1029
-
1030
- def exec_install
1031
- @installer.exec_install
1032
- end
1033
-
1034
- def exec_test
1035
- @installer.exec_test
1036
- end
1037
-
1038
- def exec_show
1039
- @config.each do |i|
1040
- printf "%-20s %s\n", i.name, i.value if i.value?
1041
- end
1042
- end
1043
-
1044
- def exec_clean
1045
- @installer.exec_clean
1046
- end
1047
-
1048
- def exec_distclean
1049
- @installer.exec_distclean
1050
- end
1051
-
1052
- end # class ToplevelInstaller
1053
-
1054
-
1055
- class ToplevelInstallerMulti < ToplevelInstaller
1056
-
1057
- include FileOperations
1058
-
1059
- def initialize(ardir_root, config)
1060
- super
1061
- @packages = directories_of("#{@ardir}/#{PACKAGES_DIRECTORY}")
1062
- raise 'no package exists' if @packages.empty?
1063
- @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
1064
- end
1065
-
1066
- def run_metaconfigs
1067
- @config.load_script "#{@ardir}/metaconfig", self
1068
- @packages.each do |name|
1069
- @config.load_script "#{@ardir}/#{PACKAGES_DIRECTORY}/#{name}/metaconfig"
1070
- end
1071
- end
1072
-
1073
- attr_reader :packages
1074
-
1075
- def packages=(list)
1076
- raise 'package list is empty' if list.empty?
1077
- list.each do |name|
1078
- raise "directory #{PACKAGES_DIRECTORY}/#{name} does not exist"\
1079
- unless File.dir?("#{@ardir}/#{PACKAGES_DIRECTORY}/#{name}")
1080
- end
1081
- @packages = list
1082
- end
1083
-
1084
- def init_installers
1085
- @installers = {}
1086
- @packages.each do |pack|
1087
- @installers[pack] = Installer.new(@config,
1088
- "#{@ardir}/#{PACKAGES_DIRECTORY}/#{pack}",
1089
- "#{PACKAGES_DIRECTORY}/#{pack}")
1090
- end
1091
- with = extract_selection(config('with'))
1092
- without = extract_selection(config('without'))
1093
- @selected = @installers.keys.select {|name|
1094
- (with.empty? or with.include?(name)) \
1095
- and not without.include?(name)
1096
- }
1097
- end
1098
-
1099
- def extract_selection(list)
1100
- a = list.split(/,/)
1101
- a.each do |name|
1102
- setup_rb_error "no such package: #{name}" unless @installers.key?(name)
1103
- end
1104
- a
1105
- end
1106
-
1107
- def print_usage(f)
1108
- super
1109
- f.puts 'Inluded packages:'
1110
- f.puts ' ' + @packages.sort.join(' ')
1111
- f.puts
1112
- end
1113
-
1114
- #
1115
- # Task Handlers
1116
- #
1117
-
1118
- def exec_config
1119
- run_hook 'pre-config'
1120
- each_selected_installers {|inst| inst.exec_config }
1121
- run_hook 'post-config'
1122
- @config.save # must be final
1123
- end
1124
-
1125
- def exec_setup
1126
- run_hook 'pre-setup'
1127
- each_selected_installers {|inst| inst.exec_setup }
1128
- run_hook 'post-setup'
1129
- end
1130
-
1131
- def exec_install
1132
- run_hook 'pre-install'
1133
- each_selected_installers {|inst| inst.exec_install }
1134
- run_hook 'post-install'
1135
- end
1136
-
1137
- def exec_test
1138
- run_hook 'pre-test'
1139
- each_selected_installers {|inst| inst.exec_test }
1140
- run_hook 'post-test'
1141
- end
1142
-
1143
- def exec_clean
1144
- rm_f @config.savefile
1145
- run_hook 'pre-clean'
1146
- each_selected_installers {|inst| inst.exec_clean }
1147
- run_hook 'post-clean'
1148
- end
1149
-
1150
- def exec_distclean
1151
- rm_f @config.savefile
1152
- run_hook 'pre-distclean'
1153
- each_selected_installers {|inst| inst.exec_distclean }
1154
- run_hook 'post-distclean'
1155
- end
1156
-
1157
- #
1158
- # lib
1159
- #
1160
-
1161
- def each_selected_installers
1162
- Dir.mkdir PACKAGES_DIRECTORY unless File.dir?(PACKAGES_DIRECTORY)
1163
- @selected.each do |pack|
1164
- $stderr.puts "Processing the package `#{pack}' ..." if verbose?
1165
- Dir.mkdir "#{PACKAGES_DIRECTORY}/#{pack}" unless File.dir?("#{PACKAGES_DIRECTORY}/#{pack}")
1166
- Dir.chdir "#{PACKAGES_DIRECTORY}/#{pack}"
1167
- yield @installers[pack]
1168
- Dir.chdir '../..'
1169
- end
1170
- end
1171
-
1172
- def run_hook(id)
1173
- @root_installer.run_hook id
1174
- end
1175
-
1176
- # module FileOperations requires this
1177
- def verbose?
1178
- @config.verbose?
1179
- end
1180
-
1181
- # module FileOperations requires this
1182
- def no_harm?
1183
- @config.no_harm?
1184
- end
1185
-
1186
- end # class ToplevelInstallerMulti
1187
-
1188
-
1189
- class Installer
1190
-
1191
- FILETYPES = %w( bin lib ext data conf man )
1192
-
1193
- include FileOperations
1194
- include HookScriptAPI
1195
-
1196
- def initialize(config, srcroot, objroot)
1197
- @config = config
1198
- @srcdir = File.expand_path(srcroot)
1199
- @objdir = File.expand_path(objroot)
1200
- @currdir = '.'
1201
- end
1202
-
1203
- def inspect
1204
- "#<#{self.class} #{File.basename(@srcdir)}>"
1205
- end
1206
-
1207
- def noop(rel)
1208
- end
1209
-
1210
- #
1211
- # Hook Script API base methods
1212
- #
1213
-
1214
- def srcdir_root
1215
- @srcdir
1216
- end
1217
-
1218
- def objdir_root
1219
- @objdir
1220
- end
1221
-
1222
- def relpath
1223
- @currdir
1224
- end
1225
-
1226
- #
1227
- # Config Access
1228
- #
1229
-
1230
- # module FileOperations requires this
1231
- def verbose?
1232
- @config.verbose?
1233
- end
1234
-
1235
- # module FileOperations requires this
1236
- def no_harm?
1237
- @config.no_harm?
1238
- end
1239
-
1240
- def verbose_off
1241
- begin
1242
- save, @config.verbose = @config.verbose?, false
1243
- yield
1244
- ensure
1245
- @config.verbose = save
1246
- end
1247
- end
1248
-
1249
- #
1250
- # TASK config
1251
- #
1252
-
1253
- def exec_config
1254
- exec_task_traverse 'config'
1255
- end
1256
-
1257
- alias config_dir_bin noop
1258
- alias config_dir_lib noop
1259
-
1260
- def config_dir_ext(rel)
1261
- extconf if extdir?(curr_srcdir())
1262
- end
1263
-
1264
- alias config_dir_data noop
1265
- alias config_dir_conf noop
1266
- alias config_dir_man noop
1267
-
1268
- def extconf
1269
- ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1270
- end
1271
-
1272
- #
1273
- # TASK setup
1274
- #
1275
-
1276
- def exec_setup
1277
- exec_task_traverse 'setup'
1278
- end
1279
-
1280
- def setup_dir_bin(rel)
1281
- files_of(curr_srcdir()).each do |fname|
1282
- update_shebang_line "#{curr_srcdir()}/#{fname}"
1283
- end
1284
- end
1285
-
1286
- alias setup_dir_lib noop
1287
-
1288
- def setup_dir_ext(rel)
1289
- make if extdir?(curr_srcdir())
1290
- end
1291
-
1292
- alias setup_dir_data noop
1293
- alias setup_dir_conf noop
1294
- alias setup_dir_man noop
1295
-
1296
- def update_shebang_line(path)
1297
- return if no_harm?
1298
- return if config('shebang') == 'never'
1299
- old = Shebang.load(path)
1300
- if old
1301
- $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
1302
- new = new_shebang(old)
1303
- return if new.to_s == old.to_s
1304
- else
1305
- return unless config('shebang') == 'all'
1306
- new = Shebang.new(config('rubypath'))
1307
- end
1308
- $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
1309
- open_atomic_writer(path) {|output|
1310
- File.open(path, 'rb') {|f|
1311
- f.gets if old # discard
1312
- output.puts new.to_s
1313
- output.print f.read
1314
- }
1315
- }
1316
- end
1317
-
1318
- def new_shebang(old)
1319
- if /\Aruby/ =~ File.basename(old.cmd)
1320
- Shebang.new(config('rubypath'), old.args)
1321
- elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1322
- Shebang.new(config('rubypath'), old.args[1..-1])
1323
- else
1324
- return old unless config('shebang') == 'all'
1325
- Shebang.new(config('rubypath'))
1326
- end
1327
- end
1328
-
1329
- def open_atomic_writer(path, &block)
1330
- tmpfile = File.basename(path) + '.tmp'
1331
- begin
1332
- File.open(tmpfile, 'wb', &block)
1333
- File.rename tmpfile, File.basename(path)
1334
- ensure
1335
- File.unlink tmpfile if File.exist?(tmpfile)
1336
- end
1337
- end
1338
-
1339
- class Shebang
1340
- def Shebang.load(path)
1341
- line = nil
1342
- File.open(path) {|f|
1343
- line = f.gets
1344
- }
1345
- return nil unless /\A#!/ =~ line
1346
- parse(line)
1347
- end
1348
-
1349
- def Shebang.parse(line)
1350
- cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1351
- new(cmd, args)
1352
- end
1353
-
1354
- def initialize(cmd, args = [])
1355
- @cmd = cmd
1356
- @args = args
1357
- end
1358
-
1359
- attr_reader :cmd
1360
- attr_reader :args
1361
-
1362
- def to_s
1363
- "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1364
- end
1365
- end
1366
-
1367
- #
1368
- # TASK install
1369
- #
1370
-
1371
- def exec_install
1372
- rm_f "#{INSTALLED_MANIFEST}"
1373
- exec_task_traverse 'install'
1374
- end
1375
-
1376
- def install_dir_bin(rel)
1377
- install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
1378
- end
1379
-
1380
- def install_dir_lib(rel)
1381
- install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
1382
- end
1383
-
1384
- def install_dir_ext(rel)
1385
- return unless extdir?(curr_srcdir())
1386
- install_files rubyextentions('.'),
1387
- "#{config('sodir')}/#{File.dirname(rel)}",
1388
- 0555
1389
- end
1390
-
1391
- def install_dir_data(rel)
1392
- install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
1393
- end
1394
-
1395
- def install_dir_conf(rel)
1396
- # FIXME: should not remove current config files
1397
- # (rename previous file to .old/.org)
1398
- install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
1399
- end
1400
-
1401
- def install_dir_man(rel)
1402
- install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
1403
- end
1404
-
1405
- def install_files(list, dest, mode)
1406
- mkdir_p dest, @config.install_prefix
1407
- list.each do |fname|
1408
- install fname, dest, mode, @config.install_prefix
1409
- end
1410
- end
1411
-
1412
- def libfiles
1413
- glob_reject(%w(*.y *.output), targetfiles())
1414
- end
1415
-
1416
- def rubyextentions(dir)
1417
- ents = glob_select("*.#{@config.dllext}", targetfiles())
1418
- if ents.empty?
1419
- setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1420
- end
1421
- ents
1422
- end
1423
-
1424
- def targetfiles
1425
- mapdir(existfiles() - hookfiles())
1426
- end
1427
-
1428
- def mapdir(ents)
1429
- ents.map {|ent|
1430
- if File.exist?(ent)
1431
- then ent # objdir
1432
- else "#{curr_srcdir()}/#{ent}" # srcdir
1433
- end
1434
- }
1435
- end
1436
-
1437
- # picked up many entries from cvs-1.11.1/src/ignore.c
1438
- JUNK_FILES = %w(
1439
- core RCSLOG tags TAGS .make.state
1440
- .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1441
- *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1442
-
1443
- *.org *.in .*
1444
- )
1445
-
1446
- def existfiles
1447
- glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1448
- end
1449
-
1450
- def hookfiles
1451
- %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1452
- %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1453
- }.flatten
1454
- end
1455
-
1456
- def glob_select(pat, ents)
1457
- re = globs2re([pat])
1458
- ents.select {|ent| re =~ ent }
1459
- end
1460
-
1461
- def glob_reject(pats, ents)
1462
- re = globs2re(pats)
1463
- ents.reject {|ent| re =~ ent }
1464
- end
1465
-
1466
- GLOB2REGEX = {
1467
- '.' => '\.',
1468
- '$' => '\$',
1469
- '#' => '\#',
1470
- '*' => '.*'
1471
- }
1472
-
1473
- def globs2re(pats)
1474
- /\A(?:#{
1475
- pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
1476
- })\z/
1477
- end
1478
-
1479
- #
1480
- # TASK test
1481
- #
1482
-
1483
- TESTDIR = 'test'
1484
-
1485
- def exec_test
1486
- unless File.directory?('test')
1487
- $stderr.puts 'no test in this package' if verbose?
1488
- return
1489
- end
1490
- $stderr.puts 'Running tests...' if verbose?
1491
- begin
1492
- require 'test/unit'
1493
- rescue LoadError
1494
- setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
1495
- end
1496
- runner = Test::Unit::AutoRunner.new(true)
1497
- runner.to_run << TESTDIR
1498
- runner.run
1499
- end
1500
-
1501
- #
1502
- # TASK clean
1503
- #
1504
-
1505
- def exec_clean
1506
- exec_task_traverse 'clean'
1507
- rm_f @config.savefile
1508
- rm_f "#{INSTALLED_MANIFEST}"
1509
- end
1510
-
1511
- alias clean_dir_bin noop
1512
- alias clean_dir_lib noop
1513
- alias clean_dir_data noop
1514
- alias clean_dir_conf noop
1515
- alias clean_dir_man noop
1516
-
1517
- def clean_dir_ext(rel)
1518
- return unless extdir?(curr_srcdir())
1519
- make 'clean' if File.file?('Makefile')
1520
- end
1521
-
1522
- #
1523
- # TASK distclean
1524
- #
1525
-
1526
- def exec_distclean
1527
- exec_task_traverse 'distclean'
1528
- rm_f @config.savefile
1529
- rm_f "#{INSTALLED_MANIFEST}"
1530
- end
1531
-
1532
- alias distclean_dir_bin noop
1533
- alias distclean_dir_lib noop
1534
-
1535
- def distclean_dir_ext(rel)
1536
- return unless extdir?(curr_srcdir())
1537
- make 'distclean' if File.file?('Makefile')
1538
- end
1539
-
1540
- alias distclean_dir_data noop
1541
- alias distclean_dir_conf noop
1542
- alias distclean_dir_man noop
1543
-
1544
- #
1545
- # Traversing
1546
- #
1547
-
1548
- def exec_task_traverse(task)
1549
- run_hook "pre-#{task}"
1550
- FILETYPES.each do |type|
1551
- if type == 'ext' and config('without-ext') == 'yes'
1552
- $stderr.puts 'skipping ext/* by user option' if verbose?
1553
- next
1554
- end
1555
- traverse task, type, "#{task}_dir_#{type}"
1556
- end
1557
- run_hook "post-#{task}"
1558
- end
1559
-
1560
- def traverse(task, rel, mid)
1561
- dive_into(rel) {
1562
- run_hook "pre-#{task}"
1563
- __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1564
- directories_of(curr_srcdir()).each do |d|
1565
- traverse task, "#{rel}/#{d}", mid
1566
- end
1567
- run_hook "post-#{task}"
1568
- }
1569
- end
1570
-
1571
- def dive_into(rel)
1572
- return unless File.dir?("#{@srcdir}/#{rel}")
1573
-
1574
- dir = File.basename(rel)
1575
- Dir.mkdir dir unless File.dir?(dir)
1576
- prevdir = Dir.pwd
1577
- Dir.chdir dir
1578
- $stderr.puts '---> ' + rel if verbose?
1579
- @currdir = rel
1580
- yield
1581
- Dir.chdir prevdir
1582
- $stderr.puts '<--- ' + rel if verbose?
1583
- @currdir = File.dirname(rel)
1584
- end
1585
-
1586
- def run_hook(id)
1587
- path = [ "#{curr_srcdir()}/#{id}",
1588
- "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
1589
- return unless path
1590
- begin
1591
- instance_eval File.read(path), path, 1
1592
- rescue
1593
- raise if $DEBUG
1594
- setup_rb_error "hook #{path} failed:\n" + $!.message
1595
- end
1596
- end
1597
-
1598
- end # class Installer
1599
-
1600
-
1601
- class SetupError < StandardError; end
1602
-
1603
- def setup_rb_error(msg)
1604
- raise SetupError, msg
1605
- end
1606
-
1607
- if $0 == __FILE__
1608
- begin
1609
- ToplevelInstaller.invoke
1610
- rescue SetupError
1611
- raise if $DEBUG
1612
- $stderr.puts $!.message
1613
- $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1614
- exit 1
1615
- end
1616
- end