class Installer $VERBOSE = nil getenv = lambda{|key| ENV[key] or abort("no ENV['#{ key }']")} PREFIX = getenv["prefix"] MAKE = getenv["make"] || getenv["MAKE"] PACKAGEDIR = getenv["packagedir"] BUILDDIR = getenv["builddir"] SUDO = getenv["sudo"] RUBY = getenv["ruby"] LDFLAGS = getenv["LDFLAGS"] CFLAGS = getenv["CFLAGS"] INSTALL = "#{ PACKAGEDIR }/INSTALL" def run manifest = test ?e, INSTALL packages = if manifest lines = IO.readlines INSTALL lines.delete_if{|line| line.strip.empty? or line =~ %r/^\s*#/} lines.map{|line| File.join(PACKAGEDIR, File.basename(line.strip))} else filelist "#{ PACKAGEDIR }/*.{tar.gz,tgz}" end packages.delete_if{|package| package.strip.empty?} packages.delete_if{|package| File.basename(package) !~ %r/\.(tar\.gz|tgz)$/} packages.delete_if{|package| File.basename(package) =~ %r/^ruby.*\.(tar\.gz|tgz)$/} Dir.chdir(BUILDDIR){ unless manifest packages = packages.sort_by do |package| lines = `tar tfz #{ package }`.split %/\n/ line = lines.grep(%r/(install\.rb|extconf\.rb|configure)/).first dirname, first, rest = line.split(File::SEPARATOR, 2) type = first unless rest abort "cannot determine type of <#{ package }>" unless type case type when /configure/ 0 when /extconf.rb/ 1 when /install.rb/ 2 end end end packages.each{|package| install_package package} } Dir.chdir(".."){ pwd = File.basename(Dir.pwd) log = "#{ pwd }.log" if test ?e, "install.rb" puts "installing #{ pwd } (see #{ log } for details)..." install_ruby_package log end if test ?e, "extconf.rb" puts "installing #{ pwd } (see #{ log } for details)..." install_ruby_extentsion log end if test ?e, "configure" puts "installing #{ pwd } (see #{ log } for details)..." install_src_package log end } end def install_package package case package when /(tgz|tar.gz)$/ install_from_tgz package else abort "can't install package <#{ package }>" end end def install_from_tgz tgz old = filelist '*' spawn "tar xvfz #{ tgz } >/dev/null 2>&1" new = filelist '*' created = new - old expected = File.join(BUILDDIR, File.basename(tgz).gsub(%r/(\.tar\.gz|\.tgz)$/,'')) dir = created.first || expected log = "#{ BUILDDIR }/#{ File.basename tgz }.log" Dir.chdir(dir){ puts "installing #{ tgz } (see #{ log } for details)..." status = nil if test ?e, 'install.rb' status = install_ruby_package(log) end if test ?e, 'extconf.rb' status = install_ruby_extentsion(log) end if test ?e, 'configure' status = install_src_package(log) end if status puts "success" else puts "failure" exit 1 end } end def install_ruby_package log system "{ #{ SUDO } #{ RUBY } install.rb '--with-cflags=#{ CFLAGS }' '--with-ldflags=#{ LDFLAGS }'; } >#{ log } 2>&1" or system "{ #{ SUDO } #{ RUBY } install.rb; } >#{ log } 2>&1" end def install_ruby_extentsion log system "{ #{ RUBY } extconf.rb '--with-cflags=#{ CFLAGS }' '--with-ldflags=#{ LDFLAGS }' && stat [mM]akefile && #{ MAKE } && #{ SUDO } #{ MAKE } install; } >#{ log } 2>&1" or system "{ #{ RUBY } extconf.rb && stat [mM]akefile && #{ MAKE } && #{ SUDO } #{ MAKE } install; } >#{ log } 2>&1" end def install_src_package log system "{ #{ MAKE } clean; } >/dev/null 2>&1" system "{ ./configure --prefix=#{ PREFIX } && stat [mM]akefile && #{ MAKE } && #{ SUDO } #{ MAKE } install; } >#{ log } 2>&1" end def spawn cmd system cmd or abort "cmd <#{ cmd }> failed" end def filelist glob Dir.glob(glob).map{|path| File.expand_path path}.sort.uniq end end Installer.new.run