Creating and Distributing your own gem: a quick rundown

Here's a quick rundown of how I was able to generate a gem from scratch and release it using github. There are 2 gems that are most commonly used for writing new gems: newgem and hoe. The pros/cons of these 2 gems could be another blog post, I recommend newgem for starters.

Install required gems

gem install --no-ri --no-rdoc newgem rubigen cucumber hoe

No surprises there. (I used cygwin on windows, worst of all supported platforms for ruby .. well, may be not, it is better than native windows support. So most folks shouldn't face any problem :-) )

create your gem

newgem <gemname>

This creates necessary directory structure, adds a few basic files including Manifest, History, README and most importantly a Rakefile. The rake file is important because it has a few rake tasks for packaging and releasing gem.

At this point, fix your README.rdoc with specifications about your gem: stuff like description, example, homepage, developers involved etc. 'newgem' internally depends on 'hoe'. An instance of Hoe class is used to configure Gem specification. This is also the place to define your gem's dependency which any serious gem will need to populate properly.

Fill your gem
Basically copy/write your reusable code/tests etc. The rake file is helpful for executing tests. If any releasable file was added/removed, manifest file needs to be updated.

rake manifest

This, however, didn't work for me in my environment. I ended up using following crude approach.

find . -type f | egrep -v "(.git\/|nbproject\/|pkg\/|script\/|\.gitignore$|\.gem$)" | sed 's/\.\///g' > Manifest.txt

Test your gem
Generate gem, install gem locally and try it out:

rake package, gem install pkg/<gem>-<version>.gem

Share gem publicly from github

The default source for gems is rubyforge. However, my little experience says that releasing gems on github is much easier. Besides being easier and faster to setup project space, it packages the gem on-the-fly when you modify your code :-) So, here we go:

* Get an account on github and setup ssh key stuff
* create repository on github, go to edit page and enable "RubyGem" checkbox. This indicates the the codebase you are uploading to github server is a gem codebase.
* On local machine, add github as remote tracking git repository

git remote add github git@github.com:<git-login>/<gem>.git

If you analyze this command carefully, you'll notice that git uses single login for all projects. It identifies each user and his/her repo by the login/gem.git identifier. The question remains, how does it authorize the user then? The answer lies an additional step that sets your global github related git settings.

Add github related global configs using following commands.

git config --global github.user [your-github-login]
git config --global github.token [your-github-token]

You can obtain your token from your account page after you login.

Another point: Here, I called my github remote repo: github. If github is going to be your primary gitserver, you are probably better off calling it "origin" (command: git remote add origin git@github.com:<git-login>/<gem>.git
* Generate a .gemspec file in the root of pushed codebase.

rake gemspec

This will transform Gem specification defined as an instance of Hoe object in your rake file among other things and generate a <gem>.gemspec file. It is necessary for the gemspec file to be at the root of codebase that is pushed to github, this is the file that git uses to package your codebase into a gem on-the-fly.
* At this point, we are ready to push the codebase to github. However, it is wise to make sure our gem still builds fine using the new gemspec file.

gem build [gem].gemspec

* Push the code to github.

git push github master

Verify your online github project page to see if your files are uploaded properly. Your README.rdoc should be rendered in proper redcloth format at this point.

OK, so when does the gem actually get built? github starts working on it if it finds all necessary things it needs, a properly configured gemspec file for one. And it takes a few minutes (4-6 in my case) for the gem to actually get generated and added to official github index file.

* verify gem is available to the world

gem list -r --source http://gems.github.com | grep [your-git-login]

In above, you have to specify --source option since github is not the default gem server. If you end up using github for installing gems a lot, you can add it as another source as follows:

gem sources -a http://gems.github.com

Related posts:

  1. Installing Edge Ferret/acts_as_ferret
  2. git how to: ignoring files in git
  3. Keeping Up With The Joneses: Keeping Rails and its extensions up to date
  4. Managing vs Creating Test Data
  5. Project Website Part 5: Morph in 11 steps or so

Comments: 4 so far

  1. I’ve felt the same pain as you when creating Ruby gems that I want to distribute. I liked newgem for a while since it didn’t include as much cruft as either hoe or bones (when using the –simple option), but it still felt a little too heavyweight for me.

    Since then, I set out to write a small command-line utility that would do the basics of building a gem directory structure that fit my needs and allow me to easily push to GitHub. I call it “simple-gem”:

    $ sudo gem install reagent-simple-gem –source=http://gems.github.com
    $ simple-gem my_gem

    Assuming that you’re using GitHub for code hosting, you just need to generate the gemspec and push:

    $ cd my_gem
    $ rake github
    $ git add . && git commit -m “Updated gemspec” && git push origin master

    More info is available on GitHub:

    http://github.com/reagent/simple-gem/tree/master/README.rdoc

    Comment by Patrick Reagan, Monday, January 12, 2009 @ 3:22 pm

  2. [...] Creating and Distributing your own gem: a quick rundown [...]

    Pingback by Ennuyer.net » Blog Archive » 2009-01-13 - Today’s Ruby/Rails Reading, Tuesday, January 13, 2009 @ 11:06 am

  3. Patrick, thanks for stopping by. Correct, there are a few quirks with both, newgem and hoe. I also don’t like that they create a runtime dependency on themselves eventhough generated gem do not need them. Do they? I hope, your gem doesn’t create a dependency on itself ;-) And, I also like the github task that you provided. Will try it out. Thanks.

    Comment by Sharad Jain, Tuesday, January 13, 2009 @ 10:41 pm

  4. Good article, Thanks

    Comment by Akhil Bansal, Wednesday, January 14, 2009 @ 12:56 pm

Leave a comment

Powered by WP Hashcash

Launch: Pathfinder Newsletter

    Get a monthly update on best practices for delivering successful software.

    Subscribe via email


    Subscribe via RSS      RSS icon

Topics

Search

WordPress

Comments about this site: info@pathf.com