mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 e72ca2e044
			
		
	
	
		e72ca2e044
		
	
	
	
	
		
			
			* tool/rbinstall.rb (Gem::Specification.last_date): skip if failed to get info from VCS, for example, in the case circumstance sharing working directory with another machine and run vcs tools cannot work. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43624 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			795 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Ruby
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			795 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Ruby
		
	
	
		
			Executable file
		
	
	
	
	
| #!./miniruby
 | |
| 
 | |
| begin
 | |
|   load "./rbconfig.rb"
 | |
| rescue LoadError
 | |
|   CONFIG = Hash.new {""}
 | |
| else
 | |
|   include RbConfig
 | |
|   $".unshift File.expand_path("./rbconfig.rb")
 | |
| end
 | |
| 
 | |
| srcdir = File.expand_path('../..', __FILE__)
 | |
| unless defined?(CROSS_COMPILING) and CROSS_COMPILING
 | |
|   $:.replace([srcdir+"/lib", Dir.pwd])
 | |
| end
 | |
| require 'fileutils'
 | |
| require 'shellwords'
 | |
| require 'optparse'
 | |
| require 'optparse/shellwords'
 | |
| require 'ostruct'
 | |
| require 'rubygems'
 | |
| require_relative 'vcs'
 | |
| 
 | |
| STDOUT.sync = true
 | |
| File.umask(0)
 | |
| 
 | |
| begin
 | |
|   $vcs = VCS.detect(File.expand_path('../..', __FILE__))
 | |
| rescue VCS::NotFoundError
 | |
|   $vcs = nil
 | |
| end
 | |
| 
 | |
| def parse_args(argv = ARGV)
 | |
|   $mantype = 'doc'
 | |
|   $destdir = nil
 | |
|   $extout = nil
 | |
|   $make = 'make'
 | |
|   $mflags = []
 | |
|   $install = []
 | |
|   $installed_list = nil
 | |
|   $dryrun = false
 | |
|   $rdocdir = nil
 | |
|   $data_mode = 0644
 | |
|   $prog_mode = 0755
 | |
|   $dir_mode = nil
 | |
|   $script_mode = nil
 | |
|   $strip = false
 | |
|   $cmdtype = (if File::ALT_SEPARATOR == '\\'
 | |
|                 File.exist?("rubystub.exe") ? 'exe' : 'bat'
 | |
|               end)
 | |
|   mflags = []
 | |
|   opt = OptionParser.new
 | |
|   opt.on('-n', '--dry-run') {$dryrun = true}
 | |
|   opt.on('--dest-dir=DIR') {|dir| $destdir = dir}
 | |
|   opt.on('--extout=DIR') {|dir| $extout = (dir unless dir.empty?)}
 | |
|   opt.on('--make=COMMAND') {|make| $make = make}
 | |
|   opt.on('--mantype=MAN') {|man| $mantype = man}
 | |
|   opt.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|
 | |
|     if arg = v.first
 | |
|       arg.insert(0, '-') if /\A[^-][^=]*\Z/ =~ arg
 | |
|     end
 | |
|     $mflags.concat(v)
 | |
|   end
 | |
|   opt.on('-i', '--install=TYPE', $install_procs.keys) do |ins|
 | |
|     $install << ins
 | |
|   end
 | |
