jumoku 0.2.0 → 0.2.1

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