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.2 - (hide annotations) (download)
Thu Feb 12 16:28:39 2004 UTC (20 years, 2 months ago) by yuya
Branch: MAIN
Changes since 1.1: +179 -171 lines
* setup.rbを3.2.3に変更

1 yuya 1.1 #
2     # This file is automatically generated. DO NOT MODIFY!
3     #
4     # setup.rb
5     #
6 yuya 1.2 # Copyright (c) 2000-2003 Minero Aoki <aamine@loveruby.net>
7 yuya 1.1 #
8 yuya 1.2 # This program is free software.
9     # You can distribute/modify this program under the terms of
10     # the GNU Lesser General Public License version 2.
11 yuya 1.1 #
12    
13     def multipackage_install?
14     FileTest.directory?(File.dirname($0) + '/packages')
15     end
16    
17     #
18     # compat.rb
19     #
20    
21 yuya 1.2 unless Enumerable.method_defined?(:map)
22     module Enumerable
23 yuya 1.1 alias map collect
24     end
25 yuya 1.2 end
26 yuya 1.1
27 yuya 1.2 unless Enumerable.method_defined?(:select)
28     module Enumerable
29 yuya 1.1 alias select find_all
30     end
31 yuya 1.2 end
32 yuya 1.1
33 yuya 1.2 unless Enumerable.method_defined?(:reject)
34     module Enumerable
35 yuya 1.1 def reject
36     result = []
37     each do |i|
38     result.push i unless yield(i)
39     end
40     result
41     end
42     end
43 yuya 1.2 end
44 yuya 1.1
45 yuya 1.2 unless Enumerable.method_defined?(:inject)
46     module Enumerable
47     def inject(result)
48 yuya 1.1 each do |i|
49     result = yield(result, i)
50     end
51     result
52     end
53     end
54 yuya 1.2 end
55 yuya 1.1
56 yuya 1.2 unless Enumerable.method_defined?(:any?)
57     module Enumerable
58 yuya 1.1 def any?
59     each do |i|
60     return true if yield(i)
61     end
62     false
63     end
64     end
65     end
66 yuya 1.2
67     unless File.respond_to?(:read)
68     def File.read(fname)
69     File.open(fname, 'rb') {|f|
70     return f.read
71     }
72     end
73     end
74 yuya 1.1 #
75     # fileop.rb
76     #
77    
78     module FileOperations
79    
80 yuya 1.2 def mkdir_p(dirname, prefix = nil)
81 yuya 1.1 dirname = prefix + dirname if prefix
82     $stderr.puts "mkdir -p #{dirname}" if verbose?
83     return if no_harm?
84    
85     # does not check '/'... it's too abnormal case
86     dirs = dirname.split(%r<(?=/)>)
87 yuya 1.2 if /\A[a-z]:\z/i =~ dirs[0]
88 yuya 1.1 disk = dirs.shift
89     dirs[0] = disk + dirs[0]
90     end
91     dirs.each_index do |idx|
92     path = dirs[0..idx].join('')
93 yuya 1.2 Dir.mkdir path unless File.dir?(path)
94 yuya 1.1 end
95     end
96    
97 yuya 1.2 def rm_f(fname)
98 yuya 1.1 $stderr.puts "rm -f #{fname}" if verbose?
99     return if no_harm?
100    
101 yuya 1.2 if File.exist?(fname) or File.symlink?(fname)
102 yuya 1.1 File.chmod 0777, fname
103     File.unlink fname
104     end
105     end
106    
107 yuya 1.2 def rm_rf(dn)
108 yuya 1.1 $stderr.puts "rm -rf #{dn}" if verbose?
109     return if no_harm?
110    
111     Dir.chdir dn
112     Dir.foreach('.') do |fn|
113     next if fn == '.'
114     next if fn == '..'
115 yuya 1.2 if File.dir?(fn)
116 yuya 1.1 verbose_off {
117     rm_rf fn
118     }
119     else
120     verbose_off {
121     rm_f fn
122     }
123     end
124     end
125     Dir.chdir '..'
126     Dir.rmdir dn
127     end
128    
129 yuya 1.2 def move_file(src, dest)
130     File.unlink dest if File.exist?(dest)
131 yuya 1.1 begin
132     File.rename src, dest
133     rescue
134 yuya 1.2 File.open(dest, 'wb') {|f| f.write File.read(src) }
135 yuya 1.1 File.chmod File.stat(src).mode, dest
136     File.unlink src
137     end
138     end
139    
140 yuya 1.2 def install(from, dest, mode, prefix = nil)
141 yuya 1.1 $stderr.puts "install #{from} #{dest}" if verbose?
142     return if no_harm?
143    
144     realdest = prefix + dest if prefix
145 yuya 1.2 realdest += '/' + File.basename(from) if File.dir?(realdest)
146     str = File.read(from)
147 yuya 1.1 if diff?(str, realdest)
148     verbose_off {
149     rm_f realdest if File.exist?(realdest)
150     }
151     File.open(realdest, 'wb') {|f| f.write str }
152     File.chmod mode, realdest
153    
154 yuya 1.2 File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| f.puts dest }
155 yuya 1.1 end
156     end
157    
158 yuya 1.2 def diff?(orig, targ)
159 yuya 1.1 return true unless File.exist?(targ)
160 yuya 1.2 orig != File.read(targ)
161 yuya 1.1 end
162    
163 yuya 1.2 def command(str)
164 yuya 1.1 $stderr.puts str if verbose?
165     system str or raise RuntimeError, "'system #{str}' failed"
166     end
167    
168 yuya 1.2 def ruby(str)
169 yuya 1.1 command config('ruby-prog') + ' ' + str
170     end
171    
172 yuya 1.2 def make(task = '')
173 yuya 1.1 command config('make-prog') + ' ' + task
174     end
175    
176 yuya 1.2 def extdir?(dir)
177 yuya 1.1 File.exist?(dir + '/MANIFEST')
178     end
179    
180 yuya 1.2 def all_files_in(dirname)
181 yuya 1.1 Dir.open(dirname) {|d|
182 yuya 1.2 return d.select {|ent| File.file?("#{dirname}/#{ent}") }
183 yuya 1.1 }
184     end
185    
186     REJECT_DIRS = %w(
187     CVS SCCS RCS CVS.adm
188     )
189    
190 yuya 1.2 def all_dirs_in(dirname)
191 yuya 1.1 Dir.open(dirname) {|d|
192 yuya 1.2 return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
193 yuya 1.1 }
194     end
195    
196 yuya 1.2 end
197    
198    
199     class File
200    
201     def File.dir?(path)
202     # for corrupted windows stat()
203     File.directory?((path[-1,1] == '/') ? path : path + '/')
204 yuya 1.1 end
205    
206     end
207     #
208     # config.rb
209     #
210    
211 yuya 1.2 if idx = ARGV.index(/\A--rbconfig=/)
212     require ARGV.delete_at(idx).split(/=/, 2)[1]
213 yuya 1.1 else
214     require 'rbconfig'
215     end
216    
217     class ConfigTable
218    
219     c = ::Config::CONFIG
220    
221     rubypath = c['bindir'] + '/' + c['ruby_install_name']
222    
223     major = c['MAJOR'].to_i
224     minor = c['MINOR'].to_i
225     teeny = c['TEENY'].to_i
226     version = "#{major}.#{minor}"
227    
228     # ruby ver. >= 1.4.4?
229     newpath_p = ((major >= 2) or
230     ((major == 1) and
231     ((minor >= 5) or
232     ((minor == 4) and (teeny >= 4)))))
233    
234     subprefix = lambda {|path|
235 yuya 1.2 path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
236 yuya 1.1 }
237    
238     if c['rubylibdir']
239     # V < 1.6.3
240     stdruby = subprefix.call(c['rubylibdir'])
241     siteruby = subprefix.call(c['sitedir'])
242     versite = subprefix.call(c['sitelibdir'])
243     sodir = subprefix.call(c['sitearchdir'])
244     elsif newpath_p
245     # 1.4.4 <= V <= 1.6.3
246     stdruby = "$prefix/lib/ruby/#{version}"
247     siteruby = subprefix.call(c['sitedir'])
248     versite = siteruby + '/' + version
249     sodir = "$site-ruby/#{c['arch']}"
250     else
251     # V < 1.4.4
252     stdruby = "$prefix/lib/ruby/#{version}"
253     siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
254     versite = siteruby
255     sodir = "$site-ruby/#{c['arch']}"
256     end
257    
258     common_descripters = [
259     [ 'prefix', [ c['prefix'],
260     'path',
261     'path prefix of target environment' ] ],
262     [ 'std-ruby', [ stdruby,
263     'path',
264     'the directory for standard ruby libraries' ] ],
265     [ 'site-ruby-common', [ siteruby,
266     'path',
267     'the directory for version-independent non-standard ruby libraries' ] ],
268     [ 'site-ruby', [ versite,
269     'path',
270     'the directory for non-standard ruby libraries' ] ],
271     [ 'bin-dir', [ '$prefix/bin',
272     'path',
273     'the directory for commands' ] ],
274     [ 'rb-dir', [ '$site-ruby',
275     'path',
276     'the directory for ruby scripts' ] ],
277     [ 'so-dir', [ sodir,
278     'path',
279     'the directory for ruby extentions' ] ],
280     [ 'data-dir', [ '$prefix/share',
281     'path',
282     'the directory for shared data' ] ],
283     [ 'ruby-path', [ rubypath,
284     'path',
285     'path to set to #! line' ] ],
286     [ 'ruby-prog', [ rubypath,
287     'name',
288     'the ruby program using for installation' ] ],
289     [ 'make-prog', [ 'make',
290     'name',
291     'the make program to compile ruby extentions' ] ],
292     [ 'without-ext', [ 'no',
293     'yes/no',
294     'does not compile/install ruby extentions' ] ]
295     ]
296     multipackage_descripters = [
297     [ 'with', [ '',
298     'name,name...',
299     'package names that you want to install',
300     'ALL' ] ],
301     [ 'without', [ '',
302     'name,name...',
303     'package names that you do not want to install',
304     'NONE' ] ]
305     ]
306     if multipackage_install?
307     DESCRIPTER = common_descripters + multipackage_descripters
308     else
309     DESCRIPTER = common_descripters
310     end
311    
312     SAVE_FILE = 'config.save'
313    
314 yuya 1.2 def ConfigTable.each_name(&block)
315 yuya 1.1 keys().each(&block)
316     end
317    
318     def ConfigTable.keys
319     DESCRIPTER.map {|name, *dummy| name }
320     end
321    
322 yuya 1.2 def ConfigTable.each_definition(&block)
323 yuya 1.1 DESCRIPTER.each(&block)
324     end
325    
326 yuya 1.2 def ConfigTable.get_entry(name)
327 yuya 1.1 name, ent = DESCRIPTER.assoc(name)
328     ent
329     end
330    
331 yuya 1.2 def ConfigTable.get_entry!(name)
332 yuya 1.1 get_entry(name) or raise ArgumentError, "no such config: #{name}"
333     end
334    
335 yuya 1.2 def ConfigTable.add_entry(name, vals)
336 yuya 1.1 ConfigTable::DESCRIPTER.push [name,vals]
337     end
338    
339 yuya 1.2 def ConfigTable.remove_entry(name)
340 yuya 1.1 get_entry(name) or raise ArgumentError, "no such config: #{name}"
341     DESCRIPTER.delete_if {|n, arr| n == name }
342     end
343    
344 yuya 1.2 def ConfigTable.config_key?(name)
345 yuya 1.1 get_entry(name) ? true : false
346     end
347    
348 yuya 1.2 def ConfigTable.bool_config?(name)
349 yuya 1.1 ent = get_entry(name) or return false
350     ent[1] == 'yes/no'
351     end
352    
353 yuya 1.2 def ConfigTable.value_config?(name)
354 yuya 1.1 ent = get_entry(name) or return false
355     ent[1] != 'yes/no'
356     end
357    
358 yuya 1.2 def ConfigTable.path_config?(name)
359 yuya 1.1 ent = get_entry(name) or return false
360     ent[1] == 'path'
361     end
362    
363    
364     class << self
365     alias newobj new
366     end
367    
368     def ConfigTable.new
369     c = newobj()
370     c.initialize_from_table
371     c
372     end
373    
374     def ConfigTable.load
375     c = newobj()
376     c.initialize_from_file
377     c
378     end
379    
380     def initialize_from_table
381     @table = {}
382     DESCRIPTER.each do |k, (default, vname, desc, default2)|
383     @table[k] = default
384     end
385     end
386    
387     def initialize_from_file
388     raise InstallError, "#{File.basename $0} config first"\
389 yuya 1.2 unless File.file?(SAVE_FILE)
390 yuya 1.1 @table = {}
391     File.foreach(SAVE_FILE) do |line|
392     k, v = line.split(/=/, 2)
393     @table[k] = v.strip
394     end
395     end
396    
397     def save
398     File.open(SAVE_FILE, 'w') {|f|
399 yuya 1.2 @table.each do |k, v|
400     f.printf "%s=%s\n", k, v if v
401     end
402 yuya 1.1 }
403     end
404    
405 yuya 1.2 def []=(k, v)
406 yuya 1.1 raise InstallError, "unknown config option #{k}"\
407 yuya 1.2 unless ConfigTable.config_key?(k)
408     @table[k] = v
409 yuya 1.1 end
410    
411 yuya 1.2 def [](key)
412 yuya 1.1 return nil unless @table[key]
413     @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
414     end
415    
416 yuya 1.2 def set_raw(key, val)
417 yuya 1.1 @table[key] = val
418     end
419    
420 yuya 1.2 def get_raw(key)
421 yuya 1.1 @table[key]
422     end
423    
424     end
425    
426    
427     module MetaConfigAPI
428    
429 yuya 1.2 def eval_file_ifexist(fname)
430     instance_eval File.read(fname), fname, 1 if File.file?(fname)
431 yuya 1.1 end
432    
433     def config_names
434     ConfigTable.keys
435     end
436    
437 yuya 1.2 def config?(name)
438 yuya 1.1 ConfigTable.config_key?(name)
439     end
440    
441 yuya 1.2 def bool_config?(name)
442 yuya 1.1 ConfigTable.bool_config?(name)
443     end
444    
445 yuya 1.2 def value_config?(name)
446 yuya 1.1 ConfigTable.value_config?(name)
447     end
448    
449 yuya 1.2 def path_config?(name)
450 yuya 1.1 ConfigTable.path_config?(name)
451     end
452    
453 yuya 1.2 def add_config(name, argname, default, desc)
454 yuya 1.1 ConfigTable.add_entry name,[default,argname,desc]
455     end
456    
457 yuya 1.2 def add_path_config(name, default, desc)
458 yuya 1.1 add_config name, 'path', default, desc
459     end
460    
461 yuya 1.2 def add_bool_config(name, default, desc)
462 yuya 1.1 add_config name, 'yes/no', default ? 'yes' : 'no', desc
463     end
464    
465 yuya 1.2 def set_config_default(name, default)
466 yuya 1.1 if bool_config?(name)
467     ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
468     else
469     ConfigTable.get_entry!(name)[0] = default
470     end
471     end
472    
473 yuya 1.2 def remove_config(name)
474 yuya 1.1 ent = ConfigTable.get_entry(name)
475     ConfigTable.remove_entry name
476     ent
477     end
478    
479     end
480     #
481     # base.rb
482     #
483    
484     require 'rbconfig'
485    
486    
487     class InstallError < StandardError; end
488    
489    
490     module HookUtils
491    
492 yuya 1.2 def run_hook(name)
493 yuya 1.1 try_run_hook "#{curr_srcdir()}/#{name}" or
494     try_run_hook "#{curr_srcdir()}/#{name}.rb"
495     end
496    
497 yuya 1.2 def try_run_hook(fname)
498     return false unless File.file?(fname)
499 yuya 1.1 begin
500 yuya 1.2 instance_eval File.read(fname), fname, 1
501 yuya 1.1 rescue
502     raise InstallError, "hook #{fname} failed:\n" + $!.message
503     end
504     true
505     end
506    
507     end
508    
509    
510     module HookScriptAPI
511    
512 yuya 1.2 def get_config(key)
513 yuya 1.1 @config[key]
514     end
515    
516     alias config get_config
517    
518 yuya 1.2 def set_config(key, val)
519 yuya 1.1 @config[key] = val
520     end
521    
522     #
523     # srcdir/objdir (works only in the package directory)
524     #
525    
526     #abstract srcdir_root
527     #abstract objdir_root
528     #abstract relpath
529    
530     def curr_srcdir
531     "#{srcdir_root()}/#{relpath()}"
532     end
533    
534     def curr_objdir
535     "#{objdir_root()}/#{relpath()}"
536     end
537    
538 yuya 1.2 def srcfile(path)
539 yuya 1.1 "#{curr_srcdir()}/#{path}"
540     end
541    
542 yuya 1.2 def srcexist?(path)
543     File.exist?(srcfile(path))
544 yuya 1.1 end
545    
546 yuya 1.2 def srcdirectory?(path)
547     File.dir?(srcfile(path))
548 yuya 1.1 end
549    
550 yuya 1.2 def srcfile?(path)
551     File.file? srcfile(path)
552 yuya 1.1 end
553    
554 yuya 1.2 def srcentries(path = '.')
555 yuya 1.1 Dir.open("#{curr_srcdir()}/#{path}") {|d|
556     return d.to_a - %w(. ..)
557     }
558     end
559    
560 yuya 1.2 def srcfiles(path = '.')
561 yuya 1.1 srcentries(path).select {|fname|
562 yuya 1.2 File.file?(File.join(curr_srcdir(), path, fname))
563 yuya 1.1 }
564     end
565    
566 yuya 1.2 def srcdirectories(path = '.')
567 yuya 1.1 srcentries(path).select {|fname|
568 yuya 1.2 File.dir?(File.join(curr_srcdir(), path, fname))
569 yuya 1.1 }
570     end
571    
572     end
573    
574    
575     class Installer
576    
577     FILETYPES = %w( bin lib ext data )
578    
579     include HookScriptAPI
580     include HookUtils
581     include FileOperations
582    
583 yuya 1.2 def initialize(config, opt, srcroot, objroot)
584 yuya 1.1 @config = config
585     @options = opt
586     @srcdir = File.expand_path(srcroot)
587     @objdir = File.expand_path(objroot)
588     @currdir = '.'
589     end
590    
591     def inspect
592     "#<#{self.class} #{File.basename(@srcdir)}>"
593     end
594    
595     #
596     # Hook Script API bases
597     #
598    
599     def srcdir_root
600     @srcdir
601     end
602    
603     def objdir_root
604     @objdir
605     end
606    
607     def relpath
608     @currdir
609     end
610    
611     #
612     # configs/options
613     #
614    
615     def no_harm?
616     @options['no-harm']
617     end
618    
619     def verbose?
620     @options['verbose']
621     end
622    
623     def verbose_off
624     begin
625     save, @options['verbose'] = @options['verbose'], false
626     yield
627     ensure
628     @options['verbose'] = save
629     end
630     end
631    
632     #
633     # TASK config
634     #
635    
636     def exec_config
637     exec_task_traverse 'config'
638     end
639    
640 yuya 1.2 def config_dir_bin(rel)
641 yuya 1.1 end
642    
643 yuya 1.2 def config_dir_lib(rel)
644 yuya 1.1 end
645    
646 yuya 1.2 def config_dir_ext(rel)
647 yuya 1.1 extconf if extdir?(curr_srcdir())
648     end
649    
650     def extconf
651     opt = @options['config-opt'].join(' ')
652     command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
653     end
654    
655 yuya 1.2 def config_dir_data(rel)
656 yuya 1.1 end
657    
658     #
659     # TASK setup
660     #
661    
662     def exec_setup
663     exec_task_traverse 'setup'
664     end
665    
666 yuya 1.2 def setup_dir_bin(rel)
667 yuya 1.1 all_files_in(curr_srcdir()).each do |fname|
668     adjust_shebang "#{curr_srcdir()}/#{fname}"
669     end
670     end
671    
672     # modify: #!/usr/bin/ruby
673     # modify: #! /usr/bin/ruby
674     # modify: #!ruby
675     # not modify: #!/usr/bin/env ruby
676     SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
677    
678 yuya 1.2 def adjust_shebang(path)
679 yuya 1.1 return if no_harm?
680    
681     tmpfile = File.basename(path) + '.tmp'
682     begin
683 yuya 1.2 File.open(path, 'rb') {|r|
684     File.open(tmpfile, 'wb') {|w|
685 yuya 1.1 first = r.gets
686 yuya 1.2 return unless SHEBANG_RE =~ first
687 yuya 1.1
688     $stderr.puts "adjusting shebang: #{File.basename path}" if verbose?
689     w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
690     w.write r.read
691     }
692     }
693     move_file tmpfile, File.basename(path)
694     ensure
695     File.unlink tmpfile if File.exist?(tmpfile)
696     end
697     end
698    
699 yuya 1.2 def setup_dir_lib(rel)
700 yuya 1.1 end
701    
702 yuya 1.2 def setup_dir_ext(rel)
703 yuya 1.1 make if extdir?(curr_srcdir())
704     end
705    
706 yuya 1.2 def setup_dir_data(rel)
707 yuya 1.1 end
708    
709     #
710     # TASK install
711     #
712    
713     def exec_install
714     exec_task_traverse 'install'
715     end
716    
717 yuya 1.2 def install_dir_bin(rel)
718 yuya 1.1 install_files collect_filenames_auto(), config('bin-dir') + '/' + rel, 0755
719     end
720    
721 yuya 1.2 def install_dir_lib(rel)
722 yuya 1.1 install_files ruby_scripts(), config('rb-dir') + '/' + rel, 0644
723     end
724    
725 yuya 1.2 def install_dir_ext(rel)
726 yuya 1.1 return unless extdir?(curr_srcdir())
727     install_files ruby_extentions('.'),
728     config('so-dir') + '/' + File.dirname(rel),
729     0555
730     end
731    
732 yuya 1.2 def install_dir_data(rel)
733 yuya 1.1 install_files collect_filenames_auto(), config('data-dir') + '/' + rel, 0644
734     end
735    
736 yuya 1.2 def install_files(list, dest, mode)
737 yuya 1.1 mkdir_p dest, @options['install-prefix']
738     list.each do |fname|
739     install fname, dest, mode, @options['install-prefix']
740     end
741     end
742    
743     def ruby_scripts
744 yuya 1.2 collect_filenames_auto().select {|n| /\.rb\z/ =~ n }
745 yuya 1.1 end
746    
747     # picked up many entries from cvs-1.11.1/src/ignore.c
748     reject_patterns = %w(
749     core RCSLOG tags TAGS .make.state
750 yuya 1.2 .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
751     *~ *.old *.bak *.BAK *.orig *.rej _$* *$
752 yuya 1.1
753     *.org *.in .*
754     )
755 yuya 1.2 mapping = {
756     '.' => '\.',
757     '$' => '\$',
758     '#' => '\#',
759 yuya 1.1 '*' => '.*'
760     }
761     REJECT_PATTERNS = Regexp.new('\A(?:' +
762     reject_patterns.map {|pat|
763 yuya 1.2 pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
764 yuya 1.1 }.join('|') +
765     ')\z')
766    
767     def collect_filenames_auto
768     mapdir((existfiles() - hookfiles()).reject {|fname|
769 yuya 1.2 REJECT_PATTERNS =~ fname
770 yuya 1.1 })
771     end
772    
773     def existfiles
774     all_files_in(curr_srcdir()) | all_files_in('.')
775     end
776    
777     def hookfiles
778     %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
779     %w( config setup install clean ).map {|t| sprintf(fmt, t) }
780     }.flatten
781     end
782    
783 yuya 1.2 def mapdir(filelist)
784 yuya 1.1 filelist.map {|fname|
785     if File.exist?(fname) # objdir
786     fname
787     else # srcdir
788     File.join(curr_srcdir(), fname)
789     end
790     }
791     end
792    
793 yuya 1.2 def ruby_extentions(dir)
794 yuya 1.1 _ruby_extentions(dir) or
795     raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
796     end
797    
798     DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
799    
800 yuya 1.2 def _ruby_extentions(dir)
801 yuya 1.1 Dir.open(dir) {|d|
802 yuya 1.2 return d.select {|fname| DLEXT =~ fname }
803 yuya 1.1 }
804     end
805    
806     #
807     # TASK clean
808     #
809    
810     def exec_clean
811     exec_task_traverse 'clean'
812     rm_f 'config.save'
813     rm_f 'InstalledFiles'
814     end
815    
816 yuya 1.2 def clean_dir_bin(rel)
817 yuya 1.1 end
818    
819 yuya 1.2 def clean_dir_lib(rel)
820 yuya 1.1 end
821    
822 yuya 1.2 def clean_dir_ext(rel)
823 yuya 1.1 return unless extdir?(curr_srcdir())
824 yuya 1.2 make 'clean' if File.file?('Makefile')
825 yuya 1.1 end
826    
827 yuya 1.2 def clean_dir_data(rel)
828 yuya 1.1 end
829    
830     #
831     # TASK distclean
832     #
833    
834     def exec_distclean
835     exec_task_traverse 'distclean'
836     rm_f 'config.save'
837     rm_f 'InstalledFiles'
838     end
839    
840 yuya 1.2 def distclean_dir_bin(rel)
841 yuya 1.1 end
842    
843 yuya 1.2 def distclean_dir_lib(rel)
844 yuya 1.1 end
845    
846 yuya 1.2 def distclean_dir_ext(rel)
847 yuya 1.1 return unless extdir?(curr_srcdir())
848 yuya 1.2 make 'distclean' if File.file?('Makefile')
849 yuya 1.1 end
850    
851     #
852     # lib
853     #
854    
855 yuya 1.2 def exec_task_traverse(task)
856     run_hook "pre-#{task}"
857 yuya 1.1 FILETYPES.each do |type|
858     if config('without-ext') == 'yes' and type == 'ext'
859     $stderr.puts 'skipping ext/* by user option' if verbose?
860     next
861     end
862 yuya 1.2 traverse task, type, "#{task}_dir_#{type}"
863 yuya 1.1 end
864 yuya 1.2 run_hook "post-#{task}"
865 yuya 1.1 end
866    
867 yuya 1.2 def traverse(task, rel, mid)
868 yuya 1.1 dive_into(rel) {
869 yuya 1.2 run_hook "pre-#{task}"
870 yuya 1.1 __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
871     all_dirs_in(curr_srcdir()).each do |d|
872 yuya 1.2 traverse task, "#{rel}/#{d}", mid
873 yuya 1.1 end
874 yuya 1.2 run_hook "post-#{task}"
875 yuya 1.1 }
876     end
877    
878 yuya 1.2 def dive_into(rel)
879     return unless File.dir?("#{@srcdir}/#{rel}")
880 yuya 1.1
881     dir = File.basename(rel)
882 yuya 1.2 Dir.mkdir dir unless File.dir?(dir)
883 yuya 1.1 prevdir = Dir.pwd
884     Dir.chdir dir
885     $stderr.puts '---> ' + rel if verbose?
886     @currdir = rel
887     yield
888     Dir.chdir prevdir
889     $stderr.puts '<--- ' + rel if verbose?
890     @currdir = File.dirname(rel)
891     end
892    
893     end
894     #
895     # toplevel.rb
896     #
897    
898     class ToplevelInstaller
899    
900 yuya 1.2 Version = '3.2.2'
901 yuya 1.1 Copyright = 'Copyright (c) 2000-2003 Minero Aoki'
902    
903     TASKS = [
904     [ 'config', 'saves your configurations' ],
905     [ 'show', 'shows current configuration' ],
906     [ 'setup', 'compiles ruby extentions and others' ],
907     [ 'install', 'installs files' ],
908     [ 'clean', "does `make clean' for each extention" ],
909     [ 'distclean',"does `make distclean' for each extention" ]
910     ]
911    
912     def ToplevelInstaller.invoke
913     instance().invoke
914     end
915    
916     @singleton = nil
917    
918     def ToplevelInstaller.instance
919     @singleton ||= new(File.dirname($0))
920     @singleton
921     end
922    
923     include MetaConfigAPI
924    
925 yuya 1.2 def initialize(ardir_root)
926 yuya 1.1 @config = nil
927     @options = { 'verbose' => true }
928     @ardir = File.expand_path(ardir_root)
929     end
930    
931     def inspect
932     "#<#{self.class} #{__id__()}>"
933     end
934    
935     def invoke
936     run_metaconfigs
937     task = parsearg_global()
938     @config = load_config(task)
939     __send__ "parsearg_#{task}"
940     init_installers
941     __send__ "exec_#{task}"
942     end
943    
944     def run_metaconfigs
945     eval_file_ifexist "#{@ardir}/metaconfig"
946     end
947    
948 yuya 1.2 def load_config(task)
949 yuya 1.1 case task
950     when 'config'
951     ConfigTable.new
952     when 'clean', 'distclean'
953     if File.exist?('config.save')
954     then ConfigTable.load
955     else ConfigTable.new
956     end
957     else
958     ConfigTable.load
959     end
960     end
961    
962     def init_installers
963     @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
964     end
965    
966     #
967     # Hook Script API bases
968     #
969    
970     def srcdir_root
971     @ardir
972     end
973    
974     def objdir_root
975     '.'
976     end
977    
978     def relpath
979     '.'
980     end
981    
982     #
983     # Option Parsing
984     #
985    
986     def parsearg_global
987     valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
988    
989     while arg = ARGV.shift
990     case arg
991     when /\A\w+\z/
992 yuya 1.2 raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
993 yuya 1.1 return arg
994    
995     when '-q', '--quiet'
996     @options['verbose'] = false
997    
998     when '--verbose'
999     @options['verbose'] = true
1000    
1001     when '-h', '--help'
1002     print_usage $stdout
1003     exit 0
1004    
1005     when '-v', '--version'
1006     puts "#{File.basename($0)} version #{Version}"
1007     exit 0
1008    
1009     when '--copyright'
1010     puts Copyright
1011     exit 0
1012    
1013     else
1014     raise InstallError, "unknown global option '#{arg}'"
1015     end
1016     end
1017    
1018     raise InstallError, <<EOS
1019     No task or global option given.
1020     Typical installation procedure is:
1021     $ ruby #{File.basename($0)} config
1022     $ ruby #{File.basename($0)} setup
1023     # ruby #{File.basename($0)} install (may require root privilege)
1024     EOS
1025     end
1026    
1027    
1028     def parsearg_no_options
1029     raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
1030     unless ARGV.empty?
1031     end
1032    
1033     alias parsearg_show parsearg_no_options
1034     alias parsearg_setup parsearg_no_options
1035     alias parsearg_clean parsearg_no_options
1036     alias parsearg_distclean parsearg_no_options
1037    
1038     def parsearg_config
1039     re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
1040     @options['config-opt'] = []
1041    
1042     while i = ARGV.shift
1043 yuya 1.2 if /\A--?\z/ =~ i
1044 yuya 1.1 @options['config-opt'] = ARGV.dup
1045     break
1046     end
1047     m = re.match(i) or raise InstallError, "config: unknown option #{i}"
1048     name, value = m.to_a[1,2]
1049     if value
1050     if ConfigTable.bool_config?(name)
1051     raise InstallError, "config: --#{name} allows only yes/no for argument"\
1052 yuya 1.2 unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
1053     value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
1054 yuya 1.1 end
1055     else
1056     raise InstallError, "config: --#{name} requires argument"\
1057     unless ConfigTable.bool_config?(name)
1058     value = 'yes'
1059     end
1060     @config[name] = value
1061     end
1062     end
1063    
1064     def parsearg_install
1065     @options['no-harm'] = false
1066     @options['install-prefix'] = ''
1067     while a = ARGV.shift
1068     case a
1069     when /\A--no-harm\z/
1070     @options['no-harm'] = true
1071     when /\A--prefix=(.*)\z/
1072     path = $1
1073     path = File.expand_path(path) unless path[0,1] == '/'
1074     @options['install-prefix'] = path
1075     else
1076     raise InstallError, "install: unknown option #{a}"
1077     end
1078     end
1079     end
1080    
1081 yuya 1.2 def print_usage(out)
1082 yuya 1.1 out.puts 'Typical Installation Procedure:'
1083     out.puts " $ ruby #{File.basename $0} config"
1084     out.puts " $ ruby #{File.basename $0} setup"
1085     out.puts " # ruby #{File.basename $0} install (may require root privilege)"
1086     out.puts
1087     out.puts 'Detailed Usage:'
1088     out.puts " ruby #{File.basename $0} <global option>"
1089     out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
1090    
1091     fmt = " %-20s %s\n"
1092     out.puts
1093     out.puts 'Global options:'
1094     out.printf fmt, '-q,--quiet', 'suppress message outputs'
1095     out.printf fmt, ' --verbose', 'output messages verbosely'
1096     out.printf fmt, '-h,--help', 'print this message'
1097     out.printf fmt, '-v,--version', 'print version and quit'
1098     out.printf fmt, ' --copyright', 'print copyright and quit'
1099    
1100     out.puts
1101     out.puts 'Tasks:'
1102     TASKS.each do |name, desc|
1103     out.printf " %-10s %s\n", name, desc
1104     end
1105    
1106     out.puts
1107     out.puts 'Options for config:'
1108     ConfigTable.each_definition do |name, (default, arg, desc, default2)|
1109     out.printf " %-20s %s [%s]\n",
1110     '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
1111     desc,
1112     default2 || default
1113     end
1114     out.printf " %-20s %s [%s]\n",
1115     '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
1116    
1117     out.puts
1118     out.puts 'Options for install:'
1119     out.printf " %-20s %s [%s]\n",
1120     '--no-harm', 'only display what to do if given', 'off'
1121     out.printf " %-20s %s [%s]\n",
1122     '--prefix', 'install path prefix', '$prefix'
1123    
1124     out.puts
1125     end
1126    
1127     #
1128     # Task Handlers
1129     #
1130    
1131     def exec_config
1132     @installer.exec_config
1133 yuya 1.2 @config.save # must be final
1134 yuya 1.1 end
1135    
1136     def exec_setup
1137     @installer.exec_setup
1138     end
1139    
1140     def exec_install
1141     @installer.exec_install
1142     end
1143    
1144     def exec_show
1145     ConfigTable.each_name do |k|
1146     v = @config.get_raw(k)
1147     if not v or v.empty?
1148     v = '(not specified)'
1149     end
1150     printf "%-10s %s\n", k, v
1151     end
1152     end
1153    
1154     def exec_clean
1155     @installer.exec_clean
1156     end
1157    
1158     def exec_distclean
1159     @installer.exec_distclean
1160     end
1161    
1162     end
1163    
1164    
1165     class ToplevelInstallerMulti < ToplevelInstaller
1166    
1167     include HookUtils
1168     include HookScriptAPI
1169     include FileOperations
1170    
1171 yuya 1.2 def initialize(ardir)
1172 yuya 1.1 super
1173     @packages = all_dirs_in("#{@ardir}/packages")
1174     raise 'no package exists' if @packages.empty?
1175     end
1176    
1177     def run_metaconfigs
1178     eval_file_ifexist "#{@ardir}/metaconfig"
1179     @packages.each do |name|
1180     eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
1181     end
1182     end
1183    
1184     def init_installers
1185     @installers = {}
1186     @packages.each do |pack|
1187     @installers[pack] = Installer.new(@config, @options,
1188     "#{@ardir}/packages/#{pack}",
1189     "packages/#{pack}")
1190     end
1191    
1192     with = extract_selection(config('with'))
1193     without = extract_selection(config('without'))
1194     @selected = @installers.keys.select {|name|
1195     (with.empty? or with.include?(name)) \
1196     and not without.include?(name)
1197     }
1198     end
1199    
1200 yuya 1.2 def extract_selection(list)
1201 yuya 1.1 a = list.split(/,/)
1202     a.each do |name|
1203     raise InstallError, "no such package: #{name}" \
1204     unless @installers.key?(name)
1205     end
1206     a
1207     end
1208    
1209 yuya 1.2 def print_usage(f)
1210 yuya 1.1 super
1211     f.puts 'Inluded packages:'
1212     f.puts ' ' + @packages.sort.join(' ')
1213     f.puts
1214     end
1215    
1216     #
1217     # multi-package metaconfig API
1218     #
1219    
1220     attr_reader :packages
1221    
1222 yuya 1.2 def declare_packages(list)
1223 yuya 1.1 raise 'package list is empty' if list.empty?
1224     list.each do |name|
1225     raise "directory packages/#{name} does not exist"\
1226 yuya 1.2 unless File.dir?("#{@ardir}/packages/#{name}")
1227 yuya 1.1 end
1228     @packages = list
1229     end
1230    
1231     #
1232     # Task Handlers
1233     #
1234    
1235     def exec_config
1236     run_hook 'pre-config'
1237     each_selected_installers {|inst| inst.exec_config }
1238     run_hook 'post-config'
1239 yuya 1.2 @config.save # must be final
1240 yuya 1.1 end
1241    
1242     def exec_setup
1243     run_hook 'pre-setup'
1244     each_selected_installers {|inst| inst.exec_setup }
1245     run_hook 'post-setup'
1246     end
1247    
1248     def exec_install
1249     run_hook 'pre-install'
1250     each_selected_installers {|inst| inst.exec_install }
1251     run_hook 'post-install'
1252     end
1253    
1254     def exec_clean
1255     rm_f 'config.save'
1256     run_hook 'pre-clean'
1257     each_selected_installers {|inst| inst.exec_clean }
1258     run_hook 'post-clean'
1259     end
1260    
1261     def exec_distclean
1262     rm_f 'config.save'
1263     run_hook 'pre-distclean'
1264     each_selected_installers {|inst| inst.exec_distclean }
1265     run_hook 'post-distclean'
1266     end
1267    
1268     #
1269     # lib
1270     #
1271    
1272     def each_selected_installers
1273 yuya 1.2 Dir.mkdir 'packages' unless File.dir?('packages')
1274 yuya 1.1 @selected.each do |pack|
1275     $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
1276 yuya 1.2 Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1277 yuya 1.1 Dir.chdir "packages/#{pack}"
1278     yield @installers[pack]
1279     Dir.chdir '../..'
1280     end
1281     end
1282    
1283     def verbose?
1284     @options['verbose']
1285     end
1286    
1287     def no_harm?
1288     @options['no-harm']
1289     end
1290    
1291     end
1292    
1293     if $0 == __FILE__
1294     begin
1295     if multipackage_install?
1296     ToplevelInstallerMulti.invoke
1297     else
1298     ToplevelInstaller.invoke
1299     end
1300     rescue
1301     raise if $DEBUG
1302     $stderr.puts $!.message
1303     $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1304     exit 1
1305     end
1306     end

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