module Multiruby
multiruby_setup is a script to help you manage multiruby.
usage: multiruby_setup [-h|cmd|spec…]
cmds: -h, --help, help = show this help. build = build and install everything. used internally. clean = clean scm build dirs and remove non-scm build dirs. list = print installed versions. rm:$version = remove a particular version. rubygems:merge = symlink all rubygem dirs to one dir. tags = list all tags from svn. update = update svn builds. update:rubygems = update rubygems and nuke install dirs. specs: the_usual = alias for latest versions from tar + rubygems mri:svn:current = alias for mri:svn:releases and mri:svn:branches. mri:svn:releases = alias for supported releases of mri ruby. mri:svn:branches = alias for active branches of mri ruby. mri:svn:branch:$branch = install a specific $branch of mri from svn. mri:svn:tag:$tag = install a specific $tag of mri from svn. mri:tar:$version = install a specific $version of mri from tarball. environment variables: GEM_URL = url for rubygems tarballs MRI_SVN = url for MRI SVN RUBY_URL = url for MRI tarballs VERSIONS = what versions to install RUBYOPT is cleared on installs.
NOTES:
-
you can add a symlink to your rubinius build into ~/.multiruby/install
-
I need patches/maintainers for other implementations.
Constants
- BRANCHES
- GEM_URL
- HELP
- MRI_SVN
- RUBY_URL
- TAGS
- VERSIONS
Public Class Methods
build_and_install()
click to toggle source
# File lib/multiruby.rb, line 63 def self.build_and_install ENV.delete 'RUBYOPT' root_dir = self.root_dir versions = [] Dir.chdir root_dir do self.setup_dirs rubygems = Dir["versions/rubygems*.tgz"] abort "You should delete all but one rubygem tarball" if rubygems.size > 1 rubygem_tarball = File.expand_path rubygems.last rescue nil Dir.chdir "build" do Dir["../versions/*"].sort.each do |tarball| next if tarball =~ /rubygems/ build_dir = File.basename tarball, ".tar.gz" version = build_dir.sub(/^ruby-?/, '') inst_dir = "#{root_dir}/install/#{version}" unless test ?d, inst_dir then unless test ?d, build_dir then if test ?d, tarball then dir = File.basename tarball FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}" else puts "creating #{inst_dir}" Dir.mkdir inst_dir run "tar zxf #{tarball}" end end Dir.chdir build_dir do puts "building and installing #{version}" if test ?f, "configure.in" then gnu_utils_build inst_dir elsif test ?f, "Rakefile" then rake_build inst_dir else raise "dunno how to build" end if rubygem_tarball and version !~ /1[._-]9|mri_trunk|rubinius/ then rubygems = File.basename rubygem_tarball, ".tgz" run "tar zxf #{rubygem_tarball}" unless test ?d, rubygems Dir.chdir rubygems do run "../ruby ./setup.rb --no-rdoc --no-ri", "../log.rubygems" end end end end end end versions = Dir["install/*"].map { |path| File.basename path } end versions end
clean()
click to toggle source
# File lib/multiruby.rb, line 124 def self.clean self.each_scm_build_dir do |style| case style when :svn then if File.exist? "Rakefile" then run "rake clean" elsif File.exist? "Makefile" then run "make clean" end else FileUtils.rm_rf Dir.pwd end end end
each_scm_build_dir() { |:svn| ... }
click to toggle source
# File lib/multiruby.rb, line 139 def self.each_scm_build_dir Multiruby.in_build_dir do Dir["*"].each do |dir| next unless File.directory? dir Dir.chdir dir do if File.exist?(".svn") then yield :svn else yield :none end end end end end
fetch_tar(v)
click to toggle source
# File lib/multiruby.rb, line 174 def self.fetch_tar v in_versions_dir do warn " Determining latest version for #{v}" ver = v[/\d+\.\d+/] base = matching_versions("#{RUBY_URL}/#{ver}/", v).last abort "Could not determine release for #{v}" unless base url = File.join RUBY_URL, ver, base unless File.file? base then warn " Fetching #{base} via HTTP... this might take a while." open(url) do |f| File.open base, 'w' do |out| out.write f.read end end end end end
gnu_utils_build(inst_dir)
click to toggle source
# File lib/multiruby.rb, line 192 def self.gnu_utils_build inst_dir run "autoconf" unless test ?f, "configure" run "./configure --enable-shared --prefix #{inst_dir}", "log.configure" unless test ?f, "Makefile" run "(nice make -j4 main; nice make main)", "log.build" run "make install-nodoc", "log.install" end
help()
click to toggle source
# File lib/multiruby.rb, line 200 def self.help puts HELP.join end
in_build_dir() { || ... }
click to toggle source
# File lib/multiruby.rb, line 204 def self.in_build_dir in_root_dir "build" do yield end end
in_install_dir() { || ... }
click to toggle source
# File lib/multiruby.rb, line 210 def self.in_install_dir in_root_dir "install" do yield end end
in_root_dir(subdir = "") { || ... }
click to toggle source
# File lib/multiruby.rb, line 216 def self.in_root_dir subdir = "" Dir.chdir File.join(self.root_dir, subdir) do yield end end
in_tmp_dir() { || ... }
click to toggle source
# File lib/multiruby.rb, line 222 def self.in_tmp_dir in_root_dir "tmp" do yield end end
in_versions_dir() { || ... }
click to toggle source
# File lib/multiruby.rb, line 228 def self.in_versions_dir in_root_dir "versions" do yield end end
list()
click to toggle source
# File lib/multiruby.rb, line 234 def self.list puts "Known versions:" in_install_dir do Dir["*"].sort.each do |d| puts " #{d}" end end end
matching_versions(url, matching=nil)
click to toggle source
# File lib/multiruby.rb, line 154 def self.matching_versions url, matching=nil file = URI.parse(url).read map = { "preview" => "beta", "rc" => "beta2", "p" => "release", "tar" => "aargh", "gz" => "aargh", } versions = file.scan(/href="(ruby.*tar.gz)"/).flatten.sort_by { |s| s.scan(/\d+|[a-z]+/).map { |a| Integer(a) rescue map[a] || a } } versions = versions.grep(/#{Regexp.escape(matching)}/) if matching versions end
merge_rubygems()
click to toggle source
# File lib/multiruby.rb, line 243 def self.merge_rubygems in_install_dir do gems = Dir["*/lib/ruby/gems"] unless test ?d, "../gems" then FileUtils.mv gems.first, ".." end gems.each do |d| FileUtils.rm_rf d FileUtils.ln_sf "../../../../gems", d end end end
mri_latest_tag(v)
click to toggle source
# File lib/multiruby.rb, line 258 def self.mri_latest_tag v Multiruby.tags.grep(/#{v}/).last end
rake_build(inst_dir)
click to toggle source
# File lib/multiruby.rb, line 262 def self.rake_build inst_dir run "rake", "log.build" FileUtils.ln_sf "../build/#{File.basename Dir.pwd}", inst_dir end
rm(name)
click to toggle source
# File lib/multiruby.rb, line 267 def self.rm name Multiruby.in_root_dir do FileUtils.rm_rf Dir["*/#{name}"] f = "versions/ruby-#{name}.tar.gz" File.unlink f if test ?f, f end end
root_dir()
click to toggle source
# File lib/multiruby.rb, line 275 def self.root_dir root_dir = File.expand_path(ENV['MULTIRUBY'] || File.join(ENV['HOME'], ".multiruby")) unless test ?d, root_dir then puts "creating #{root_dir}" Dir.mkdir root_dir, 0700 end root_dir end
run(base_cmd, log = nil)
click to toggle source
# File lib/multiruby.rb, line 287 def self.run base_cmd, log = nil cmd = base_cmd cmd += " > #{log} 2>&1" if log puts "Running command: #{cmd}" raise "ERROR: Command failed with exit code #{$?}" unless system cmd end
setup_dirs(download = true)
click to toggle source
# File lib/multiruby.rb, line 294 def self.setup_dirs download = true %w(build install versions tmp).each do |dir| unless test ?d, dir then puts "creating #{dir}" Dir.mkdir dir if dir == "versions" && download then warn " Downloading initial ruby tarballs to ~/.multiruby/versions:" VERSIONS.each do |v| self.fetch_tar v end warn " ...done" warn " Put other ruby tarballs in ~/.multiruby/versions to use them." end end end end
svn_co(url, dir)
click to toggle source
# File lib/multiruby.rb, line 311 def self.svn_co url, dir Multiruby.in_versions_dir do Multiruby.run "svn co #{url} #{dir}" unless File.directory? dir FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}" end end
update()
click to toggle source
# File lib/multiruby.rb, line 334 def self.update # TODO: # update will look at the dir name and act accordingly rel_.* will # figure out latest tag on that name and svn sw to it trunk and # others will just svn update clean = [] self.each_scm_build_dir do |style| dir = File.basename(Dir.pwd) warn dir case style when :svn then case dir when /mri_\d/ then system "svn cleanup" # just in case svn_up = `svn up` in_build_dir do if svn_up =~ /^[ADUCG] / then clean << dir else warn " no update" end FileUtils.ln_sf "../build/#{dir}", "../versions/#{dir}" end when /mri_rel_(.+)/ then ver = $1 url = `svn info`[/^URL: (.*)/, 1] latest = self.mri_latest_tag(ver).chomp('/') new_url = File.join(File.dirname(url), latest) if new_url != url then run "svn sw #{new_url}" clean << dir else warn " no update" end else warn " update in this svn dir not supported yet: #{dir}" end else warn " update in non-svn dir not supported yet: #{dir}" end end in_install_dir do clean.each do |dir| warn "removing install/#{dir}" FileUtils.rm_rf dir end end end
update_rubygems()
click to toggle source
# File lib/multiruby.rb, line 387 def self.update_rubygems warn " Determining latest version for rubygems" html = URI.parse(GEM_URL).read versions = html.scan(/href="rubygems-update-(\d+(?:\.\d+)+).gem/i).flatten latest = versions.sort_by { |v| v.scan(/\d+/).map { |s| s.to_i } }.last Multiruby.in_versions_dir do file = "rubygems-#{latest}.tgz" unless File.file? file then warn " Fetching rubygems-#{latest}.tgz via HTTP." File.unlink(*Dir["rubygems*"]) File.open file, 'w' do |f| f.write URI.parse(GEM_URL+"/"+file).read end end end Multiruby.in_build_dir do FileUtils.rm_rf Dir["rubygems*"] end Multiruby.in_install_dir do FileUtils.rm_rf Dir["*"] end end