libxml-ruby 3.2.4-x64-mingw-ucrt → 4.1.1-x64-mingw-ucrt

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