Packaging Your Code as a Gem






Packaging Your Code as a Gem

Problem

You want to package a program you wrote as a Ruby gem, possibly to distribute it on the main gem server at rubyforge.org.

Solution

First, you must write a specification file. This file consists of a few lines of Ruby code that instantiate a Gem::Specification object and populate it with information about your program. Assuming that all of your program's files are in a subdirectory called lib/, the following might make a good specification file:

	# shielding.gemspec
	require 'rubygems'
	spec = Gem::Specification.new do |spec|
	  spec.name = 'shielding'
	  spec.summary = 'A library for calculating the strength of duophasic shielding'
	  spec.description = %{This library calculates to high precision the
	  physical and electrostatic strength of a duophasic shield. It knows
	  about most real-world shield configurations, as well as many
	  theoretical arrangements not yet built.}
	  spec.author = 'Bob Zaff'
	  spec.email = '[email protected]'
	  spec.homepage = 'http://www.example.com/software/shielding/'
	  spec.files = Dir['lib/*.rb']
	  spec.version = '1.0.0'
	end

You can then use the gem build command to create the actual gem from its specification file:

	$ gem build shielding.gemspec
	Attempting to build gem spec 'shielding.gemspec'
	  Successfully built RubyGem
	  Name: shielding
	  Version: 1.0.0
	  File: shielding-1.0.0.gem

	$ ls
	shield.gemspec shielding-1.0.0.gem

Then install the gem normally:

	$ gem install ./shielding-1.0.0.gem
	Attempting local installation of './shielding-1.0.0.gem'
	Successfully installed shielding, version 1.0.0
	Installing RDoc documentation for shielding-1.0.0…
	WARNING: Generating RDoc on .gem that may not have RDoc.

You can also build a gem from within Ruby code by passing the completed Gem::Specification into a Gem::Builder object.

	require 'rubygems/builder'
	builder = Gem::Builder.new(spec).build
	# Successfully built RubyGem
	# Name: shielding
	# Version: 1.0.0
	# File: shielding-1.0.0.gem
	# => "shielding-1.0.0.gem"

Gem::Builder is useful as a starting point for automating your releases, but if you're interested in doing that, you should use Rake (see Chapter 19, especially Recipe 19.4).

Discussion

Other recipes in this chapter query gem repositories for information and get it back in the form of Gem::Specification objects. To create your own Ruby gem, you need to create a Gem::Specification object from scratch. A file that defines a Gem::Specification object is called a "gemspec" and it usually has a .gemspec extension.

To make a Gem::Specification object that can be turned into a gem, you must define the four attributes name, summary, version, and files. The version attribute should be a string of the form "[major version].[minor version].[revision]"; this is the recommended form for version numbers of software products packaged as gems (see Recipe 18.3).

I recommend you also define author, email, description, and possibly homepage. The description attribute advertises your gem, and the other three attributes give a way for your users to get in touch with you.

Some other tips on creating your gemspec:

  • If you want a user to be able to require a file from their own Ruby code, put it into the lib/ subdirectory of your project. If you put it into some other directory, you'll need to add the name of that directory to the require_paths attribute.

  • If you want a user to be able to run a file as a Ruby script, put it into the bin/ subdirectory of your project. If you put it into some other directory, you'll need to change the bindir attribute.

  • If the code in your gem has associated unit tests, put the names of the test files into an array as the test_files attribute. It's also a good idea to keep those files together in a test/ subdirectory. Once the gem is installed, you can run its tests by issuing the command gem check-t [gem name]

  • Ruby automatically generates a set of RDoc HTML pages for all the Ruby classes and files in your gem. Unless you set the has_rdoc attribute, when you install the gem you'll get a "WARNING: Generating RDoc on .gem that may not have RDoc."

    You can take advantage of the RDoc generation by linking nonRDoc files from the RDoc site: just name those files in the array extra_rdoc_files. If your gem comes with a README file or other nonRDoc documentation, it's a good idea to include that with the RDoc, since that's where most people will look first for documentation.

  • The files attribute should be an array that includes every file you want to be packaged in the gem. If you included any files in test_files or extra_rdoc_files, you must include them again here or they won't actually be installed. The simplest way to do this is to define files last of all, and stick test_files and extra_rdoc_files inside:

    	spec.test_files = Dir['test/*.rb']
    	spec.extra_rdoc_files = ['README']
    	spec.files = Dir['lib/*.rb'] + spec.test_files + spec.extra_rdoc_files
    

  • If your gem requires another gem to work, the spec file is where you define the dependency. Use the Gem::Specification#add_dependency method rather than modifying the dependencies attribute directly. The add_dependency method accepts an optional version restriction, in a format that should be familiar to you if you've read other recipes in this chapter. You can use a version restriction to make sure your gem is only used with certain versions of another gem.

    	spec.add_dependency('another_gem')
    	spec.add_dependency('yet_another_gem', '~> 3.0')
    	# Any version will do.
    	# Must be 3.0.x series.
    

See Also



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows