Today we will create gemsets management stuff and we'll also make Ruby management easier. As previously, lets start from "low-level" bash scripts. Place them somewhere in your app (example: app_root/sript/tasks/rvm) and make them executable (chmod 755).
List available gemsets from a selected Ruby
#!/bin/bash
# Returns list of selected ruby gemsets
# Requires ruby version as parameter
#
# Example: ./rvm_gemset_list.sh 1.9.2-p0
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -gt 0 ] || die "Minimum 1 parameter required! $# provided"
ruby_version="$1"
init_rvm(){
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
fi
}
perform_task(){
init_rvm
rvm use $ruby_version > /dev/null
rvm gemset list
}
perform_task
Creating gemset in selected Ruby
#!/bin/bash
# Creates gemset in a given Ruby version
# Parameters:
# 1) Ruby version
# 2) Gemset name
#
# Example: ./rvm_gemset_list.sh 1.9.2-p0 example_gemset
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -gt 1 ] || die "Minimum 2 parameters required! $# provided"
ruby_version="$1"
gemset_name="$2"
init_rvm(){
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
fi
}
perform_task(){
init_rvm
rvm use $ruby_version > /dev/null
rvm gemset create $gemset_name
}
perform_task
Removing gemset from selected Ruby version
#!/bin/bash
# Returns list of selected ruby gemsets
# Parameters:
# 1) Ruby version
# 2) Gemset name
#
# Example: ./rvm_gemset_list.sh 1.9.2-p0 example_gemset
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -gt 0 ] || die "Minimum 1 parameter required! $# provided"
ruby_version="$1"
gemset_name="$2"
init_rvm(){
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
fi
}
perform_task(){
init_rvm
rvm use $ruby_version > /dev/null
rvm --force gemset delete $gemset_name
}
perform_task
Creating RVM class
Ok, so we can now install/uninstall Rubies and create/destroy gemsets. Let's wrap it with some Ruby magic! We'll start from creating RVM class. It will represent RVM in our application:
class RVM
class RVMNotInstalled < StandardError; end
# Check if RVM is installed
def self.installed?
c = Script.new('rvm/list')
res = c.run
!res.include?('nie znale') && !res.include?('not f')
rescue
false
end
def self.check_for_rvm
raise RVMNotInstalled unless self.installed?
end
end
If RVM is not installed running list script will return something like "command not found". Thanks to this, we can check whether or not RVM is installed.
Let's make things better!
Ok, now the better stuff. Ruby stuff :) Each Ruby instance should have it's own representation in our application (not in AR - will wrap it with AR in next part of this tutorial):
class RVM
class Ruby
class UnknownRubyVersion < StandardError; end
class GemsetAlreadyExists < StandardError; end
class GemsetDoesNotExist < StandardError; end
class RubyVersionAlreadyInstalled < StandardError; end
attr_reader :version
attr_accessor :gemset
end
end
Exceptions description:
- UnknownRubyVersion - will be raised when trying ti install/uninstall unknown (not existing) Ruby version
- GemsetAlreadyExists - when trying to install gemset which already exists
- GemsetDoesNotExist - when trying to remove non existing gemset
- RubyVersionAlreadyInstalled - when trying to install already installed Ruby version
Install/Uninstall Ruby
Now methods from RVM::Ruby:
class RVM
class Ruby
def self.install(ruby, log_path, lock_id)
raise RubyVersionAlreadyInstalled, ruby if self.list.include?(ruby)
raise UnknownRubyVersion, ruby unless self.known.include?(ruby)
c = Script.new('rvm/install', ruby, log_path, lock_id)
c.ignite
end
def self.uninstall(ruby, log_path)
raise UnknownRubyVersion, ruby unless self.list.include?(ruby)
c = Script.new('rvm/uninstall', ruby, log_path)
c.run
end
end
end
Other helpful class methods
class RVM
class Ruby
def self.selected
RVM.check_for_rvm
c = Script.new('rvm/list')
list = c.run
#list.delete!('rvm rubies')
list = list.split("\n")
selected = false
list.each do |ruby|
selected = ruby.delete('=> ').strip if ruby.include?('=> ')
end
selected.split('[').first
end
# Returns list of rvm rubies installed
def self.list
RVM.check_for_rvm
c = Script.new('rvm/list')
list = c.run
#list.delete!('rvm rubies')
list = list.split("\n")
rubies = []
list.each do |ruby|
ruby = ruby.delete('=> ').strip
next if ruby == 'rvmrubies' || ruby == ""
rubies << ruby.split('[').first
end
rubies
end
# Returns list of known rubies
def self.known
RVM.check_for_rvm
c = Script.new('rvm/known')
list = c.run
rubies = []
list.split("\n").each do |r|
next if r.include?('#')
next if r.include?('iron')
next if r.include?('macruby')
next if r == ''
r+='-head' unless r.include?('-')
rubies << r.strip.delete('[').delete(']')
end
rubies
end
end
end
RVM::Ruby Instance methods
Ok, so now we have a bunch of useful class methods, however we still cannot manipulate on a single Ruby instance stuff such as gemsets. But, not for long. Lets start with initialization of an RVM::Ruby instance:
def initialize(ruby, gemset = nil)
RVM.check_for_rvm
@version = ruby
@gemset = gemset
raise UnknownRubyVersion, ruby unless self.class.list.include?(ruby)
if @gemset
raise GemsetDoesNotExist, @gemset unless gemsets.include?(@gemset)
end
end
Now it is time for gemsets management:
# Show all gemsets available in this ruby version
def gemsets
c = Script.new("rvm/gemsets", version)
list = c.run
list = list.split("\n")
gemsets = []
list[1..-1].each do |g|
next if g.include?('gemsets for')
g.delete!('=> ')
gemsets << g.strip
end
gemsets
end
def gemset_selected
unless @gemset
c = Script.new("/rvm/gemsets", version)
list = c.run
list = list.split("\n")
selected = nil
list[1..-1].each do |g|
next if g.include?('gemsets for')
selected = g.strip if g.include?('=> ')
end
@gemset = selected
end
@gemset
end
def create_gemset(name)
raise GemsetAlreadyExists, name if gemsets.include?(name)
c = Script.new("rvm/gemset_create", version, name)
c.run
true
end
def delete_gemset(name)
raise GemsetDoesNotExist, name unless gemsets.include?(name)
c = Script.new("rvm/gemset_delete", version, name)
c.run
true
end
and one additional method:
def full_name
"#{version}@#{gemset}"
end
That's all for now! Managing RVM stuff now is much easier, for example we can do something like this:
RVM::Ruby.install('ruby-1.9.2-head', '/var/log/ruby_install.log', 1234)
# wait till installation ends
ruby = RVM::Ruby.new('ruby-1.9.2-head')
ruby.create_gemset('my_gemset')
Tutorial parts
- RVM Ruby version management directly from… Ruby
- Handling Rubies and gemsets management easier (from Ruby)