|   opt.on('--data-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
 | |
|     $data_mode = mode
 | |
|   end
 | |
|   opt.on('--prog-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
 | |
|     $prog_mode = mode
 | |
|   end
 | |
|   opt.on('--dir-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
 | |
|     $dir_mode = mode
 | |
|   end
 | |
|   opt.on('--script-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
 | |
|     $script_mode = mode
 | |
|   end
 | |
|   opt.on('--installed-list [FILENAME]') {|name| $installed_list = name}
 | |
|   opt.on('--rdoc-output [DIR]') {|dir| $rdocdir = dir}
 | |
|   opt.on('--cmd-type=TYPE', %w[bat cmd plain]) {|cmd| $cmdtype = (cmd unless cmd == 'plain')}
 | |
|   opt.on('--[no-]strip') {|strip| $strip = strip}
 | |
| 
 | |
|   opt.order!(argv) do |v|
 | |
|     case v
 | |
|     when /\AINSTALL[-_]([-\w]+)=(.*)/
 | |
|       argv.unshift("--#{$1.tr('_', '-')}=#{$2}")
 | |
|     when /\A\w[-\w+]*=\z/
 | |
|       mflags << v
 | |
|     when /\A\w[-\w+]*\z/
 | |
|       $install << v.intern
 | |
|     else
 | |
|       raise OptionParser::InvalidArgument, v
 | |
|     end
 | |
|   end rescue abort "#{$!.message}\n#{opt.help}"
 | |
| 
 | |
|   unless defined?(RbConfig)
 | |
|     puts opt.help
 | |
|     exit
 | |
|   end
 | |
| 
 | |
|   $make, *rest = Shellwords.shellwords($make)
 | |
|   $mflags.unshift(*rest) unless rest.empty?
 | |
|   $mflags.unshift(*mflags)
 | |
| 
 | |
|   def $mflags.set?(flag)
 | |
|     grep(/\A-(?!-).*#{flag.chr}/i) { return true }
 | |
|     false
 | |
|   end
 | |
|   def $mflags.defined?(var)
 | |
|     grep(/\A#{var}=(.*)/) {return block_given? ? yield($1) : $1}
 | |
|     false
 | |
|   end
 | |
| 
 | |
|   if $mflags.set?(?n)
 | |
|     $dryrun = true
 | |
|   else
 | |
|     $mflags << '-n' if $dryrun
 | |
|   end
 | |
| 
 | |
|   $destdir ||= $mflags.defined?("DESTDIR")
 | |
|   if $extout ||= $mflags.defined?("EXTOUT")
 | |
|     RbConfig.expand($extout)
 | |
|   end
 | |
| 
 | |
|   $continue = $mflags.set?(?k)
 | |
| 
 | |
|   if $installed_list ||= $mflags.defined?('INSTALLED_LIST')
 | |
|     RbConfig.expand($installed_list, RbConfig::CONFIG)
 | |
|     $installed_list = open($installed_list, "ab")
 | |
|     $installed_list.sync = true
 | |
|   end
 | |
| 
 | |
|   $rdocdir ||= $mflags.defined?('RDOCOUT')
 | |
| 
 | |
|   $dir_mode ||= $prog_mode | 0700
 | |
|   $script_mode ||= $prog_mode
 | |
| end
 | |
| 
 | |
| $install_procs = Hash.new {[]}
 | |
| def install?(*types, &block)
 | |
|   $install_procs[:all] <<= block
 | |
|   types.each do |type|
 | |
|     $install_procs[type] <<= block
 | |
|   end
 | |
| end
 | |
| 
 | |
| def strip_file(files)
 | |
|   if !defined?($strip_command) and (cmd = CONFIG["STRIP"])
 | |
|     case cmd
 | |
|     when "", "true", ":" then return
 | |
|     else $strip_command = Shellwords.shellwords(cmd)
 | |
|     end
 | |
|   elsif !$strip_command
 | |
|     return
 | |
|   end
 | |
|   system(*($strip_command + [files].flatten))
 | |
| end
 | |
| 
 | |
| def install(src, dest, options = {})
 | |
|   options = options.clone
 | |
|   strip = options.delete(:strip)
 | |
|   options[:preserve] = true
 | |
|   d = with_destdir(dest)
 | |
|   super(src, d, options)
 | |
|   srcs = Array(src)
 | |
|   if strip
 | |
|     d = srcs.map {|src| File.join(d, File.basename(src))} if $made_dirs[dest]
 | |
|     strip_file(d)
 | |
|   end
 | |
|   if $installed_list
 | |
|     dest = srcs.map {|src| File.join(dest, File.basename(src))} if $made_dirs[dest]
 | |
|     $installed_list.puts dest
 | |
|   end
 | |
| end
 | |
| 
 | |
| def ln_sf(src, dest)
 | |
|   super(src, with_destdir(dest))
 | |
|   $installed_list.puts dest if $installed_list
 | |
| end
 | |
| 
 | |
| $made_dirs = {}
 | |
| def makedirs(dirs)
 | |
|   dirs = fu_list(dirs)
 | |
|   dirs.collect! do |dir|
 | |
|     realdir = with_destdir(dir)
 | |
|     realdir unless $made_dirs.fetch(dir) do
 | |
|       $made_dirs[dir] = true
 | |
|       $installed_list.puts(File.join(dir, "")) if $installed_list
 | |
|       File.directory?(realdir)
 | |
|     end
 | |
|   end.compact!
 | |
|   super(dirs, :mode => $dir_mode) unless dirs.empty?
 | |
| end
 | |
| 
 | |
| FalseProc = proc {false}
 | |
| def path_matcher(pat)
 | |
|   if pat and !pat.empty?
 | |
|     proc {|f| pat.any? {|n| File.fnmatch?(n, f)}}
 | |
|   else
 | |
|     FalseProc
 | |
|   end
 | |
| end
 | |
| 
 | |
| def install_recursive(srcdir, dest, options = {})
 | |
|   opts = options.clone
 | |
|   noinst = opts.delete(:no_install)
 | |
|   glob = opts.delete(:glob) || "*"
 | |
|   maxdepth = opts.delete(:maxdepth)
 | |
|   subpath = (srcdir.size+1)..-1
 | |
|   prune = []
 | |
|   skip = []
 | |
|   if noinst
 | |
|     if Array === noinst
 | |
|       prune = noinst.grep(/#{File::SEPARATOR}/o).map!{|f| f.chomp(File::SEPARATOR)}
 | |
|       skip = noinst.grep(/\A[^#{File::SEPARATOR}]*\z/o)
 | |
|     else
 | |
|       if noinst.index(File::SEPARATOR)
 | |
|         prune = [noinst]
 | |
|       else
 | |
|         skip = [noinst]
 | |
|       end
 | |
|     end
 | |
|   end
 | |
|   skip |= %w"#*# *~ *.old *.bak *.orig *.rej *.diff *.patch *.core"
 | |
|   prune = path_matcher(prune)
 | |
|   skip = path_matcher(skip)
 | |
|   File.directory?(srcdir) or return rescue return
 | |
|   paths = [[srcdir, dest, 0]]
 | |
|   found = []
 | |
|   while file = paths.shift
 | |
|     found << file
 | |
|     file, d, dir = *file
 | |
|     if dir
 | |
|       depth = dir + 1
 | |
|       next if maxdepth and maxdepth < depth
 | |
|       files = []
 | |
|       Dir.foreach(file) do |f|
 | |
|         src = File.join(file, f)
 | |
|         d = File.join(dest, dir = src[subpath])
 | |
|         stat = File.lstat(src) rescue next
 | |
|         if stat.directory?
 | |
|           files << [src, d, depth] if maxdepth != depth and /\A\./ !~ f and !prune[dir]
 | |
|         elsif stat.symlink?
 | |
|           # skip
 | |
|         else
 | |
|           files << [src, d, false] if File.fnmatch?(glob, f) and !skip[f]
 | |
|         end
 | |
|       end
 | |
|       paths.insert(0, *files)
 | |
|     end
 | |
|   end
 | |
|   for src, d, dir in found
 | |
|     if dir
 | |
|       makedirs(d)
 | |
|     else
 | |
|       makedirs(d[/.*(?=\/)/m])
 | |
|       if block_given?
 | |
|         yield src, d, opts
 | |
|       else
 | |
|         install src, d, opts
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| def open_for_install(path, mode)
 | |
|   data = open(realpath = with_destdir(path), "rb") {|f| f.read} rescue nil
 | |
|   newdata = yield
 | |
|   unless $dryrun
 | |
|     unless newdata == data
 | |
|       open(realpath, "wb", mode) {|f| f.write newdata}
 | |
|     end
 | |
|     File.chmod(mode, realpath)
 | |
|   end
 | |
|   $installed_list.puts path if $installed_list
 | |
| end
 | |
| 
 | |
| def with_destdir(dir)
 | |
|   return dir if !$destdir or $destdir.empty?
 | |
|   dir = dir.sub(/\A\w:/, '') if File::PATH_SEPARATOR == ';'
 | |
|   $destdir + dir
 | |
| end
 | |
| 
 | |
| def prepare(mesg, basedir, subdirs=nil)
 | |
|   return unless basedir
 | |
|   case
 | |
|   when !subdirs
 | |
|     dirs = basedir
 | |
|   when subdirs.size == 0
 | |
|     subdirs = nil
 | |
|   when subdirs.size == 1
 | |
|     dirs = [basedir = File.join(basedir, subdirs)]
 | |
|     subdirs = nil
 | |
|   else
 | |
|     dirs = [basedir, *subdirs.collect {|dir| File.join(basedir, dir)}]
 | |
|   end
 | |
|   printf("installing %-18s %s%s\n", "#{mesg}:", basedir,
 | |
|          (subdirs ? " (#{subdirs.join(', ')})" : ""))
 | |
|   makedirs(dirs)
 | |
| end
 | |
| 
 | |
| def CONFIG.[](name, mandatory = false)
 | |
|   value = super(name)
 | |
|   if mandatory
 | |
|     raise "CONFIG['#{name}'] must be set" if !value or value.empty?
 | |
|   end
 | |
|   value
 | |
| end
 | |
| 
 | |
| exeext = CONFIG["EXEEXT"]
 | |
| 
 | |
| ruby_install_name = CONFIG["ruby_install_name", true]
 | |
| rubyw_install_name = CONFIG["rubyw_install_name"]
 | |
| goruby_install_name = "go" + ruby_install_name
 | |
| 
 | |
| bindir = CONFIG["bindir", true]
 | |
| libdir = CONFIG[CONFIG.fetch("libdirname", "libdir"), true]
 | |
| rubyhdrdir = CONFIG["rubyhdrdir", true]
 | |
| archhdrdir = CONFIG["rubyarchhdrdir"] || (rubyhdrdir + "/" + CONFIG['arch'])
 | |
| rubylibdir = CONFIG["rubylibdir", true]
 | |
| archlibdir = CONFIG["rubyarchdir", true]
 | |
| sitelibdir = CONFIG["sitelibdir"]
 | |
| sitearchlibdir = CONFIG["sitearchdir"]
 | |
| vendorlibdir = CONFIG["vendorlibdir"]
 | |
| vendorarchlibdir = CONFIG["vendorarchdir"]
 | |
| mandir = CONFIG["mandir", true]
 | |
| docdir = CONFIG["docdir", true]
 | |
| configure_args = Shellwords.shellwords(CONFIG["configure_args"])
 | |
| enable_shared = CONFIG["ENABLE_SHARED"] == 'yes'
 | |
| dll = CONFIG["LIBRUBY_SO", enable_shared]
 | |
| lib = CONFIG["LIBRUBY", true]
 | |
| arc = CONFIG["LIBRUBY_A", true]
 | |
| major = CONFIG["MAJOR", true]
 | |
| minor = CONFIG["MINOR", true]
 | |
| load_relative = configure_args.include?("--enable-load-relative")
 | |
| 
 | |
| install?(:local, :arch, :bin, :'bin-arch') do
 | |
|   prepare "binary commands", bindir
 | |
| 
 | |
|   install ruby_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
 | |
|   if rubyw_install_name and !rubyw_install_name.empty?
 | |
|     install rubyw_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
 | |
|   end
 | |
|   if File.exist? goruby_install_name+exeext
 | |
|     install goruby_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
 | |
|   end
 | |
|   if enable_shared and dll != lib
 | |
|     install dll, bindir, :mode => $prog_mode, :strip => $strip
 | |
|   end
 | |
| end
 | |
| 
 | |
| install?(:local, :arch, :lib) do
 | |
|   prepare "base libraries", libdir
 | |
| 
 | |
|   install lib, libdir, :mode => $prog_mode, :strip => $strip unless lib == arc
 | |
|   install arc, libdir, :mode => $data_mode
 | |
|   if dll == lib and dll != arc
 | |
|     for link in CONFIG["LIBRUBY_ALIASES"].split
 | |
|       ln_sf(dll, File.join(libdir, link))
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   prepare "arch files", archlibdir
 | |
|   install "rbconfig.rb", archlibdir, :mode => $data_mode
 | |
|   if CONFIG["ARCHFILE"]
 | |
|     for file in CONFIG["ARCHFILE"].split
 | |
|       install file, archlibdir, :mode => $data_mode
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| install?(:local, :arch, :data) do
 | |
|   pc = CONFIG["ruby_pc"]
 | |
|   if pc and File.file?(pc) and File.size?(pc)
 | |
|     prepare "pkgconfig data", pkgconfigdir = File.join(libdir, "pkgconfig")
 | |
|     install pc, pkgconfigdir, :mode => $data_mode
 | |
|   end
 | |
| end
 | |
| 
 | |
| install?(:ext, :arch, :'ext-arch') do
 | |
|   prepare "extension objects", archlibdir
 | |
|   noinst = %w[-* -*/] | (CONFIG["no_install_files"] || "").split
 | |
|   install_recursive("#{$extout}/#{CONFIG['arch']}", archlibdir, :no_install => noinst, :mode => $prog_mode, :strip => $strip)
 | |
|   prepare "extension objects", sitearchlibdir
 | |
|   prepare "extension objects", vendorarchlibdir
 | |
| end
 | |
| install?(:ext, :arch, :'ext-arch') do
 | |
|   prepare "extension headers", archhdrdir
 | |
|   install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "*.h", :mode => $data_mode)
 | |
| end
 | |
| install?(:ext, :comm, :'ext-comm') do
 | |
|   prepare "extension scripts", rubylibdir
 | |
|   install_recursive("#{$extout}/common", rubylibdir, :mode => $data_mode)
 | |
|   prepare "extension scripts", sitelibdir
 | |
|   prepare "extension scripts", vendorlibdir
 | |
| end
 | |
| install?(:ext, :comm, :'ext-comm') do
 | |
|   hdrdir = rubyhdrdir + "/ruby"
 | |
|   prepare "extension headers", hdrdir
 | |
|   install_recursive("#{$extout}/include/ruby", hdrdir, :glob => "*.h", :mode => $data_mode)
 | |
| end
 | |
| 
 | |
| install?(:doc, :rdoc) do
 | |
|   if $rdocdir
 | |
|     ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system")
 | |
|     prepare "rdoc", ridatadir
 | |
|     install_recursive($rdocdir, ridatadir, :mode => $data_mode)
 | |
|   end
 | |
| end
 | |
| install?(:doc, :capi) do
 | |
|   prepare "capi-docs", docdir
 | |
|   install_recursive "doc/capi", docdir+"/capi", :mode => $data_mode
 | |
| end
 | |
| 
 | |
| if load_relative
 | |
|   PROLOG_SCRIPT = <<EOS
 | |
| #!/bin/sh\n# -*- ruby -*-
 | |
| bindir=`#{CONFIG["CHDIR"]} "${0%/*}" 2>/dev/null; pwd`
 | |
| EOS
 | |
|   if CONFIG["LIBRUBY_RELATIVE"] != 'yes' and libpathenv = CONFIG["LIBPATHENV"]
 | |
|     pathsep = File::PATH_SEPARATOR
 | |
|     PROLOG_SCRIPT << <<EOS
 | |
| prefix="${bindir%/bin}"
 | |
| export #{libpathenv}="$prefix/lib${#{libpathenv}#{pathsep}+#{pathsep}$#{libpathenv}}"
 | |
| EOS
 | |
|   end
 | |
|   PROLOG_SCRIPT << %Q[exec "$bindir/#{ruby_install_name}" -x "$0" "$@"\n]
 | |
| else
 | |
|   PROLOG_SCRIPT = nil
 | |
| end
 | |
| 
 | |
| install?(:local, :comm, :bin, :'bin-comm') do
 | |
|   prepare "command scripts", bindir
 | |
| 
 | |
|   ruby_shebang = File.join(bindir, ruby_install_name)
 | |
|   if File::ALT_SEPARATOR
 | |
|     ruby_bin = ruby_shebang.tr(File::SEPARATOR, File::ALT_SEPARATOR)
 | |
|     if $cmdtype == 'exe'
 | |
|       stub = File.open("rubystub.exe", "rb") {|f| f.read} << "\n" rescue nil
 | |
|     end
 | |
|   end
 | |
|   if trans = CONFIG["program_transform_name"]
 | |
|     exp = []
 | |
|     trans.gsub!(/\$\$/, '$')
 | |
|     trans.scan(%r[\G[\s;]*(/(?:\\.|[^/])*/)?([sy])(\\?\W)((?:(?!\3)(?:\\.|.))*)\3((?:(?!\3)(?:\\.|.))*)\3([gi]*)]) do
 | |
|       |addr, cmd, sep, pat, rep, opt|
 | |
|       addr &&= Regexp.new(addr[/\A\/(.*)\/\z/, 1])
 | |
|       case cmd
 | |
|       when 's'
 | |
|         next if pat == '^' and rep.empty?
 | |
|         exp << [addr, (opt.include?('g') ? :gsub! : :sub!),
 | |
|                 Regexp.new(pat, opt.include?('i')), rep.gsub(/&/){'\&'}]
 | |
|       when 'y'
 | |
|         exp << [addr, :tr!, Regexp.quote(pat), rep]
 | |
|       end
 | |
|     end
 | |
|     trans = proc do |base|
 | |
|       exp.each {|addr, opt, pat, rep| base.__send__(opt, pat, rep) if !addr or addr =~ base}
 | |
|       base
 | |
|     end
 | |
|   elsif /ruby/ =~ ruby_install_name
 | |
|     trans = proc {|base| ruby_install_name.sub(/ruby/, base)}
 | |
|   else
 | |
|     trans = proc {|base| base}
 | |
|   end
 | |
|   install_recursive(File.join(srcdir, "bin"), bindir, :maxdepth => 1) do |src, cmd|
 | |
|     cmd = cmd.sub(/[^\/]*\z/m) {|n| RbConfig.expand(trans[n])}
 | |
| 
 | |
|     shebang = ''
 | |
|     body = ''
 | |
|     open(src, "rb") do |f|
 | |
|       shebang = f.gets
 | |
|       body = f.read
 | |
|     end
 | |
|     shebang or raise "empty file - #{src}"
 | |
|     if PROLOG_SCRIPT
 | |
|       shebang.sub!(/\A(\#!.*?ruby\b)?/) {PROLOG_SCRIPT + ($1 || "#!ruby\n")}
 | |
|     else
 | |
|       shebang.sub!(/\A\#!.*?ruby\b/) {"#!" + ruby_shebang}
 | |
|     end
 | |
|     shebang.sub!(/\r$/, '')
 | |
|     body.gsub!(/\r$/, '')
 | |
| 
 | |
|     cmd << ".#{$cmdtype}" if $cmdtype
 | |
|     open_for_install(cmd, $script_mode) do
 | |
|       case $cmdtype
 | |
|       when "exe"
 | |
|         stub + shebang + body
 | |
|       when "bat"
 | |
|         [<<-"EOH".gsub(/^\s+/, ''), shebang, body, "__END__\n:endofruby\n"].join.gsub(/$/, "\r")
 | |
|           @echo off
 | |
|           @if not "%~d0" == "~d0" goto WinNT
 | |
|           #{ruby_bin} -x "#{cmd}" %1 %2 %3 %4 %5 %6 %7 %8 %9
 | |
|           @goto endofruby
 | |
|           :WinNT
 | |
|           "%~dp0#{ruby_install_name}" -x "%~f0" %*
 | |
|           @goto endofruby
 | |
|         EOH
 | |
|       when "cmd"
 | |
|         <<"/EOH" << shebang << body
 | |
| @"%~dp0#{ruby_install_name}" -x "%~f0" %*
 | |
| @exit /b %ERRORLEVEL%
 | |
| /EOH
 | |
|       else
 | |
|         shebang + body
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| install?(:local, :comm, :lib) do
 | |
|   prepare "library scripts", rubylibdir
 | |
|   noinst = %w[README* *.txt *.rdoc *.gemspec]
 | |
|   install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode)
 | |
| end
 | |
| 
 | |
| install?(:local, :arch, :lib) do
 | |
|   prepare "common headers", rubyhdrdir
 | |
| 
 | |
|   noinst = []
 | |
|   unless RUBY_PLATFORM =~ /mswin|mingw|bccwin/
 | |
|     noinst << "win32.h"
 | |
|   end
 | |
|   noinst = nil if noinst.empty?
 | |
|   install_recursive(File.join(srcdir, "include"), rubyhdrdir, :no_install => noinst, :glob => "*.h", :mode => $data_mode)
 | |
| end
 | |
| 
 | |
| install?(:local, :comm, :man) do
 | |
|   mdocs = Dir["#{srcdir}/man/*.[1-9]"]
 | |
|   prepare "manpages", mandir, ([] | mdocs.collect {|mdoc| mdoc[/\d+$/]}).sort.collect {|sec| "man#{sec}"}
 | |
| 
 | |
|   mandir = File.join(mandir, "man")
 | |
|   has_goruby = File.exist?(goruby_install_name+exeext)
 | |
|   require File.join(srcdir, "tool/mdoc2man.rb") if $mantype != "doc"
 | |
|   mdocs.each do |mdoc|
 | |
|     next unless File.file?(mdoc) and open(mdoc){|fh| fh.read(1) == '.'}
 | |
|     base = File.basename(mdoc)
 | |
|     if base == "goruby.1"
 | |
|       next unless has_goruby
 | |
|     end
 | |
| 
 | |
|     destdir = mandir + (section = mdoc[/\d+$/])
 | |
|     destname = ruby_install_name.sub(/ruby/, base.chomp(".#{section}"))
 | |
|     destfile = File.join(destdir, "#{destname}.#{section}")
 | |
| 
 | |
|     if $mantype == "doc"
 | |
|       install mdoc, destfile, :mode => $data_mode
 | |
|     else
 | |
|       class << (w = [])
 | |
|         alias print push
 | |
|       end
 | |
|       open(mdoc) {|r| Mdoc2Man.mdoc2man(r, w)}
 | |
|       open_for_install(destfile, $data_mode) {w.join("")}
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| # :stopdoc:
 | |
| module Gem
 | |
|   if defined?(Specification)
 | |
|     remove_const(:Specification)
 | |
|   end
 | |
| 
 | |
|   class Specification < OpenStruct
 | |
|     def initialize(*)
 | |
|       super
 | |
|       yield(self) if defined?(yield)
 | |
|       self.executables ||= []
 | |
|     end
 | |
| 
 | |
|     def self.load(path)
 | |
|       src = File.open(path, "rb") {|f| f.read}
 | |
|       src.sub!(/\A#.*/, '')
 | |
|       spec = eval(src, nil, path)
 | |
|       spec.date ||= last_date(path) || RUBY_RELEASE_DATE
 | |
|       spec
 | |
|     end
 | |
| 
 | |
|     def self.last_date(path)
 | |
|       return unless $vcs
 | |
|       time = $vcs.get_revisions(path)[2] rescue return
 | |
|       return unless time
 | |
|       time.strftime("%Y-%m-%d")
 | |
|     end
 | |
| 
 | |
|     def to_ruby
 | |
|       <<-GEMSPEC
 | |
| Gem::Specification.new do |s|
 | |
|   s.name = #{name.dump}
 | |
|   s.version = #{version.dump}
 | |
|   s.date = #{date.dump}
 | |
|   s.summary = #{summary.dump}
 | |
|   s.description = #{description.dump}
 | |
|   s.homepage = #{homepage.dump}
 | |
|   s.authors = #{authors.inspect}
 | |
|   s.email = #{email.inspect}
 | |
|   s.files = #{files.inspect}
 | |
| end
 | |
|       GEMSPEC
 | |
|     end
 | |
| 
 | |
|     def self.unresolved_deps
 | |
|       []
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| module RbInstall
 | |
|   module Specs
 | |
|     class FileCollector
 | |
|       def initialize(base_dir)
 | |
|         @base_dir = base_dir
 | |
|       end
 | |
| 
 | |
|       def collect
 | |
|         (ruby_libraries + built_libraries).sort
 | |
|       end
 | |
| 
 | |
|       private
 | |
|       def type
 | |
|         /\/(ext|lib)?\/.*?\z/ =~ @base_dir
 | |
|         $1
 | |
|       end
 | |
| 
 | |
|       def ruby_libraries
 | |
|         case type
 | |
|         when "ext"
 | |
|           prefix = "#{$extout}/common/"
 | |
|           base = "#{prefix}#{relative_base}"
 | |
|         when "lib"
 | |
|           base = @base_dir
 | |
|           prefix = base.sub(/lib\/.*?\z/, "") + "lib/"
 | |
|         end
 | |
| 
 | |
|         Dir.glob("#{base}{.rb,/**/*.rb}").collect do |ruby_source|
 | |
|           remove_prefix(prefix, ruby_source)
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def built_libraries
 | |
|         case type
 | |
|         when "ext"
 | |
|           prefix = "#{$extout}/#{CONFIG['arch']}/"
 | |
|           base = "#{prefix}#{relative_base}"
 | |
|           Dir.glob("#{base}{.so,/**/*.so}").collect do |built_library|
 | |
|             remove_prefix(prefix, built_library)
 | |
|           end
 | |
|         when "lib"
 | |
|           []
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def relative_base
 | |
|         /\/#{Regexp.escape(type)}\/(.*?)\z/ =~ @base_dir
 | |
|         $1
 | |
|       end
 | |
| 
 | |
|       def remove_prefix(prefix, string)
 | |
|         string.sub(/\A#{Regexp.escape(prefix)}/, "")
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     class Reader < Struct.new(:src)
 | |
|       def gemspec
 | |
|         @gemspec ||= begin
 | |
|           spec = Gem::Specification.load(src) || raise("invalid spec in #{src}")
 | |
|           file_collector = FileCollector.new(File.dirname(src))
 | |
|           spec.files = file_collector.collect
 | |
|           spec
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def spec_source
 | |
|         @gemspec.to_ruby
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     class Generator < Struct.new(:name, :base_dir, :src, :execs)
 | |
|       def gemspec
 | |
|         @gemspec ||= eval spec_source
 | |
|       end
 | |
| 
 | |
|       def spec_source
 | |
|         <<-GEMSPEC
 | |
| Gem::Specification.new do |s|
 | |
|   s.name = #{name.dump}
 | |
|   s.version = #{version.dump}
 | |
|   s.summary = "This #{name} is bundled with Ruby"
 | |
|   s.executables = #{execs.inspect}
 | |
|   s.files = #{files.inspect}
 | |
| end
 | |
|         GEMSPEC
 | |
|       end
 | |
| 
 | |
|       private
 | |
|       def version
 | |
|         version = open(src) { |f|
 | |
|           f.find { |s| /^\s*\w*VERSION\s*=(?!=)/ =~ s }
 | |
|         } or return
 | |
|         version.split(%r"=\s*", 2)[1].strip[/\A([\'\"])(.*?)\1/, 2]
 | |
|       end
 | |
| 
 | |
|       def files
 | |
|         file_collector = FileCollector.new(base_dir)
 | |
|         file_collector.collect
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | |
| # :startdoc:
 | |
| 
 | |
| install?(:ext, :comm, :gem) do
 | |
|   $:.unshift(File.join(srcdir, "lib"))
 | |
|   require("rubygems.rb")
 | |
|   gem_dir = Gem.default_dir
 | |
|   directories = Gem.ensure_gem_subdirectories(gem_dir, :mode => $dir_mode)
 | |
|   prepare "default gems", gem_dir, directories
 | |
| 
 | |
|   spec_dir = File.join(gem_dir, directories.grep(/^spec/)[0])
 | |
|   default_spec_dir = "#{spec_dir}/default"
 | |
|   makedirs(default_spec_dir)
 | |
| 
 | |
|   gems = {}
 | |
|   File.foreach(File.join(srcdir, "defs/default_gems")) do |line|
 | |
|     line.chomp!
 | |
|     line.sub!(/\s*#.*/, '')
 | |
|     next if line.empty?
 | |
|     words = []
 | |
|     line.scan(/\G\s*([^\[\]\s]+|\[([^\[\]]*)\])/) do
 | |
|       words << ($2 ? $2.split : $1)
 | |
|     end
 | |
|     name, base_dir, src, execs = *words
 | |
|     next unless name and base_dir and src
 | |
| 
 | |
|     src       = File.join(srcdir, src)
 | |
|     base_dir  = File.join(srcdir, base_dir)
 | |
|     specgen   = RbInstall::Specs::Generator.new(name, base_dir, src, execs || [])
 | |
|     gems[name] ||= specgen
 | |
|   end
 | |
| 
 | |
|   Dir.glob(srcdir+"/{lib,ext}/**/*.gemspec").each do |src|
 | |
|     specgen   = RbInstall::Specs::Reader.new(src)
 | |
|     gems[specgen.gemspec.name] ||= specgen
 | |
|   end
 | |
| 
 | |
|   gems.sort.each do |name, specgen|
 | |
|     gemspec   = specgen.gemspec
 | |
|     base_dir  = specgen.src.sub(/\A#{Regexp.escape(srcdir)}\//, "")
 | |
|     full_name = "#{gemspec.name}-#{gemspec.version}"
 | |
| 
 | |
|     puts "#{" "*30}#{gemspec.name} #{gemspec.version}"
 | |
|     gemspec_path = File.join(default_spec_dir, "#{full_name}.gemspec")
 | |
|     open_for_install(gemspec_path, $data_mode) do
 | |
|       specgen.spec_source
 | |
|     end
 | |
| 
 | |
|     unless gemspec.executables.empty? then
 | |
|       bin_dir = File.join(gem_dir, 'gems', full_name, 'bin')
 | |
|       makedirs(bin_dir)
 | |
| 
 | |
|       execs = gemspec.executables.map {|exec| File.join(srcdir, 'bin', exec)}
 | |
|       install(execs, bin_dir, :mode => $prog_mode)
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | |
| parse_args()
 | |
| 
 | |
| include FileUtils
 | |
| include FileUtils::NoWrite if $dryrun
 | |
| @fileutils_output = STDOUT
 | |
| @fileutils_label = ''
 | |
| 
 | |
| all = $install.delete(:all)
 | |
| $install << :local << :ext if $install.empty?
 | |
| installs = $install.map do |inst|
 | |
|   if !(procs = $install_procs[inst]) || procs.empty?
 | |
|     next warn("unknown install target - #{inst}")
 | |
|   end
 | |
|   procs
 | |
| end
 | |
| installs.flatten!
 | |
| installs.uniq!
 | |
| installs |= $install_procs[:all] if all
 | |
| installs.each do |block|
 | |
|   dir = Dir.pwd
 | |
|   begin
 | |
|     block.call
 | |
|   ensure
 | |
|     Dir.chdir(dir)
 | |
|   end
 | |
| end
 | |
| 
 | |
| # vi:set sw=2:
 |