Hydra - good, Hydra on Heroku - not so good

Hydra is a great tool for Rails development as it can distribute your tests to remote machines.  In my current project, we’re running Ruby 1.9.1 on Rails edge with RSpec 2.0 beta so not everything works right all the time.

The biggest culprit is having Heroku attempt to install our development and test gems.  In particular, if you list gem ‘hydra’ within your Gemfile for Heroku - rake no longer works.  You get a helpful message like this:

%  heroku rake routes --app your-app
(in /disk1/home/slugs/192557_b2246d5_db92/mnt)
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:32: warning: already initialized constant RAKEVERSION
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake/alt_system.rb:32: warning: already initialized constant WINDOWS
WARNING: Possible conflict with Rake extension: String#ext already exists
WARNING: Possible conflict with Rake extension: String#pathmap already exists
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:404: warning: already initialized constant EMPTY_TASK_ARGS
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:452: warning: already initialized constant EMPTY
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:960: warning: already initialized constant RUBY_EXT
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:964: warning: already initialized constant RUBY
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1033: warning: already initialized constant LN_SUPPORTED
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1242: warning: already initialized constant ARRAY_METHODS
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1245: warning: already initialized constant MUST_DEFINE
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1249: warning: already initialized constant MUST_NOT_DEFINE
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1253: warning: already initialized constant SPECIAL_RETURN
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1259: warning: already initialized constant DELEGATING_METHODS
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1569: warning: already initialized constant DEFAULT_IGNORE_PATTERNS
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1575: warning: already initialized constant DEFAULT_IGNORE_PROCS
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1612: warning: already initialized constant FileList
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1638: warning: already initialized constant EARLY
/disk1/home/slugs/192557_b2246d5_db92/mnt/.bundle/gems/gems/rake-0.8.7/lib/rake.rb:1968: warning: already initialized constant DEFAULT_RAKEFILES
rake aborted!
stack level too deep
/disk1/home/slugs/192557_b2246d5_db92/mnt/Rakefile:10:in `<top (required)>'
(See full trace by running task with --trace)

So the fix is to exclude execution of the entire block by Heroku:

source 'http://rubygems.org'

gem 'rails', '3.0.0.beta3'

## snip ##

if RUBY_PLATFORM =~ /darwin/
  group :test do
    gem 'rspec', '2.0.0.beta.11'
    gem 'rspec-rails', '2.0.0.beta.11'
## snip ##
    gem 'hydra', :git => 'git://github.com/ngauthier/hydra.git'
  group :development, :test do
    gem 'wirble'
    gem 'hirb'
    gem 'awesome_print'
    gem 'ruby-debug19'      # does not support 1.9.2
gem 'ruby-debug-ide19'

If you run linux (as I do half the time), then check for this environment variable:

if ENV[“SHELL”] != “/usr/bin/git-shell”

Don't show your cards - defense in depth

I recently went to visit a popular Ruby and Rails website called the Ruby Toolbox at http://www.ruby-toolbox.com/

On my arrival, I had a friendly “Application Segmentation Fault” message.  Even more useful was the stack trace (I bolded the awesome parts):

rails/gem_dependency.rb:119:Warning: Gem::Dependency#version_
requirements is deprecated and will be removed on or after
August 2010.  Use #requirement
** [NewRelic] New Relic RPM Agent 2.11.2 Initialized: pid = 20162
** [NewRelic] Agent Log found in /disk1/home/slugs/127160_40c7b71
>> Thin web server (v1.2.6 codename Crazy Delicious)
>> Maximum connections set to 1024
>> Listening on, CTRL+C to stop
** [NewRelic] Connected to NewRelic Service at collector7.
rails/backtrace_cleaner.rb:25: [BUG] Segmentation fault
ruby 1.8.7 (2009-12-24 patchlevel 248) [x86_64-linux], MBARI
0x6770, Ruby Enterprise Edition 2010.01

Security is about defense in depth.  Not only are you supposed to change your passwords, but you make them hard to guess.  Not only do you check your firewall for open ports, but you make it impossible to have unauthorized applications send packets out.

So needless to say, you pull away a few layers of your security when you spit out folder structure, internal listening port, web server name/version and other product version information.

In the case of Heroku, it’s not exactly a secret that they run that flavor of ruby, rails, and web server.  Though I didn’t know it was those exact versions and that they were running REE.  Still, they shouldn’t advertise it.

Git? Mercurial? Or does your DVCS really matter?

There is much talk on the social networks such as Twitter and Blogs regarding Git over Mercurial and vice-versa.  If you don’t know much about Distributed Version Control Systems (DVCS), you should just browse the home pages of Git and Mercurial then head over to Wikipedia’s entry for DVCS.

Besides rampant personal opinion, there are two good write-ups that I’ve found comparing the two packages.  Neither article is completely accurate but the comments do shed light on the inaccuracies.

Let’s start with Google’s DVCSAnalysis for Google Code.  The main inaccuracy in this document are rebasing support added to Mercurial (which is noted after the point) and the last two bullet point under Mercurial advantages which can be overcome by configuration within git.

The third bullet point under Google’s analysis concerns maintenance of git repositories.  First a little research on why you need to ‘git gc’ which summaries to the need of removing duplicate objects and compacting objects in your git repository.  This is where git’s configurations come into play.  In particular, you can ignore the need for maintenance by running:

git config --global gc.auto 0

The fourth bullet point under Google’s analysis concerns history not being sacred on git repositories.  This can only occur if you force a push.  As noted in the comments, you can run this command on the server to disallow such actions:

git config --system receive.denyNonFastforwards true

The other good write-up I found was by the Python core team when they chose a new source control for the Python project.

They did a great job of writing out scenarios and a sample set of commands for each VCS to compare.  For me, “Backport” looks complicated in git whereas “Separation of Issue Dependencies” looks complicated in anything but git’s stash command.

Their final points conclude three reasons for choosing Mercurial over git.  The first point is an obvious pain point for Windows users of git - there just isn’t any good support for git under Windows.  The other two points are not as applicable to the general developer but you can read the article to see if they apply to you.  For one, I’m not partial to if the underlying software was written in Python or not but, obviously, the Python core team feels differently to use tools written in their language of choice and I can completely understand their position.

In the end, the similarities between the two systems are so profound that it’s my personal belief that both systems are very solid and neither is the wrong choice.  They were both started at the same time (2005) for the same reasons (as a replacement for BitKeeper).  If you need great HTTP support or Windows support, Mercurial is a much easier path.  Git has found good communities in the Linux Kernel and on GitHub.  With the use of Mercurial for Google Code and Microsoft CodePlex, the community around Mercurial is growing and growing fast.  You can’t go wrong with either choice and you’ll probably need to use both if you’re an active developer in the community.

Someone doesn’t have to lose for another to win.

Edit: (2010-04-22) Another great site: http://whygitisbetterthanx.com/

Edit: (2010-04-23) This is the ultimate answer: http://gitvsmercurial.com/

Earlier →