2 # This file is automatically generated. DO NOT MODIFY!
6 # Copyright (c) 2000-2003 Minero Aoki <aamine@loveruby.net>
8 # 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.
16 methods = instance_methods()
18 unless methods.include?('map')
22 unless methods.include?('select')
26 unless methods.include?('reject')
30 result.push i unless yield(i)
36 unless methods.include?('inject')
39 result = yield(result, i)
45 unless methods.include?('any?')
48 return true if yield(i)
55 def File.read_all( fname )
56 File.open(fname, 'rb') {|f| return f.read }
59 def File.write( fname, str )
60 File.open(fname, 'wb') {|f| f.write str }
66 if i = ARGV.index(/\A--rbconfig=/)
79 rubypath = c['bindir'] + '/' + c['ruby_install_name']
81 major = c['MAJOR'].to_i
82 minor = c['MINOR'].to_i
83 teeny = c['TEENY'].to_i
84 version = "#{major}.#{minor}"
87 newpath_p = ((major >= 2) or
90 ((minor == 4) and (teeny >= 4)))))
92 re = Regexp.new('\A' + Regexp.quote(c['prefix']))
93 subprefix = lambda {|path|
94 re === path and path.sub(re, '$prefix')
99 stdruby = subprefix.call(c['rubylibdir'])
100 siteruby = subprefix.call(c['sitedir'])
101 versite = subprefix.call(c['sitelibdir'])
102 sodir = subprefix.call(c['sitearchdir'])
104 # 1.4.4 <= V <= 1.6.3
105 stdruby = "$prefix/lib/ruby/#{version}"
106 siteruby = subprefix.call(c['sitedir'])
107 versite = siteruby + '/' + version
108 sodir = "$site-ruby/#{c['arch']}"
111 stdruby = "$prefix/lib/ruby/#{version}"
112 siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
114 sodir = "$site-ruby/#{c['arch']}"
118 [ 'prefix', [ c['prefix'],
120 'path prefix of target environment' ] ],
121 [ 'std-ruby', [ stdruby,
123 'the directory for standard ruby libraries' ] ],
124 [ 'site-ruby-common', [ siteruby,
126 'the directory for version-independent non-standard ruby libraries' ] ],
127 [ 'site-ruby', [ versite,
129 'the directory for non-standard ruby libraries' ] ],
130 [ 'bin-dir', [ '$prefix/bin',
132 'the directory for commands' ] ],
133 [ 'rb-dir', [ '$site-ruby',
135 'the directory for ruby scripts' ] ],
138 'the directory for ruby extentions' ] ],
139 [ 'data-dir', [ '$prefix/share',
141 'the directory for shared data' ] ],
142 [ 'ruby-path', [ rubypath,
144 'path to set to #! line' ] ],
145 [ 'ruby-prog', [ rubypath,
147 'the ruby program using for installation' ] ],
148 [ 'make-prog', [ 'make',
150 'the make program to compile ruby extentions' ] ],
151 [ 'without-ext', [ 'no',
153 'does not compile/install ruby extentions' ] ]
156 SAVE_FILE = 'config.save'
158 def ConfigTable.each_name( &block )
163 DESCRIPTER.map {|k,*dummy| k }
166 def ConfigTable.each_definition( &block )
167 DESCRIPTER.each(&block)
170 def ConfigTable.get_entry( name )
171 name, ent = DESCRIPTER.assoc(name)
175 def ConfigTable.get_entry!( name )
176 get_entry(name) or raise ArgumentError, "no such config: #{name}"
179 def ConfigTable.add_entry( name, vals )
180 ConfigTable::DESCRIPTER.push [name,vals]
183 def ConfigTable.remove_entry( name )
184 get_entry name or raise ArgumentError, "no such config: #{name}"
185 DESCRIPTER.delete_if {|n,arr| n == name }
188 def ConfigTable.config_key?( name )
189 get_entry(name) ? true : false
192 def ConfigTable.bool_config?( name )
193 ent = get_entry(name) or return false
197 def ConfigTable.value_config?( name )
198 ent = get_entry(name) or return false
202 def ConfigTable.path_config?( name )
203 ent = get_entry(name) or return false
219 raise InstallError, "#{File.basename $0} config first"\
220 unless FileTest.file?(SAVE_FILE)
221 File.foreach(SAVE_FILE) do |line|
222 k, v = line.split(/=/, 2)
236 DESCRIPTER.each do |k, (default, vname, desc, default2)|
243 File.open(SAVE_FILE, 'w') {|f|
244 @table.each do |k, v|
245 f.printf "%s=%s\n", k, v if v
251 ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}"
252 if ConfigTable.path_config? k
253 @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v
260 @table[key] or return nil
261 @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
264 def set_raw( key, val )
277 def eval_file_ifexist( fname )
278 instance_eval File.read_all(fname), fname, 1 if FileTest.file?(fname)
286 ConfigTable.config_key? name
289 def bool_config?( name )
290 ConfigTable.bool_config? name
293 def value_config?( name )
294 ConfigTable.value_config? name
297 def path_config?( name )
298 ConfigTable.path_config? name
301 def add_config( name, argname, default, desc )
302 ConfigTable.add_entry name,[default,argname,desc]
305 def add_path_config( name, default, desc )
306 add_config name, 'path', default, desc
309 def add_bool_config( name, default, desc )
310 add_config name, 'yes/no', default ? 'yes' : 'no', desc
313 def set_config_default( name, default )
315 ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no'
317 ConfigTable.get_entry!(name)[0] = default
321 def remove_config( name )
322 ent = ConfigTable.get_entry(name)
323 ConfigTable.remove_entry name
332 module FileOperations
334 def mkdir_p( dname, prefix = nil )
335 dname = prefix + dname if prefix
336 $stderr.puts "mkdir -p #{dname}" if verbose?
339 # does not check '/'... it's too abnormal case
340 dirs = dname.split(%r<(?=/)>)
341 if /\A[a-z]:\z/i === dirs[0]
343 dirs[0] = disk + dirs[0]
345 dirs.each_index do |idx|
346 path = dirs[0..idx].join('')
347 Dir.mkdir path unless dir? path
352 $stderr.puts "rm -f #{fname}" if verbose?
355 if File.exist? fname or File.symlink? fname
356 File.chmod 0777, fname
362 $stderr.puts "rm -rf #{dn}" if verbose?
366 Dir.foreach('.') do |fn|
388 File.write dest, File.read_all(src)
389 File.chmod File.stat(src).mode, dest
394 def install( from, dest, mode, prefix = nil )
395 $stderr.puts "install #{from} #{dest}" if verbose?
398 realdest = prefix + dest if prefix
400 realdest += '/' + File.basename(from)
402 str = File.read_all(from)
403 if diff? str, realdest
405 rm_f realdest if File.exist? realdest
407 File.write realdest, str
408 File.chmod mode, realdest
410 File.open(objdir + '/InstalledFiles', 'a') {|f| f.puts realdest }
414 def diff?( orig, targ )
415 return true unless File.exist? targ
416 orig != File.read_all(targ)
420 $stderr.puts str if verbose?
421 system str or raise RuntimeError, "'system #{str}' failed"
425 command config('ruby-prog') + ' ' + str
429 # for corrupted windows stat()
430 File.directory?((dname[-1,1] == '/') ? dname : dname + '/')
433 def all_files_in( dname )
435 return d.select {|n| FileTest.file? "#{dname}/#{n}" }
443 def all_dirs_in( dname )
445 return d.select {|n| dir? "#{dname}/#{n}" } - %w(. ..) - REJECT_DIRS
454 class InstallError < StandardError; end
460 Copyright = 'Copyright (c) 2000-2003 Minero Aoki'
465 def self.declare_toplevel_installer( inst )
466 raise ArgumentError, 'two toplevel installers declared' if @toplevel
470 def self.toplevel_installer
475 FILETYPES = %w( bin lib ext data )
477 include FileOperations
479 def initialize( config, opt, srcroot, objroot )
482 @srcdir = File.expand_path(srcroot)
483 @objdir = File.expand_path(objroot)
488 "#<#{self.class} #{__id__}>"
495 def get_config( key )
499 alias config get_config
501 def set_config( key, val )
514 save, @options['verbose'] = @options['verbose'], false
516 @options['verbose'] = save
524 alias srcdir_root srcdir
525 alias package_root srcdir
528 "#{@srcdir}/#{@currdir}"
532 alias objdir_root objdir
535 "#{@objdir}/#{@currdir}"
539 curr_srcdir + '/' + path
542 def srcexist?( path )
543 File.exist? srcfile(path)
546 def srcdirectory?( path )
551 FileTest.file? srcfile(path)
554 def srcentries( path = '.' )
555 Dir.open(curr_srcdir + '/' + path) {|d|
556 return d.to_a - %w(. ..) - hookfilenames
560 def srcfiles( path = '.' )
561 srcentries(path).select {|fname|
562 FileTest.file? File.join(curr_srcdir, path, fname)
566 def srcdirectories( path = '.' )
567 srcentries(path).select {|fname|
568 dir? File.join(curr_srcdir, path, fname)
573 return unless dir?("#{@srcdir}/#{rel}")
575 dir = File.basename(rel)
576 Dir.mkdir dir unless dir?(dir)
579 $stderr.puts '---> ' + rel if verbose?
583 $stderr.puts '<--- ' + rel if verbose?
584 @currdir = File.dirname(rel)
592 exec_task_traverse 'config'
595 def config_dir_bin( rel )
598 def config_dir_lib( rel )
601 def config_dir_ext( rel )
602 extconf if extdir? curr_srcdir
606 opt = @options['config-opt'].join(' ')
607 command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}"
610 def config_dir_data( rel )
618 exec_task_traverse 'setup'
621 def setup_dir_bin( relpath )
622 all_files_in(curr_srcdir()).each do |fname|
623 add_rubypath "#{curr_srcdir}/#{fname}"
627 SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
629 def add_rubypath( path )
630 $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose?
633 tmpfile = File.basename(path) + '.tmp'
636 File.open(tmpfile, 'w') {|w|
638 return unless SHEBANG_RE === first # reject '/usr/bin/env ruby'
640 w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
643 mv tmpfile, File.basename(path)
645 rm_f tmpfile if File.exist? tmpfile
649 def setup_dir_lib( relpath )
652 def setup_dir_ext( relpath )
653 make if extdir?(curr_srcdir)
656 def setup_dir_data( relpath )
664 exec_task_traverse 'install'
667 def install_dir_bin( rel )
668 install_files target_filenames(), config('bin-dir') + '/' + rel, 0755
671 def install_dir_lib( rel )
672 install_files target_filenames(), config('rb-dir') + '/' + rel, 0644
675 def install_dir_ext( rel )
676 install_dir_ext_main File.dirname(rel) if extdir?(curr_srcdir)
679 def install_dir_ext_main( rel )
680 install_files allext('.'), config('so-dir') + '/' + rel, 0555
683 def install_dir_data( rel )
684 install_files target_filenames(), config('data-dir') + '/' + rel, 0644
687 def install_files( list, dest, mode )
688 mkdir_p dest, @options['install-prefix']
690 install fname, dest, mode, @options['install-prefix']
695 if FileTest.file? "#{curr_srcdir()}/MANIFEST"
696 mapdir(target_filenames_MANIFEST())
698 mapdir(target_filenames_AUTO())
702 def mapdir( filelist )
703 filelist.map {|fname|
704 if File.exist? fname # current objdir == '.'
707 File.join(curr_srcdir(), fname)
712 def target_filenames_MANIFEST
713 File.read_all("#{curr_srcdir()}/MANIFEST").split
716 # picked up many entries from cvs-1.11.1/src/ignore.c
717 REJECT_PATTERNS = %w(
718 core RCSLOG tags TAGS .make.state
719 .nse_depinfo #* .#* cvslog.* ,* .del-* *.a *.olb *.o *.obj
720 *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$
724 Regexp.compile('\A' + pattern.gsub(/[\.\$]/) {|s| '\\' + s }.gsub(/\*/, '.*') + '\z')
727 def target_filenames_AUTO
728 (existfiles() - hookfiles()).reject {|fname|
729 REJECT_PATTERNS.any? {|re| re === fname }
734 all_files_in(curr_srcdir()) | all_files_in(curr_objdir())
738 %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
739 %w( config setup install clean ).map {|t| sprintf(fmt, t) }
744 _allext(dir) or raise InstallError,
745 "no extention exists: Have you done 'ruby #{$0} setup' ?"
748 DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
752 return d.select {|fname| DLEXT === fname }
761 exec_task_traverse 'clean'
763 rm_f 'InstalledFiles'
766 def clean_dir_bin( rel )
769 def clean_dir_lib( rel )
772 def clean_dir_ext( rel )
773 make 'clean' if FileTest.file?('Makefile')
776 def clean_dir_data( rel )
784 exec_task_traverse 'distclean'
786 rm_f 'InstalledFiles'
789 def distclean_dir_bin( rel )
792 def distclean_dir_lib( rel )
795 def distclean_dir_ext( rel )
796 make 'distclean' if FileTest.file?('Makefile')
803 def make( task = '' )
804 command config('make-prog') + ' ' + task
807 def exec_task_traverse( task )
808 run_hook 'pre-' + task
809 FILETYPES.each do |type|
810 if config('without-ext') == 'yes' and type == 'ext'
811 $stderr.puts 'skipping ext/* by user option' if verbose?
814 traverse task, type, task + '_dir_' + type
816 run_hook 'post-' + task
819 def traverse( task, rel, mid )
821 run_hook 'pre-' + task
822 __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
823 all_dirs_in(curr_srcdir()).each do |d|
824 traverse task, rel + '/' + d, mid
826 run_hook 'post-' + task
831 try_run_hook curr_srcdir + '/' + name or
832 try_run_hook curr_srcdir + '/' + name + '.rb'
835 def try_run_hook( fname )
836 return false unless FileTest.file?(fname)
840 env.instance_eval File.read_all(fname), fname, 1
842 raise InstallError, "hook #{fname} failed:\n" + $!.message
848 File.exist? dir + '/MANIFEST'
854 ### begin toplevel.rb
856 class ToplevelInstaller < Installer
859 new(File.dirname($0)).invoke
864 [ 'config', 'saves your configurations' ],
865 [ 'show', 'shows current configuration' ],
866 [ 'setup', 'compiles extention or else' ],
867 [ 'install', 'installs files' ],
868 [ 'clean', "does `make clean' for each extention" ],
869 [ 'distclean',"does `make distclean' for each extention" ]
873 def initialize( root )
874 super nil, {'verbose' => true}, root, '.'
875 Installer.declare_toplevel_installer self
882 case task = parsearg_global()
884 @config = ConfigTable.new
886 @config = ConfigTable.load
893 include MetaConfigAPI
896 eval_file_ifexist "#{srcdir_root()}/metaconfig"
909 $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose?
911 __send__ 'exec_' + task
913 $stderr.printf "%s failed\n", task
916 $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose?
920 # processing arguments
924 task_re = /\A(?:#{TASKS.map {|i| i[0] }.join '|'})\z/
926 while arg = ARGV.shift
929 task_re === arg or raise InstallError, "wrong task: #{arg}"
933 @options['verbose'] = false
936 @options['verbose'] = true
942 when '-v', '--version'
943 puts "#{File.basename $0} version #{Version}"
951 raise InstallError, "unknown global option '#{arg}'"
955 raise InstallError, "No task or global option given.
956 Typical installation procedure is:
957 $ ruby #{File.basename $0} config
958 $ ruby #{File.basename $0} setup
959 # ruby #{File.basename $0} install (may require root privilege)
964 def parsearg_TASK( task )
965 mid = "parsearg_#{task}"
966 if respond_to? mid, true
970 raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"
975 re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
976 @options['config-opt'] = []
980 @options['config-opt'] = ARGV.dup
983 m = re.match(i) or raise InstallError, "config: unknown option #{i}"
984 name, value = m.to_a[1,2]
986 if ConfigTable.bool_config?(name)
987 /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument"
988 value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no'
991 ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument"
994 @config[name] = value
999 @options['no-harm'] = false
1000 @options['install-prefix'] = ''
1001 while a = ARGV.shift
1003 when /\A--no-harm\z/
1004 @options['no-harm'] = true
1005 when /\A--prefix=(.*)\z/
1007 path = File.expand_path(path) unless path[0,1] == '/'
1008 @options['install-prefix'] = path
1010 raise InstallError, "install: unknown option #{a}"
1016 def print_usage( out )
1017 out.puts 'Typical Installation Procedure:'
1018 out.puts " $ ruby #{File.basename $0} config"
1019 out.puts " $ ruby #{File.basename $0} setup"
1020 out.puts " # ruby #{File.basename $0} install (may require root privilege)"
1022 out.puts 'Detailed Usage:'
1023 out.puts " ruby #{File.basename $0} <global option>"
1024 out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
1028 out.puts 'Global options:'
1029 out.printf fmt, '-q,--quiet', 'suppress message outputs'
1030 out.printf fmt, ' --verbose', 'output messages verbosely'
1031 out.printf fmt, '-h,--help', 'print this message'
1032 out.printf fmt, '-v,--version', 'print version and quit'
1033 out.printf fmt, ' --copyright', 'print copyright and quit'
1037 TASKS.each do |name, desc|
1038 out.printf " %-10s %s\n", name, desc
1042 out.puts 'Options for config:'
1043 ConfigTable.each_definition do |name, (default, arg, desc, default2)|
1044 out.printf " %-20s %s [%s]\n",
1045 '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
1049 out.printf " %-20s %s [%s]\n",
1050 '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
1053 out.puts 'Options for install:'
1054 out.printf " %-20s %s [%s]\n",
1055 '--no-harm', 'only display what to do if given', 'off'
1056 out.printf " %-20s %s [%s]\n",
1057 '--prefix', 'install path prefix', '$prefix'
1076 ConfigTable.each_name do |k|
1077 v = @config.get_raw(k)
1078 if not v or v.empty?
1079 v = '(not specified)'
1081 printf "%-10s %s\n", k, v
1091 ToplevelInstaller.invoke
1094 $stderr.puts $!.message
1095 $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."