AutoGit: alternative to RubyGems based on Git

Rubygems has a facility of versions. You can write something like this in your code to specify a correct version: gem(“RMagick”, ”=2.0.1”)

But this approach has lots of drawbacks: it takes time to release a new version, especially when you’ve applied an important patch. Sometimes you try to fix it by running your own gemserver, but this adds more complexity and you still have to go through the painful gem publishing routine.

Some folks try to fix it with git submodules: you can connect foreign repository to yours and freeze it to the specific commit or tag. But you still is not very flexible (imagine firewall on a production server or git hosting outage) and you still need to run some command-line commands.

Today I’ve created a simple and elegant solution for dependencies management: zero-configuration package manager AutoGit.

http://github.com/oleganza/autogit/tree/master

It works like charm:

autogit "git://github.com/oleganza/autogit.git", "84b14f0df" 

With AutoGit you can specify a URL of the library and a specific commit (tag) in your ruby source code. It automatically checks whether you have desired code checked out in ~/.autogit folder, clones repositories and creates efficient copies with specific revision checked out.

You don’t have to run any command-line utilities in order to install or update libraries. It also understands a list of URLs as mirrors: if it has no access to first URL (because of firewall restrictions or github.com is down), it uses next one in a list. And when it doesn’t find a commit, it attempts to fetch updates into the local clone, so you never need to do “gem update” or “git fetch” by hand.

AutoGit is a single-file library: you can simply drop it into your application folder and it will just work.

The library is very simple and could be easily extended whenever you need to. The following code shows how a list of gems could be organized for different environments:

sources = %w{
 git://github.com/
 git@localhost:github/
 ~/github/
}
libs = {
 "oleganza/declarations" => "f05be8ca8a77",
 "oleganza/autogit"      => "84b14f0df",
 "rails/rails"           => "2.2.2",
 "yrashk/strokedb"       => "0.2.1" 
}

libs.each do |path, commit|
 autogit(sources.map{|s| s + path }, commit)
end

Posted on January 30, 2009 by Oleg Andreev - permalink

Add your comment

iPinWheel, an iPhone Application for Kids and grown ups... Pierlis sponsors the "Railscamp Paris 2" event