Hosting My Own Ruby Gems Repository
What Is A Gem Repository?
For people not familiar with Ruby, a gem is a code package (a sort of zip file) containing all Ruby source files and resources for a given application or library.
Gems are typically stored in hosted repositories like RubyForge, GemCutter, or GitHub so that applications and libraries can be shared on the Internet. However anyone can create a repository to host gems as long as the repository conforms to the structure and indexing defined by RubyGems the Ruby package manager.
In the past I have used RubyForge as a co-maintainer of the ruby-paypal library and I have used GemCutter as well.
So why would I want to create my own repository?
Well, I am hosting some Ruby apps on Heroku which requires you to specify where your external gems come from. This is nice as you can specify a RubyForge, GemCutter, GitHub or any repository for that matter. However as gems evolve, sometimes older version do not remain available on these repositories. Rails has solved that problem by freezing the gems in its own vendor directory. But if you use another framework (like Camping for me, or Sinatra for others), you need a place to freeze your dependencies. So creating and hosting your own repository gives you that flexibility to control which versions of external gems you need.
Creating the repository
So I followed instructions from the gem repository creation manual. But everytime I would run the command, RubyGems would not find any gems. So I started to browse the code for Gem::Indexer and wrote a few lines of code to do the indexing from irb launched from your host destination (the one above ./gems):
require 'rubygems' require 'rubygems/indexer' i=Gem::Indexer.new '.' i.generate_index
And if you want to update the index later:
require 'rubygems' require 'rubygems/indexer' i=Gem::Indexer.new '.' i.update_index
I suspect the issue with the gem command must exist somewhere higher at the command parsing level but I have not looked into it (I just wanted to create my repository and move on).
Once I ran the commands, several files were created, but the most important one is the yaml file which represents the definition of the repository index. It contains a description of all the gems in your repository.
Sourcing Your Gems
So now in my .gems file for Heroku I can specify that a given gem comes from my repository using a statement like:
anexternalgem --source http://gems.monnet-usa.com
So What?
Now these gems are frozen. I can now regain control over when I want to update to a later version of that gem.
RubyGems is a very powerful packaging system and like so many Ruby components provides a lot of flexibility.