Tired of juggling Ruby gems? Try Rip. It's a one-size-fits-all, no fuss, powerful package manager.
If you work on multiple Ruby projects concurrently, you’re probably accustomed to juggling gems. One project requires one batch of gems; another effort depends on a different set; and a third project utilitizes a specific legacy gem. Thankfully, the Ruby gem system can maintain multiple versions of the same gem in a single repository, making much of this task easy. If you need an explicit version of a gem (or any late model version, such as 3.x), simply install the code you need and name the dependency.
For example, if your code depends on Diamond v1.0.1, you can install that version of the gem with…
$ sudo gem install Diamond -v 1.0.1
… and include the gem with the statement…
gem 'Diamond', '= 1.0.1’
But what if you want to test your code with different versions of the same gem? Worse, what if each variant of the gem depends on multiple versions of other gems? Soon you are wrestling with a morass of interdependencies and no effective technique to enforce and ensure revision locking among any prescribed subset.
One solution is a virtual machine per configuration. Create a base image and create an instance for each permutation. That’s workable, albeit very time-consuming to establish and practice.
Still, the notion is the correct one: Create a virtual environment for each subset of gems and switch quickly and easily to the appropriate environment for each test. A similar notion is equally useful: Create multiple environments and run multiple, complex applications concurrently, each in its own “box.”
A virtual environment is just one feature of the new—as in version 0.0.1—Rip package manager created by Chris Wanstrath and a small team of developers at Github. As the project home page attests, “Rip is an attempt to create a next generation packaging system for Ruby,” and simplifying package interdependencies is a top priority.
Packages Simplified
Inspired by Python’s virtualenv (a virtual environment builder) and pip (an alternative package installer), Rip offers several improvements over Ruby’s native gem package manager.
- Creating and sharing a package is a snap: Add a single file to your source code to make it compatible with Rip. In fact, if your source is a single file, you can use it as is. There is no build step and no need to distribute your package via a dedicated system. If your code is on a local file system or on the Web, it’s ready to share.
- Dependencies are deduced when a Rip package is installed, not when packages run.
- Software can be installed from a variety of sources, including a directory, a single file, a Git repository, and a traditional gem. A source can be local or remote.
- You can create one, some, or many virtual environments and switch from one to another with one command. You can also run any Ruby interpreter in concert with Rip, and can run multiple applications concurrently, each in a given environment.
To be clear, Rip isn’t intended to replace RubyGems. Instead, it’s a supplement and an alternative. Rip does not clobber the gems you already have installed, and it won’t upset an existing Ruby or Rails project.
For example, after a fresh install of Rip on a MacBook running Leopard and the latest version of Xcode, the default Rip environment, base, is empty; while all the previously installed gems (upwards of forty) are still available.
$ rip list
ripenv: base
nothing installed
$ gem list
*** LOCAL GEMS ***
abstract (1.0.0)
actionmailer (2.3.2, 2.1.1, 1.3.6, 1.3.3)
actionpack (2.3.2, 2.1.1, 1.13.6, 1.13.3)
actionwebservice (1.2.6, 1.2.3)
activerecord (2.3.2, 2.1.1, 1.15.6, 1.15.3)
activerecord-oracle_enhanced-adapter (1.2.0)
activeresource (2.3.2, 2.1.1)
activesupport (2.3.2, 2.1.1, 1.4.4, 1.4.2)
...
treetop (1.2.4)
vpim (0.658)
ZenTest (4.0.0)
The former command, rip list catalogs all the available packages in the current environment. gem list performs the same function for the local gem repository.
Rip is (currently) user-specific, and each user can have as many environments as desired. However, only one environment may be active at any time.
Rip maintains its enviroments and configuration metadata in $HOME/.rip. Each environment is implemented as a subdirectory. A special subdirectory, aptly named active, contains the software for the active environment. (The active subdirectory is actually a symbolic link to the current environment.)
Assuming you create environments alpha and beta, install some packages in each environment, and make beta the current environment, your Rip directory might look like this:
.rip/
active -> ~/.rip/beta
alpha/
bin/
lib/
alpha.ripenv
base/
bin/
lib/
base.ripenv
beta/
bin/
lib/
beta.ripenv
rip-packages/
In each environment, bin contains the applications and utilities installed by the packages stored in the environment, while lib contains code. Each eponymous .ripenv file stores information about the environment, including its contents.
Let ’er Rip
Rip is provided as a traditional Ruby gem and installs in seconds. Type sudo gem install Rip.
$ sudo gem install Rip
Building native extensions. This could take a while...
****************************************************
So far so good...
Run `rip check` to be sure Rip installed successfully
NOTE: You may need to source your ~/.bashrc
or start a new shell session.
Get started: `rip -h` or http://hellorip.com/
****************************************************
Successfully installed rip-0.0.1
1 gem installed
Installing ri documentation for rip-0.0.1...
Installing RDoc documentation for rip-0.0.1...
Per the message, run rip check to validate the install.
$ rip check
RIPDIR env variable not found. did you run setup.rb?
If you installed the Rip gem and see the error message above, logout and login anew to sources your shell startup files. One of those files sets the environment variables Rip requires to operate.