In Files

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:

Constants

TAGS
BRANCHES
VERSIONS
MRI_SVN
RUBY_URL
GEM_URL
HELP

Public Class Methods

build_and_install() click to toggle source
     # File lib/multiruby.rb, line 63
 63:   def self.build_and_install
 64:     ENV.delete 'RUBYOPT'
 65: 
 66:     root_dir = self.root_dir
 67:     versions = []
 68: 
 69:     Dir.chdir root_dir do
 70:       self.setup_dirs
 71: 
 72:       rubygems = Dir["versions/rubygems*.tgz"]
 73:       abort "You should delete all but one rubygem tarball" if rubygems.size > 1
 74:       rubygem_tarball = File.expand_path rubygems.last rescue nil
 75: 
 76:       Dir.chdir "build" do
 77:         Dir["../versions/*"].sort.each do |tarball|
 78:           next if tarball =~ /rubygems/
 79: 
 80:           build_dir = File.basename tarball, ".tar.gz"
 81:           version = build_dir.sub(/^ruby-?/, '')
 82:           versions << version
 83:           inst_dir = "#{root_dir}/install/#{version}"
 84: 
 85:           unless test dd, inst_dir then
 86:             unless test dd, build_dir then
 87:               if test dd, tarball then
 88:                 dir = File.basename tarball
 89:                 FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
 90:               else
 91:                 puts "creating #{inst_dir}"
 92:                 Dir.mkdir inst_dir
 93:                 run "tar zxf #{tarball}"
 94:               end
 95:             end
 96:             Dir.chdir build_dir do
 97:               puts "building and installing #{version}"
 98:               if test ff, "configure.in" then
 99:                 gnu_utils_build inst_dir
100:               elsif test ff, "Rakefile" then
101:                 rake_build inst_dir
102:               else
103:                 raise "dunno how to build"
104:               end
105: 
106:               if rubygem_tarball and version !~ /1[._-]9|mri_trunk|rubinius/ then
107:                 rubygems = File.basename rubygem_tarball, ".tgz"
108:                 run "tar zxf #{rubygem_tarball}" unless test dd, rubygems
109: 
110:                 Dir.chdir rubygems do
111:                   run "../ruby ./setup.rb --no-rdoc --no-ri", "../log.rubygems"
112:                 end
113:               end
114:             end
115:           end
116:         end
117:       end
118:     end
119: 
120:     versions
121:   end
clean() click to toggle source
     # File lib/multiruby.rb, line 123
123:   def self.clean
124:     self.each_scm_build_dir do |style|
125:       case style
126:       when :svn, :git then
127:         if File.exist? "Rakefile" then
128:           run "rake clean"
129:         elsif File.exist? "Makefile" then
130:           run "make clean"
131:         end
132:       else
133:         FileUtils.rm_rf Dir.pwd
134:       end
135:     end
136:   end
each_scm_build_dir() click to toggle source
     # File lib/multiruby.rb, line 138
138:   def self.each_scm_build_dir
139:     Multiruby.in_build_dir do
140:       Dir["*"].each do |dir|
141:         next unless File.directory? dir
142:         Dir.chdir dir do
143:           if File.exist?(".svn") || File.exist?(".git") then
144:             scm = File.exist?(".svn") ? :svn : :git
145:             yield scm
146:           else
147:             yield :none
148:           end
149:         end
150:       end
151:     end
152:   end
env(name, fallback;) click to toggle source
    # File lib/multiruby.rb, line 46
46:   def self.env name, fallback; ENV[name] || fallback; end
extract_latest_version(url, matching=nil) click to toggle source
     # File lib/multiruby.rb, line 154
154:   def self.extract_latest_version url, matching=nil
155:     file = URI.parse(url).read
156:     versions = file.scan(/href="(ruby.*tar.gz)"/).flatten.reject { |s|
157:       s =~ /-rc\d/
158:     }.sort_by { |s|
159:       s.split(/\D+/).map { |i| i.to_i }
160:     }.flatten
161: 
162:     versions = versions.grep(/#{Regexp.escape(matching)}/) if matching
163:     versions.last
164:   end
fetch_tar(v) click to toggle source
     # File lib/multiruby.rb, line 166
166:   def self.fetch_tar v
167:     in_versions_dir do
168:       warn "  Determining latest version for #{v}"
169:       ver = v[/\d+\.\d+/]
170:       base = extract_latest_version("#{RUBY_URL}/#{ver}/", v)
171:       abort "Could not determine release for #{v}" unless base
172:       url = File.join RUBY_URL, ver, base
173:       unless File.file? base then
174:         warn "    Fetching #{base} via HTTP... this might take a while."
175:         open(url) do |f|
176:           File.open base, 'w' do |out|
177:             out.write f.read
178:           end
179:         end
180:       end
181:     end
182:   end
git_clone(url, dir) click to toggle source
     # File lib/multiruby.rb, line 184
184:   def self.git_clone url, dir
185:     Multiruby.in_versions_dir do
186:       Multiruby.run "git clone #{url} #{dir}" unless File.directory? dir
187:       FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
188:     end
189:   end
gnu_utils_build(inst_dir) click to toggle source
     # File lib/multiruby.rb, line 191
191:   def self.gnu_utils_build inst_dir
192:     run "autoconf" unless test ff, "configure"
193:     run "./configure --enable-shared --prefix #{inst_dir}", "log.configure" unless
194:       test ff, "Makefile"
195:     run "(nice make -j4; nice make)", "log.build"
196:     run "make install", "log.install"
197:   end
help() click to toggle source
     # File lib/multiruby.rb, line 199
199:   def self.help
200:     puts HELP.join
201:   end
in_build_dir() click to toggle source
     # File lib/multiruby.rb, line 203
203:   def self.in_build_dir
204:     Dir.chdir File.join(self.root_dir, "build") do
205:       yield
206:     end
207:   end
in_install_dir() click to toggle source
     # File lib/multiruby.rb, line 209
209:   def self.in_install_dir
210:     Dir.chdir File.join(self.root_dir, "install") do
211:       yield
212:     end
213:   end
in_root_dir() click to toggle source
     # File lib/multiruby.rb, line 215
215:   def self.in_root_dir
216:     Dir.chdir self.root_dir do
217:       yield
218:     end
219:   end
in_tmp_dir() click to toggle source
     # File lib/multiruby.rb, line 221
221:   def self.in_tmp_dir
222:     Dir.chdir File.join(self.root_dir, "tmp") do
223:       yield
224:     end
225:   end
in_versions_dir() click to toggle source
     # File lib/multiruby.rb, line 227
227:   def self.in_versions_dir
228:     Dir.chdir File.join(self.root_dir, "versions") do
229:       yield
230:     end
231:   end
list() click to toggle source
     # File lib/multiruby.rb, line 233
233:   def self.list
234:     puts "Known versions:"
235:     in_install_dir do
236:       Dir["*"].sort.each do |d|
237:         puts "  #{d}"
238:       end
239:     end
240:   end
merge_rubygems() click to toggle source
     # File lib/multiruby.rb, line 242
242:   def self.merge_rubygems
243:     in_install_dir do
244:       gems = Dir["*/lib/ruby/gems"]
245: 
246:       unless test dd, "../gems" then
247:         FileUtils.mv gems.first, ".."
248:       end
249: 
250:       gems.each do |d|
251:         FileUtils.rm_rf d
252:         FileUtils.ln_sf "../../../../gems", d
253:       end
254:     end
255:   end
mri_latest_tag(v) click to toggle source
     # File lib/multiruby.rb, line 257
257:   def self.mri_latest_tag v
258:     Multiruby.tags.grep(/#{v}/).last
259:   end
rake_build(inst_dir) click to toggle source
     # File lib/multiruby.rb, line 261
261:   def self.rake_build inst_dir
262:     run "rake", "log.build"
263:     FileUtils.ln_sf "../build/#{File.basename Dir.pwd}", inst_dir
264:   end
rm(name) click to toggle source
     # File lib/multiruby.rb, line 266
266:   def self.rm name
267:     Multiruby.in_root_dir do
268:       FileUtils.rm_rf Dir["*/#{name}"]
269:       f = "versions/ruby-#{name}.tar.gz"
270:       File.unlink f if test ff, f
271:     end
272:   end
root_dir() click to toggle source
     # File lib/multiruby.rb, line 274
274:   def self.root_dir
275:     root_dir = File.expand_path(ENV['MULTIRUBY'] ||
276:                                 File.join(ENV['HOME'], ".multiruby"))
277: 
278:     unless test dd, root_dir then
279:       puts "creating #{root_dir}"
280:       Dir.mkdir root_dir, 0700
281:     end
282: 
283:     root_dir
284:   end
run(base_cmd, log = nil) click to toggle source
     # File lib/multiruby.rb, line 286
286:   def self.run base_cmd, log = nil
287:     cmd = base_cmd
288:     cmd += " > #{log} 2>&1" if log
289:     puts "Running command: #{cmd}"
290:     raise "ERROR: Command failed with exit code #{$?}" unless system cmd
291:   end
setup_dirs(download = true) click to toggle source
     # File lib/multiruby.rb, line 293
293:   def self.setup_dirs download = true
294:     %(build install versions tmp).each do |dir|
295:       unless test dd, dir then
296:         puts "creating #{dir}"
297:         Dir.mkdir dir
298:         if dir == "versions" && download then
299:           warn "  Downloading initial ruby tarballs to ~/.multiruby/versions:"
300:           VERSIONS.each do |v|
301:             self.fetch_tar v
302:           end
303:           warn "  ...done"
304:           warn "  Put other ruby tarballs in ~/.multiruby/versions to use them."
305:         end
306:       end
307:     end
308:   end
svn_co(url, dir) click to toggle source
     # File lib/multiruby.rb, line 310
310:   def self.svn_co url, dir
311:     Multiruby.in_versions_dir do
312:       Multiruby.run "svn co #{url} #{dir}" unless File.directory? dir
313:       FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
314:     end
315:   end
tags() click to toggle source
     # File lib/multiruby.rb, line 317
317:   def self.tags
318:     tags = nil
319:     Multiruby.in_tmp_dir do
320:       cache = "svn.tag.cache"
321:       File.unlink cache if Time.now - File.mtime(cache) > 3600 rescue nil
322: 
323:       File.open cache, "w" do |f|
324:         f.write `svn ls #{MRI_SVN}/tags/`
325:       end unless File.exist? cache
326: 
327:       tags = File.read(cache).split(/\n/).grep(/^v/).reject {|s| s =~ /preview/}
328:     end
329: 
330:     tags = tags.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }
331:   end
update() click to toggle source
     # File lib/multiruby.rb, line 333
333:   def self.update
334:     # TODO:
335:     # update will look at the dir name and act accordingly rel_.* will
336:     # figure out latest tag on that name and svn sw to it trunk and
337:     # others will just svn update
338: 
339:     clean = []
340: 
341:     self.each_scm_build_dir do |style|
342:       dir = File.basename(Dir.pwd)
343:       warn dir
344: 
345:       case style
346:       when :svn then
347:         case dir
348:         when /mri_\d/ then
349:           system "svn cleanup" # just in case
350:           svn_up = `svn up`
351:           in_build_dir do
352:             if svn_up =~ /^[ADUCG] / then
353:               clean << dir
354:             else
355:               warn "  no update"
356:             end
357:             FileUtils.ln_sf "../build/#{dir}", "../versions/#{dir}"
358:           end
359:         when /mri_rel_(.+)/ then
360:           ver = $1
361:           url = `svn info`[/^URL: (.*)/, 1]
362:           latest = self.mri_latest_tag(ver).chomp('/')
363:           new_url = File.join(File.dirname(url), latest)
364:           if new_url != url then
365:             run "svn sw #{new_url}"
366:             clean << dir
367:           else
368:             warn "  no update"
369:           end
370:         else
371:           warn "  update in this svn dir not supported yet: #{dir}"
372:         end
373:       when :git then
374:         case dir
375:         when /rubinius/ then
376:           run "rake git:update build" # minor cheat by building here
377:         else
378:           warn "  update in this git dir not supported yet: #{dir}"
379:         end
380:       else
381:         warn "  update in non-svn dir not supported yet: #{dir}"
382:       end
383:     end
384: 
385:     in_install_dir do
386:       clean.each do |dir|
387:         warn "removing install/#{dir}"
388:         FileUtils.rm_rf dir
389:       end
390:     end
391:   end
update_rubygems() click to toggle source
     # File lib/multiruby.rb, line 393
393:   def self.update_rubygems
394:     warn "  Determining latest version for rubygems"
395:     html = URI.parse(GEM_URL).read
396: 
397:     versions = html.scan(/href="rubygems-update-(\d+(?:\.\d+)+).gem/).flatten
398:     latest = versions.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }.last
399: 
400:     Multiruby.in_versions_dir do
401:       file = "rubygems-#{latest}.tgz"
402:       unless File.file? file then
403:         warn "    Fetching rubygems-#{latest}.tgz via HTTP."
404:         File.unlink(*Dir["rubygems*"])
405:         File.open file, 'w' do |f|
406:           f.write URI.parse(GEM_URL+"/"+file).read
407:         end
408:       end
409:     end
410: 
411:     Multiruby.in_build_dir do
412:       FileUtils.rm_rf Dir["rubygems*"]
413:     end
414: 
415:     Multiruby.in_install_dir do
416:       FileUtils.rm_rf Dir["*"]
417:     end
418:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.