Skip to content

Instantly share code, notes, and snippets.

@pete
Created July 20, 2011 23:06
Show Gist options
  • Save pete/1096147 to your computer and use it in GitHub Desktop.
Save pete/1096147 to your computer and use it in GitHub Desktop.
Awk script to install Ruby.
#!/usr/bin/awk -f
# Assuming no Ruby installation, gets and installs Ruby, Rubygems (if 1.8), and
# bundler and isolate (latest versions). If your OS is detected as Debian (or
# Ubuntu), the prerequisites for compiling Ruby will be installed. Other OS's
# either aren't supported, don't need this script, or perhaps I didn't consider
# them.
# If you pass -h, help, -help, or --help, you'll get some helpful info about how
# to control the script.
# This script, in awk, really doesn't do awk justice. Highly recommended
# language. You can learn it in a few hours and it's so much fun, you might go
# blind. Here, have some links:
# An Awk Primer: http://en.wikibooks.org/wiki/An_Awk_Primer
# "Awk is a boon":
# http://www.think-lamp.com/2008/10/awk-a-boon-for-cli-enthusiasts/
# The C2 Page on awk: http://c2.com/cgi/wiki?AwkLanguage
# The mawk man page: http://invisible-island.net/mawk/manpage/mawk.txt
# I'd put this up as a gist before, but had forgotten to log in (so it was
# anonymous and didn't show up in the list of gists I had made, and so I had
# issues finding it) and had not included an indicator that it's been put into
# the public domain. Rectifying that:
# Pete Elmore, May 2011. Public domain.
BEGIN {
# Config:
DefaultVersion = "1.9.2-p180"
BuildDir = "/tmp/manyruby"
DestDir = "/opt/rubies"
RubygemsVersion = "1.7.2"
# End Config
# You wanna emulate rvm, just put BuildDir and DestDir somewhere in
# your home directory.
version = ENVIRON["RB_VERSION"]
builddir = ENVIRON["RB_BUILDDIR"]
destdir = ENVIRON["RB_DESTDIR"]
gemversion = ENVIRON["RB_GEMVERSION"]
if(!version)
version = DefaultVersion
if(!builddir)
builddir = BuildDir
if(!destdir)
destdir = DestDir
if(!gemversion)
destdir = DestDir
for(i in ARGV) {
if(ARGV[i] ~ /-?-?h(elp)?/) {
print_help()
exit
}
}
if(!skip_prereqs()) {
if(is_debian()) {
run_debian_cmds()
} else {
print "Don't know how to install prereqs for your OS."
print "Feel free to add is_$youros() and " \
"run_$youros_cmds() to this if/else section."
}
}
old_destdir = destdir
destdir = destdir "/" version
f = ruby_fname(version)
try_mkdir(builddir)
maybe_fetch(builddir, f, ruby_url(version))
unpack_in(builddir, f)
build(version)
# pre-1.8: You get no gems.
if(majmin(version) == "1.8") {
print "Ruby 1.8 detected, going to also install RubyGems."
maybe_fetch(builddir, gems_fname(gemversion),
gems_url(gemversion))
unpack_in(builddir, gems_fname(gemversion))
install_gems(builddir "/rubygems-" gemversion)
}
# I can't seem to get pre-1.8 this far without extmk.rb segfaulting
# (possibly a gcc issue, possibly a 64/32-bit issue), so, hey, I'm not
# going to care. 1.0-971225 wouldn't even *build*. Fie!
install_initial_gems(destdir "/bin/gem")
print "All set! To use Ruby " version ", do this in your shell:"
print "\texport PATH=\"" destdir "/bin:$PATH\""
}
function print_help() {
print "** ManyRuby **"
print "A simple script that doesn't require ruby, and will fetch and "\
"install available"
print "versions of ruby for your enjoyment."
print "Options are all envvars; argv is ignored unless you ask for " \
"help."
print ""
print "Influential environment variables:"
print "RB_VERSION: The Ruby Version to install (default " \
DefaultVersion ")"
print "RB_BUILDDIR: The dir to use for building packages (default " \
BuildDir ")"
print "RB_DESTDIR: The destination prefix for Ruby. (default " \
DestDir "/$RB_VERSION)"
print "SKIP_PREREQS: Set if you wish the script to *not* try to " \
"install things that"
print " are needed to build Ruby."
print ""
print "To automatically jump around, add this to your ~/.bashrc:"
print "\tuse-ruby () {"
print "\t\tif [ ! -x " destdir "/$1/bin/ruby ]; then"
print "\t\t\tRB_VERSION=$1 manyruby"
print "\t\tfi"
print "\t\tPATH=\"" destdir "/$1/bin:$PATH\""
print "\t}"
print "That'll allow you to type 'use-ruby 1.8.7-p334', which will " \
"build and install"
print "it if needed, and will set your $PATH to make it the default."
print "(If you know how to change your shell from bash to whatever, " \
"I'll wager you"
print "know how to do the equivalent in your shell of choice.)"
}
function skip_prereqs() {
return !!ENVIRON["SKIP_PREREQS"]
}
# The is_$os and run_$os_cmds functions are for checking if an OS is $os and
# running some commands on it as prereqs if it is.
# Debuntu is where I've used this script the most, but most of the
# distributions I use do a nice job with Ruby, so there's not a lot of data on
# where I use this script the most.
function is_debian() {
return !system("which apt-get >/dev/null 2>/dev/null")
}
function run_debian_cmds() {
cmd = "apt-get install gcc libz-dev libreadline6-dev"
"id -u" | getline uid
if(uid ~ /^0$/)
cmd = "sudo " cmd
try_cmd(cmd, "Couldn't run " cmd)
}
function ruby_fname(version) {
# 1.6 and before were not available as .tar.bz2, so we default to tgz.
# Not that 1.6 will actually compile for me, but I don't know that it
# won't for you.
return "ruby-" version ".tar.gz"
}
function gems_fname(version) {
return "rubygems-" version ".tgz"
}
function majmin(version) {
match(version, /^[0-9]+\.[0-9]+/)
return substr(version, RSTART, RLENGTH)
}
function ruby_url(version) {
return("ftp://ftp.ruby-lang.org/pub/ruby/" majmin(version) \
"/" ruby_fname(version))
}
function gems_url(version) {
return("http://production.cf.rubygems.org/rubygems/" \
gems_fname(version))
}
function fetch(dir, url) {
try_cmd_in(dir, "wget " url, "Couldn't wget " url)
}
function maybe_fetch(dir, fname, url) {
if(!exists(dir "/" fname))
fetch(dir, url)
else
print "Already have " fname ", not wgetting..."
try(exists(dir "/" fname), "wget failed? Can't find " dir "/" fname)
}
function exists(fname) {
return !system("stat " fname ">/dev/null")
}
function unpack_in(dir, fname) {
if(fname ~ /\.tar\.bz2$/)
targs = "xvjf"
else if(fname ~ /\.(tar\.gz|tgz)$/)
targs = "xvzf"
try_cmd_in(dir, "tar " targs " " fname, "Couldn't unpack " fname)
}
function fatal(mesg) {
print mesg > "/dev/stderr"
exit 1
}
function try(pred, mesg) {
if(!pred)
fatal(mesg)
}
function system_in(dir, cmd) {
return system("cd " dir "; " cmd)
}
function build(version) {
dir = builddir "/ruby-" version
try_mkdir(destdir)
try_cmd_in(dir, "./configure --prefix=" destdir, "./configure failed!")
# Various versions of ruby behave badly if you use parallel make.
try_cmd_in(dir, "make -j1", "Couldn't make ruby!")
try_cmd_in(dir, "make install",
"Couldn't install ruby into " destdir "!")
}
function install_gems(dir) {
try_cmd_in(dir, destdir "/bin/ruby setup.rb",
"Couldn't install rubygems!")
}
function install_initial_gems(gemcmd) {
if(system(gemcmd " install bundler isolate"))
print "Couldn't install one of bundler or isolate. This isn't"\
"considered fatal." > "/dev/stderr"
}
function try_cmd_in(dir, cmd, msg) {
print "Running in " dir ": " cmd
try(!system_in(dir, cmd), msg)
}
function try_cmd(cmd, msg) {
print "Running: " cmd
try(!system(cmd), msg)
}
function try_mkdir(dir) {
try(!system("mkdir -p " dir), "Couldn't mkdir " dir "!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment