Installing and Creating Standalone Packages with setup.rb

Problem

You want to install a Ruby package that includes a setup.rb script instead of being packaged as a Ruby gem. Or, you want to make it possible for people to install your software package without having to install Ruby gems.

Solution

To install a setup-rbbased Ruby package as root or the administrative user, simply run the setup.rb script:

$ ruby setup.rb

By default, setup.rb installs a package into your site_ruby directory. If you don have root access or only want to install the package for your own use, you can install the package into your home directory, like this:

$ ruby setup.rb all --installdirs=home

That command installs the package into the lib/ruby/ subdirectory of your home directory. Make sure you have that directory included in your RUBYLIB environment variable, or Ruby won know to look there when you require a library. You can check your library path with the special $: global variable:

$: # => ["/home/leonardr/lib/ruby", "/usr/local/lib/site_ruby/1.8", … ] require installed_via_setup # => true

Discussion

Because Ruby gems are not yet part of the standard Ruby library, some people prefer to package their software releases as self-contained archives. A package that includes a setup.rb installation script contains all the code and data necessary for installation; it might have dependencies, but it doesn rely on another component just to get itself installed. The rubygems package itself is installed via setup.rb, since it can assume that the system already supports gem-based installations.

You might also use a setup.rb script instead of a Ruby gem if you want to add Ruby hook scripts to the installation procedure. For instance, you might want to create a new database when your package is installed. Once the Rubygems package is included in the Ruby standard library, this will be just about the only reason left not to package all your software as Ruby gems. Even native C extensions can be included in a Ruby gem and built as part of the gem installation.

Ruby gems and setup.rb impose similar file structures on your package: your Ruby libraries go into a lib/ subdirectory, command-line applications go into a bin/ subdirectory, and unit tests go into a tests/ subdirectory.

To use setup.rb, simply arrange your package to conform with its file stucture, and copy the setup.rb file itself into the top-level directory of your package.

setup.rb works kind of like a Unix Makefile: it has various tasks like test, clean, install, and all that are triggered when the user runs setup.rb with certain options. You can put a pre- or post-hook into any task by creating a Ruby script called "pre-[task].rb" or "post-[task].rb". All such files will be run before or after the appropriate task.

Heres a simple example. Ive created a small package with the following layout:

setup.rb post-clean.rb lib/ lib/installed_via_setup.rb lib/pre-config.rb bin/ bin/command.rb

Ive got a library, a command-line script, a hook script pre-config.rb that needs to run before the config task, and a second hook script post-clean.rb that needs to run after the clean task. The hook scripts simply print out the messages "Pre-config hook called" and "Post-clean hook called".

When I run the clean task, with the command ruby setup.rb clean, I see the following output:

$ ruby setup.rb clean ---> bin <--- bin ---> lib <--- lib Post-clean hook called. rm -f .config rm -f InstalledFiles

When I run setup.rb without specifying a task, I see the following output:

$ ruby setup.rb … Pre-configuration hook called. … rm -f InstalledFiles ---> bin mkdir -p /usr/bin/ install command.rb /usr/bin/ <--- bin ---> lib mkdir -p /usr/local/lib/site_ruby/1.8/ install installed_via_setup.rb /usr/local/lib/site_ruby/1.8/

My command-line program gets installed into /usr/bin/, and my library file into site_ruby. The preconfiguration hook script gets called because the default task, all, simply runs three other tasks: config (TRiggering the hook script), setup, and install.

Once Ive run ruby setup.rb, I am free to require installed_via_setup from within any Ruby program, and to invoke command.rb from the command line.

Theres no easy way to uninstall a package installed with setup.rb; you need to delete the files manually.

One final thing to watch out for: standalone Ruby packages created before about 2004 may be installed via a script called install.rb. This script works much the same way as setup.rb. The two scripts were both written by Minero Aoki and are both part of the setup.rb package, but install.rb was intended for smaller-scale installations. As of late 2003, the two scripts were merged, so now you only have to worry about setup.rb.

See Also

Категории