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 programs files are in a subdirectory called lib/, the following might make a good specification file:
# shielding.gemspec require ubygems 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 = zaff@example.com 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 ubygems/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 e 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, youll 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, youll 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. Its 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 youll 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, its a good idea to include that with the RDoc, since thats 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 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[ est/*.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 youve 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
- The Gemspec reference (http://docs.rubygems.org/read/chapter/20)
- Recipe 18.3, "Requiring a Specific Version of a Gem"
- Recipe 18.7, "Distributing Your Gems"
- Recipe 19.4, "Automatically Building a Gem"
Категории