Develop and Download Open Source Software

Browse CVS Repository

Annotation of /exerb/exerb/setup.rb

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download)
Wed Oct 12 02:39:14 2005 UTC (18 years, 6 months ago) by yuya
Branch: MAIN
Changes since 1.3: +795 -575 lines
* setup.rbを3.4.0に変更

1 yuya 1.1 #
2     # setup.rb
3     #
4 yuya 1.4 # Copyright (c) 2000-2005 Minero Aoki
5 yuya 1.1 #
6 yuya 1.2 # This program is free software.
7     # You can distribute/modify this program under the terms of
8 yuya 1.4 # the GNU LGPL, Lesser General Public License version 2.1.
9 yuya 1.1 #
10    
11 yuya 1.4 unless Enumerable.method_defined?(:map) # Ruby 1.4.6
12 yuya 1.2 module Enumerable
13 yuya 1.1 alias map collect
14     end
15 yuya 1.2 end
16 yuya 1.1
17 yuya 1.4 unless File.respond_to?(:read) # Ruby 1.6
18 yuya 1.2 def File.read(fname)
19 yuya 1.3 open(fname) {|f|
20 yuya 1.2 return f.read
21     }
22     end
23     end
24 yuya 1.3
25 yuya 1.4 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 yuya 1.1
33 yuya 1.3 def File.binread(fname)
34     open(fname, 'rb') {|f|
35     return f.read
36     }
37     end
38 yuya 1.1
39 yuya 1.4 # for corrupted Windows' stat(2)
40 yuya 1.3 def File.dir?(path)
41     File.directory?((path[-1,1] == '/') ? path : path + '/')
42 yuya 1.2 end
43    
44 yuya 1.1
45 yuya 1.4 class ConfigTable
46 yuya 1.1
47 yuya 1.4 include Enumerable
48 yuya 1.3
49 yuya 1.4 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 yuya 1.3
61 yuya 1.4 attr_accessor :install_prefix
62     attr_accessor :config_opt
63 yuya 1.1
64 yuya 1.4 attr_writer :verbose
65 yuya 1.1
66 yuya 1.4 def verbose?
67     @verbose
68     end
69 yuya 1.1
70 yuya 1.4 attr_writer :no_harm
71 yuya 1.1
72 yuya 1.4 def no_harm?
73     @no_harm
74 yuya 1.1 end
75    
76 yuya 1.4 attr_accessor :libsrc_pattern
77 yuya 1.1
78 yuya 1.4 def [](key)
79     lookup(key).resolve(self)
80 yuya 1.1 end
81    
82 yuya 1.4 def []=(key, val)
83     lookup(key).set val
84 yuya 1.1 end
85    
86 yuya 1.4 def names
87     @items.map {|i| i.name }
88 yuya 1.1 end
89    
90 yuya 1.4 def each(&block)
91     @items.each(&block)
92 yuya 1.1 end
93    
94 yuya 1.4 def key?(name)
95     @table.key?(name)
96 yuya 1.1 end
97    
98 yuya 1.4 def lookup(name)
99     @table[name] or setup_rb_error "no such config item: #{name}"
100 yuya 1.1 end
101    
102 yuya 1.4 def add(item)
103     @items.push item
104     @table[item.name] = item
105 yuya 1.1 end
106    
107 yuya 1.4 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 yuya 1.1 end
113    
114 yuya 1.4 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 yuya 1.1 end
119    
120 yuya 1.4 def savefile
121     '.config'
122 yuya 1.1 end
123    
124 yuya 1.4 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 yuya 1.1 end
134    
135 yuya 1.4 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 yuya 1.1 end
143    
144 yuya 1.4 def load_standard_entries
145     standard_entries(@rbconfig).each do |ent|
146     add ent
147     end
148 yuya 1.1 end
149    
150 yuya 1.4 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 yuya 1.1
195 yuya 1.4 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 yuya 1.1 end
200    
201 yuya 1.4 [
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 yuya 1.1 end
302 yuya 1.4 @items.freeze
303     @table.freeze
304     @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
305 yuya 1.1 end
306    
307 yuya 1.4 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 yuya 1.1 end
311    
312 yuya 1.4 def dllext
313     @rbconfig['DLEXT']
314 yuya 1.1 end
315 yuya 1.4
316     def value_config?(name)
317     lookup(name).value?
318 yuya 1.1 end
319    
320 yuya 1.4 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 yuya 1.1
357 yuya 1.4 def check(val)
358     setup_rb_error "config: --#{name} requires argument" unless val
359     val
360     end
361 yuya 1.1 end
362    
363 yuya 1.4 class BoolItem < Item
364     def config_type
365     'bool'
366     end
367 yuya 1.1
368 yuya 1.4 def help_opt
369     "--#{@name}"
370     end
371 yuya 1.1
372 yuya 1.4 private
373 yuya 1.1
374 yuya 1.4 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 yuya 1.1 end
382    
383 yuya 1.4 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 yuya 1.1 end
395    
396 yuya 1.4 class ProgramItem < Item
397     def config_type
398     'program'
399     end
400 yuya 1.1 end
401    
402 yuya 1.4 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 yuya 1.1 end
421    
422 yuya 1.4 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 yuya 1.1 end
451    
452 yuya 1.4 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 yuya 1.1 end
473    
474 yuya 1.4 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 yuya 1.1
512 yuya 1.4 def set_config_default(name, default)
513     @config.lookup(name).default = default
514     end
515 yuya 1.1
516 yuya 1.4 def remove_config(name)
517     @config.remove(name)
518     end
519 yuya 1.1
520 yuya 1.4 # 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 yuya 1.1 end
525    
526 yuya 1.4 # 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 yuya 1.1 end
532    
533 yuya 1.4 end # class ConfigTable
534 yuya 1.3
535 yuya 1.1
536 yuya 1.4 # This module requires: #verbose?, #no_harm?
537 yuya 1.3 module FileOperations
538    
539     def mkdir_p(dirname, prefix = nil)
540 yuya 1.4 dirname = prefix + File.expand_path(dirname) if prefix
541 yuya 1.3 $stderr.puts "mkdir -p #{dirname}" if verbose?
542     return if no_harm?
543    
544 yuya 1.4 # Does not check '/', it's too abnormal.
545     dirs = File.expand_path(dirname).split(%r<(?=/)>)
546 yuya 1.3 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 yuya 1.4 def rm_f(path)
557     $stderr.puts "rm -f #{path}" if verbose?
558 yuya 1.3 return if no_harm?
559 yuya 1.4 force_remove_file path
560     end
561 yuya 1.3
562 yuya 1.4 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 yuya 1.3 end
576     end
577    
578 yuya 1.4 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 yuya 1.3 else
588 yuya 1.4 force_remove_file entpath
589 yuya 1.3 end
590     end
591 yuya 1.4 begin
592     Dir.rmdir path
593     rescue Errno::ENOTEMPTY
594     # directory may not be empty
595     end
596 yuya 1.3 end
597    
598     def move_file(src, dest)
599 yuya 1.4 force_remove_file dest
600 yuya 1.3 begin
601     File.rename src, dest
602     rescue
603 yuya 1.4 File.open(dest, 'wb') {|f|
604     f.write File.binread(src)
605     }
606 yuya 1.3 File.chmod File.stat(src).mode, dest
607     File.unlink src
608     end
609     end
610    
611 yuya 1.4 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 yuya 1.3 def install(from, dest, mode, prefix = nil)
624     $stderr.puts "install #{from} #{dest}" if verbose?
625     return if no_harm?
626    
627 yuya 1.4 realdest = prefix ? prefix + File.expand_path(dest) : dest
628 yuya 1.3 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 yuya 1.4 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 yuya 1.3 end
659    
660 yuya 1.4 def ruby(*args)
661     command config('rubyprog'), *args
662 yuya 1.3 end
663    
664 yuya 1.4 def make(task = nil)
665     command(*[config('makeprog'), task].compact)
666 yuya 1.3 end
667    
668     def extdir?(dir)
669 yuya 1.4 File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
670 yuya 1.3 end
671    
672 yuya 1.4 def files_of(dir)
673     Dir.open(dir) {|d|
674     return d.select {|ent| File.file?("#{dir}/#{ent}") }
675 yuya 1.3 }
676     end
677    
678 yuya 1.4 DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
679 yuya 1.3
680 yuya 1.4 def directories_of(dir)
681     Dir.open(dir) {|d|
682     return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
683 yuya 1.3 }
684     end
685    
686     end
687 yuya 1.1
688    
689 yuya 1.4 # This module requires: #srcdir_root, #objdir_root, #relpath
690 yuya 1.1 module HookScriptAPI
691    
692 yuya 1.2 def get_config(key)
693 yuya 1.1 @config[key]
694     end
695    
696     alias config get_config
697    
698 yuya 1.4 # obsolete: use metaconfig to change configuration
699 yuya 1.2 def set_config(key, val)
700 yuya 1.1 @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 yuya 1.2 def srcfile(path)
716 yuya 1.1 "#{curr_srcdir()}/#{path}"
717     end
718    
719 yuya 1.2 def srcexist?(path)
720     File.exist?(srcfile(path))
721 yuya 1.1 end
722    
723 yuya 1.2 def srcdirectory?(path)
724     File.dir?(srcfile(path))
725 yuya 1.1 end
726    
727 yuya 1.2 def srcfile?(path)
728 yuya 1.4 File.file?(srcfile(path))
729 yuya 1.1 end
730    
731 yuya 1.2 def srcentries(path = '.')
732 yuya 1.1 Dir.open("#{curr_srcdir()}/#{path}") {|d|
733     return d.to_a - %w(. ..)
734     }
735     end
736    
737 yuya 1.2 def srcfiles(path = '.')
738 yuya 1.1 srcentries(path).select {|fname|
739 yuya 1.2 File.file?(File.join(curr_srcdir(), path, fname))
740 yuya 1.1 }
741     end
742    
743 yuya 1.2 def srcdirectories(path = '.')
744 yuya 1.1 srcentries(path).select {|fname|
745 yuya 1.2 File.dir?(File.join(curr_srcdir(), path, fname))
746 yuya 1.1 }
747     end
748    
749     end
750    
751    
752 yuya 1.3 class ToplevelInstaller
753 yuya 1.1
754 yuya 1.4 Version = '3.4.0'
755     Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
756 yuya 1.1
757 yuya 1.3 TASKS = [
758 yuya 1.4 [ 'all', 'do config, setup, then install' ],
759 yuya 1.3 [ 'config', 'saves your configurations' ],
760     [ 'show', 'shows current configuration' ],
761     [ 'setup', 'compiles ruby extentions and others' ],
762     [ 'install', 'installs files' ],
763 yuya 1.4 [ 'test', 'run all tests in test/' ],
764 yuya 1.3 [ 'clean', "does `make clean' for each extention" ],
765     [ 'distclean',"does `make distclean' for each extention" ]
766     ]
767 yuya 1.1
768 yuya 1.3 def ToplevelInstaller.invoke
769 yuya 1.4 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 yuya 1.1 end
791    
792 yuya 1.4 def initialize(ardir_root, config)
793     @ardir = File.expand_path(ardir_root)
794     @config = config
795     # cache
796     @valid_task_re = nil
797 yuya 1.1 end
798    
799 yuya 1.4 def config(key)
800     @config[key]
801 yuya 1.1 end
802    
803 yuya 1.3 def inspect
804     "#<#{self.class} #{__id__()}>"
805 yuya 1.1 end
806    
807 yuya 1.3 def invoke
808     run_metaconfigs
809 yuya 1.4 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 yuya 1.1 end
830 yuya 1.4
831 yuya 1.3 def run_metaconfigs
832 yuya 1.4 @config.load_script "#{@ardir}/metaconfig"
833 yuya 1.1 end
834    
835 yuya 1.3 def init_installers
836 yuya 1.4 @installer = Installer.new(@config, @ardir, File.expand_path('.'))
837 yuya 1.1 end
838    
839     #
840 yuya 1.3 # Hook Script API bases
841 yuya 1.1 #
842    
843 yuya 1.3 def srcdir_root
844     @ardir
845 yuya 1.1 end
846    
847 yuya 1.3 def objdir_root
848     '.'
849 yuya 1.1 end
850    
851 yuya 1.3 def relpath
852     '.'
853 yuya 1.1 end
854    
855     #
856 yuya 1.3 # Option Parsing
857 yuya 1.1 #
858    
859 yuya 1.3 def parsearg_global
860     while arg = ARGV.shift
861     case arg
862     when /\A\w+\z/
863 yuya 1.4 setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
864 yuya 1.3 return arg
865     when '-q', '--quiet'
866 yuya 1.4 @config.verbose = false
867     when '--verbose'
868     @config.verbose = true
869     when '--help'
870 yuya 1.3 print_usage $stdout
871     exit 0
872 yuya 1.4 when '--version'
873 yuya 1.3 puts "#{File.basename($0)} version #{Version}"
874     exit 0
875     when '--copyright'
876     puts Copyright
877     exit 0
878     else
879 yuya 1.4 setup_rb_error "unknown global option '#{arg}'"
880 yuya 1.3 end
881 yuya 1.1 end
882 yuya 1.4 nil
883     end
884 yuya 1.3
885 yuya 1.4 def valid_task?(t)
886     valid_task_re() =~ t
887 yuya 1.1 end
888    
889 yuya 1.4 def valid_task_re
890     @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
891     end
892 yuya 1.1
893 yuya 1.3 def parsearg_no_options
894 yuya 1.4 unless ARGV.empty?
895     setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
896     end
897 yuya 1.1 end
898    
899 yuya 1.3 alias parsearg_show parsearg_no_options
900     alias parsearg_setup parsearg_no_options
901 yuya 1.4 alias parsearg_test parsearg_no_options
902 yuya 1.3 alias parsearg_clean parsearg_no_options
903     alias parsearg_distclean parsearg_no_options
904 yuya 1.1
905 yuya 1.3 def parsearg_config
906 yuya 1.4 evalopt = []
907     set = []
908     @config.config_opt = []
909 yuya 1.3 while i = ARGV.shift
910     if /\A--?\z/ =~ i
911 yuya 1.4 @config.config_opt = ARGV.dup
912 yuya 1.3 break
913     end
914 yuya 1.4 name, value = *@config.parse_opt(i)
915     if @config.value_config?(name)
916     @config[name] = value
917 yuya 1.3 else
918 yuya 1.4 evalopt.push [name, value]
919 yuya 1.3 end
920 yuya 1.4 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 yuya 1.3 end
929 yuya 1.1 end
930    
931 yuya 1.3 def parsearg_install
932 yuya 1.4 @config.no_harm = false
933     @config.install_prefix = ''
934 yuya 1.3 while a = ARGV.shift
935     case a
936 yuya 1.4 when '--no-harm'
937     @config.no_harm = true
938     when /\A--prefix=/
939     path = a.split(/=/, 2)[1]
940 yuya 1.3 path = File.expand_path(path) unless path[0,1] == '/'
941 yuya 1.4 @config.install_prefix = path
942 yuya 1.3 else
943 yuya 1.4 setup_rb_error "install: unknown option #{a}"
944 yuya 1.3 end
945     end
946 yuya 1.1 end
947    
948 yuya 1.3 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 yuya 1.1
958 yuya 1.4 fmt = " %-24s %s\n"
959 yuya 1.3 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 yuya 1.4 out.printf fmt, ' --help', 'print this message'
964     out.printf fmt, ' --version', 'print version and quit'
965 yuya 1.3 out.printf fmt, ' --copyright', 'print copyright and quit'
966     out.puts
967     out.puts 'Tasks:'
968     TASKS.each do |name, desc|
969 yuya 1.4 out.printf fmt, name, desc
970 yuya 1.3 end
971 yuya 1.1
972 yuya 1.4 fmt = " %-24s %s [%s]\n"
973 yuya 1.3 out.puts
974 yuya 1.4 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 yuya 1.1 end
978 yuya 1.4 out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
979 yuya 1.3 out.puts
980 yuya 1.4 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 yuya 1.3 out.puts
984 yuya 1.1 end
985    
986 yuya 1.3 #
987     # Task Handlers
988     #
989 yuya 1.1
990 yuya 1.3 def exec_config
991     @installer.exec_config
992     @config.save # must be final
993 yuya 1.1 end
994    
995 yuya 1.3 def exec_setup
996     @installer.exec_setup
997 yuya 1.1 end
998    
999 yuya 1.3 def exec_install
1000     @installer.exec_install
1001 yuya 1.1 end
1002    
1003 yuya 1.4 def exec_test
1004     @installer.exec_test
1005     end
1006    
1007 yuya 1.3 def exec_show
1008 yuya 1.4 @config.each do |i|
1009     printf "%-20s %s\n", i.name, i.value if i.value?
1010 yuya 1.3 end
1011 yuya 1.1 end
1012    
1013 yuya 1.3 def exec_clean
1014     @installer.exec_clean
1015 yuya 1.1 end
1016    
1017 yuya 1.3 def exec_distclean
1018     @installer.exec_distclean
1019 yuya 1.1 end
1020    
1021 yuya 1.4 end # class ToplevelInstaller
1022 yuya 1.1
1023    
1024 yuya 1.3 class ToplevelInstallerMulti < ToplevelInstaller
1025 yuya 1.1
1026 yuya 1.3 include FileOperations
1027 yuya 1.1
1028 yuya 1.4 def initialize(ardir_root, config)
1029 yuya 1.3 super
1030 yuya 1.4 @packages = directories_of("#{@ardir}/packages")
1031 yuya 1.3 raise 'no package exists' if @packages.empty?
1032 yuya 1.4 @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
1033 yuya 1.1 end
1034    
1035 yuya 1.3 def run_metaconfigs
1036 yuya 1.4 @config.load_script "#{@ardir}/metaconfig", self
1037 yuya 1.3 @packages.each do |name|
1038 yuya 1.4 @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
1039 yuya 1.3 end
1040 yuya 1.1 end
1041    
1042 yuya 1.4 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 yuya 1.3 def init_installers
1054     @installers = {}
1055     @packages.each do |pack|
1056 yuya 1.4 @installers[pack] = Installer.new(@config,
1057 yuya 1.3 "#{@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 yuya 1.1 end
1067    
1068 yuya 1.3 def extract_selection(list)
1069     a = list.split(/,/)
1070     a.each do |name|
1071 yuya 1.4 setup_rb_error "no such package: #{name}" unless @installers.key?(name)
1072 yuya 1.3 end
1073     a
1074 yuya 1.1 end
1075    
1076 yuya 1.3 def print_usage(f)
1077     super
1078     f.puts 'Inluded packages:'
1079     f.puts ' ' + @packages.sort.join(' ')
1080     f.puts
1081 yuya 1.1 end
1082    
1083     #
1084 yuya 1.3 # 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 yuya 1.1 end
1093    
1094 yuya 1.3 def exec_setup
1095     run_hook 'pre-setup'
1096     each_selected_installers {|inst| inst.exec_setup }
1097     run_hook 'post-setup'
1098 yuya 1.1 end
1099    
1100 yuya 1.3 def exec_install
1101     run_hook 'pre-install'
1102     each_selected_installers {|inst| inst.exec_install }
1103     run_hook 'post-install'
1104 yuya 1.1 end
1105    
1106 yuya 1.4 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 yuya 1.3 def exec_clean
1113 yuya 1.4 rm_f @config.savefile
1114 yuya 1.3 run_hook 'pre-clean'
1115     each_selected_installers {|inst| inst.exec_clean }
1116     run_hook 'post-clean'
1117     end
1118 yuya 1.1
1119 yuya 1.3 def exec_distclean
1120 yuya 1.4 rm_f @config.savefile
1121 yuya 1.3 run_hook 'pre-distclean'
1122     each_selected_installers {|inst| inst.exec_distclean }
1123     run_hook 'post-distclean'
1124 yuya 1.1 end
1125    
1126 yuya 1.3 #
1127     # lib
1128     #
1129 yuya 1.1
1130 yuya 1.3 def each_selected_installers
1131     Dir.mkdir 'packages' unless File.dir?('packages')
1132     @selected.each do |pack|
1133 yuya 1.4 $stderr.puts "Processing the package `#{pack}' ..." if verbose?
1134 yuya 1.3 Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1135     Dir.chdir "packages/#{pack}"
1136     yield @installers[pack]
1137     Dir.chdir '../..'
1138     end
1139 yuya 1.1 end
1140    
1141 yuya 1.4 def run_hook(id)
1142     @root_installer.run_hook id
1143     end
1144    
1145     # module FileOperations requires this
1146 yuya 1.3 def verbose?
1147 yuya 1.4 @config.verbose?
1148 yuya 1.1 end
1149    
1150 yuya 1.4 # module FileOperations requires this
1151 yuya 1.3 def no_harm?
1152 yuya 1.4 @config.no_harm?
1153 yuya 1.1 end
1154    
1155 yuya 1.4 end # class ToplevelInstallerMulti
1156 yuya 1.3
1157    
1158     class Installer
1159    
1160 yuya 1.4 FILETYPES = %w( bin lib ext data conf man )
1161 yuya 1.3
1162 yuya 1.4 include FileOperations
1163 yuya 1.3 include HookScriptAPI
1164 yuya 1.1
1165 yuya 1.4 def initialize(config, srcroot, objroot)
1166 yuya 1.3 @config = config
1167     @srcdir = File.expand_path(srcroot)
1168     @objdir = File.expand_path(objroot)
1169     @currdir = '.'
1170 yuya 1.1 end
1171    
1172 yuya 1.3 def inspect
1173     "#<#{self.class} #{File.basename(@srcdir)}>"
1174 yuya 1.1 end
1175    
1176     #
1177 yuya 1.4 # Hook Script API base methods
1178 yuya 1.1 #
1179    
1180     def srcdir_root
1181 yuya 1.3 @srcdir
1182 yuya 1.1 end
1183    
1184     def objdir_root
1185 yuya 1.3 @objdir
1186 yuya 1.1 end
1187    
1188     def relpath
1189 yuya 1.3 @currdir
1190 yuya 1.1 end
1191    
1192     #
1193 yuya 1.4 # Config Access
1194 yuya 1.1 #
1195    
1196 yuya 1.4 # module FileOperations requires this
1197     def verbose?
1198     @config.verbose?
1199 yuya 1.3 end
1200 yuya 1.1
1201 yuya 1.4 # module FileOperations requires this
1202     def no_harm?
1203     @config.no_harm?
1204 yuya 1.3 end
1205 yuya 1.1
1206 yuya 1.3 def verbose_off
1207     begin
1208 yuya 1.4 save, @config.verbose = @config.verbose?, false
1209 yuya 1.3 yield
1210     ensure
1211 yuya 1.4 @config.verbose = save
1212 yuya 1.3 end
1213     end
1214 yuya 1.1
1215 yuya 1.3 #
1216     # TASK config
1217     #
1218 yuya 1.1
1219 yuya 1.3 def exec_config
1220     exec_task_traverse 'config'
1221     end
1222 yuya 1.1
1223 yuya 1.3 def config_dir_bin(rel)
1224     end
1225 yuya 1.1
1226 yuya 1.3 def config_dir_lib(rel)
1227     end
1228 yuya 1.1
1229 yuya 1.4 def config_dir_man(rel)
1230     end
1231    
1232 yuya 1.3 def config_dir_ext(rel)
1233     extconf if extdir?(curr_srcdir())
1234 yuya 1.1 end
1235    
1236 yuya 1.3 def extconf
1237 yuya 1.4 ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1238 yuya 1.3 end
1239 yuya 1.1
1240 yuya 1.3 def config_dir_data(rel)
1241 yuya 1.1 end
1242    
1243 yuya 1.4 def config_dir_conf(rel)
1244     end
1245    
1246 yuya 1.3 #
1247     # TASK setup
1248     #
1249 yuya 1.1
1250 yuya 1.3 def exec_setup
1251     exec_task_traverse 'setup'
1252     end
1253 yuya 1.1
1254 yuya 1.3 def setup_dir_bin(rel)
1255 yuya 1.4 files_of(curr_srcdir()).each do |fname|
1256 yuya 1.3 adjust_shebang "#{curr_srcdir()}/#{fname}"
1257 yuya 1.1 end
1258     end
1259    
1260 yuya 1.3 def adjust_shebang(path)
1261     return if no_harm?
1262     tmpfile = File.basename(path) + '.tmp'
1263     begin
1264     File.open(path, 'rb') {|r|
1265 yuya 1.4 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 yuya 1.3 File.open(tmpfile, 'wb') {|w|
1269 yuya 1.4 w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath'))
1270 yuya 1.3 w.write r.read
1271     }
1272     }
1273     move_file tmpfile, File.basename(path)
1274     ensure
1275     File.unlink tmpfile if File.exist?(tmpfile)
1276 yuya 1.1 end
1277 yuya 1.3 end
1278 yuya 1.1
1279 yuya 1.3 def setup_dir_lib(rel)
1280     end
1281 yuya 1.1
1282 yuya 1.4 def setup_dir_man(rel)
1283     end
1284    
1285 yuya 1.3 def setup_dir_ext(rel)
1286     make if extdir?(curr_srcdir())
1287     end
1288 yuya 1.1
1289 yuya 1.3 def setup_dir_data(rel)
1290 yuya 1.1 end
1291    
1292 yuya 1.4 def setup_dir_conf(rel)
1293     end
1294    
1295 yuya 1.1 #
1296 yuya 1.3 # TASK install
1297 yuya 1.1 #
1298    
1299 yuya 1.3 def exec_install
1300 yuya 1.4 rm_f 'InstalledFiles'
1301 yuya 1.3 exec_task_traverse 'install'
1302     end
1303    
1304     def install_dir_bin(rel)
1305 yuya 1.4 install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
1306 yuya 1.1 end
1307    
1308 yuya 1.3 def install_dir_lib(rel)
1309 yuya 1.4 install_files rubyscripts(), "#{config('rbdir')}/#{rel}", 0644
1310 yuya 1.1 end
1311    
1312 yuya 1.3 def install_dir_ext(rel)
1313     return unless extdir?(curr_srcdir())
1314 yuya 1.4 install_files rubyextentions('.'),
1315     "#{config('sodir')}/#{File.dirname(rel)}",
1316 yuya 1.3 0555
1317 yuya 1.1 end
1318    
1319 yuya 1.3 def install_dir_data(rel)
1320 yuya 1.4 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 yuya 1.1 end
1332    
1333 yuya 1.3 def install_files(list, dest, mode)
1334 yuya 1.4 mkdir_p dest, @config.install_prefix
1335 yuya 1.3 list.each do |fname|
1336 yuya 1.4 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 yuya 1.3 end
1349 yuya 1.4 ents
1350 yuya 1.1 end
1351    
1352 yuya 1.4 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 yuya 1.1 end
1364 yuya 1.4
1365 yuya 1.3 # picked up many entries from cvs-1.11.1/src/ignore.c
1366 yuya 1.4 JUNK_FILES = %w(
1367 yuya 1.3 core RCSLOG tags TAGS .make.state
1368     .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1369     *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1370 yuya 1.1
1371 yuya 1.3 *.org *.in .*
1372     )
1373 yuya 1.1
1374 yuya 1.3 def existfiles
1375 yuya 1.4 glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1376 yuya 1.3 end
1377 yuya 1.1
1378 yuya 1.3 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 yuya 1.1
1384 yuya 1.4 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 yuya 1.1 end
1393    
1394 yuya 1.4 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 yuya 1.1 end
1406    
1407 yuya 1.4 #
1408     # TASK test
1409     #
1410    
1411     TESTDIR = 'test'
1412 yuya 1.1
1413 yuya 1.4 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 yuya 1.1 end
1424    
1425 yuya 1.3 #
1426     # TASK clean
1427     #
1428    
1429     def exec_clean
1430     exec_task_traverse 'clean'
1431 yuya 1.4 rm_f @config.savefile
1432 yuya 1.3 rm_f 'InstalledFiles'
1433 yuya 1.1 end
1434    
1435 yuya 1.3 def clean_dir_bin(rel)
1436 yuya 1.1 end
1437    
1438 yuya 1.3 def clean_dir_lib(rel)
1439     end
1440 yuya 1.1
1441 yuya 1.3 def clean_dir_ext(rel)
1442     return unless extdir?(curr_srcdir())
1443     make 'clean' if File.file?('Makefile')
1444     end
1445 yuya 1.1
1446 yuya 1.3 def clean_dir_data(rel)
1447 yuya 1.1 end
1448    
1449 yuya 1.4 def clean_dir_conf(rel)
1450     end
1451    
1452 yuya 1.1 #
1453 yuya 1.3 # TASK distclean
1454 yuya 1.1 #
1455    
1456 yuya 1.3 def exec_distclean
1457     exec_task_traverse 'distclean'
1458 yuya 1.4 rm_f @config.savefile
1459 yuya 1.3 rm_f 'InstalledFiles'
1460 yuya 1.1 end
1461    
1462 yuya 1.3 def distclean_dir_bin(rel)
1463 yuya 1.1 end
1464    
1465 yuya 1.3 def distclean_dir_lib(rel)
1466 yuya 1.1 end
1467    
1468 yuya 1.3 def distclean_dir_ext(rel)
1469     return unless extdir?(curr_srcdir())
1470     make 'distclean' if File.file?('Makefile')
1471 yuya 1.1 end
1472    
1473 yuya 1.4 def distclean_dir_data(rel)
1474     end
1475    
1476     def distclean_dir_conf(rel)
1477     end
1478    
1479 yuya 1.1 #
1480     # lib
1481     #
1482    
1483 yuya 1.3 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 yuya 1.1 end
1492 yuya 1.3 run_hook "post-#{task}"
1493 yuya 1.1 end
1494    
1495 yuya 1.3 def traverse(task, rel, mid)
1496     dive_into(rel) {
1497     run_hook "pre-#{task}"
1498     __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1499 yuya 1.4 directories_of(curr_srcdir()).each do |d|
1500 yuya 1.3 traverse task, "#{rel}/#{d}", mid
1501     end
1502     run_hook "post-#{task}"
1503     }
1504 yuya 1.1 end
1505    
1506 yuya 1.3 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 yuya 1.1 end
1520    
1521 yuya 1.4 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 yuya 1.1 end
1541    
1542     if $0 == __FILE__
1543     begin
1544 yuya 1.4 ToplevelInstaller.invoke
1545     rescue SetupError
1546 yuya 1.1 raise if $DEBUG
1547     $stderr.puts $!.message
1548     $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1549     exit 1
1550     end
1551     end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26