Sunday, December 12, 2010

Rails 2.3.8: Upgrading to Bundler

On the way to upgrading an application to Rails 3, I want to try replacing Rails' current gem management system with Bundler. I'll do this by following the Rails 2.3 instructions on the Bundler site.

As always, begin by creating a new branch and switching into it:
$ git branch bundler
$ git checkout bundler

Now we can begin installing Bundler.
First, insert the following code into /config/boot.rb, right above the last line (Rails.boot!):

class Rails::Boot
  def run
    load_initializer

    Rails::Initializer.class_eval do
      def load_gems
        @bundler_loaded ||= Bundler.require :default, Rails.env
      end
    end

    Rails::Initializer.run(:set_load_path)
  end
end

Next, create a new file, config/preinitializer.rb, and insert the following:

begin
    require "rubygems"
      require "bundler"
rescue LoadError
    raise "Could not load the bundler gem. Install it with `gem install bundler`."
end

if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24")
    raise RuntimeError, "Your bundler version is too old for Rails 2.3." +
         "Run `gem install bundler` to upgrade."
end

begin
    # Set up load paths for all bundled gems
      ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
        Bundler.setup
rescue Bundler::GemNotFound
    raise RuntimeError, "Bundler couldn't find some gems." +
          "Did you run `bundle install`?"
end

Then, create the file /Gemfile and copy the following code into it:
source :gemcutter
gem "rails", "~> 2.3.5"
gem "sqlite3-ruby", :require => "sqlite3"

# bundler requires these gems in all environments
# gem "nokogiri", "1.4.2"
# gem "geokit"

group :development do
  # bundler requires these gems in development
  # gem "rails-footnotes"
end

group :test do
  # bundler requires these gems while running tests
  # gem "rspec"
  # gem "faker"
end

I needed to add the gems which are specific to my application, including factory_girl. Furthermore, I use MySQL instead of SQLite, so I'll have to change those lines too. Ultimately, my new Gemfile looksl ike this:

source 'http://rubygems.org'
gem "rails", '2.3.8'
gem 'factory_girl'
gem 'searchlogic'

# bundler requires these gems in all environments
# gem "nokogiri", "1.4.2"
# gem "geokit"

group :development do
  # bundler requires these gems in development
  # gem "rails-footnotes"
end

group :test do
  # bundler requires these gems while running tests
  # gem "rspec"
  # gem "faker"
end


At this point int he Bundler instructions, it ends with "From this point on, you can follow the instructions in the Rails 3 guide" and then the command
$ rake db:migrate

I'm not sure why this is here, as it comes with no explanation. I don't think any migrations have been generated, so I'm not sure why we are supposed to run a migration. Nevertheless, I do it anyway:
$ rake db:migrate

As predicted, nothing happens. Clicking on the link "Learn more: Rails 3" takes us to the Rails 3 installation tutorial, where we are meant to continue following the steps.

At this point, to see if it's working, run bundler from the command line:
$ bundle install

To my astonishment, it works. To test it out, let's add Devise to the Gemfile and see if Bundler can install them:
gem "devise", "1.0.9"

Then from the command line:
$ sudo bundle install

Again, it works. Thanks Rails.

The next step would be to clean up the old code that's no longer needed for gem management. All I can think of is to remove the gem lines from /config/environment.rb by commenting them out:

#RAILS_GEM_VERSION = '2.3.8' unless defined? RAILS_GEM_VERSION
#  config.gem "factory_girl"
#  config.gem "searchlogic"

After restarting the server, everything still works, so I guess it's a successful install of Bundler. Having that out of the way will make the transition to Rails just a little bit easier.

To finish up, we need to commit our changes, merge back into the master branch, and delete the bundler branch:
$ git add .
$ git commit -am "upgraded to Bundler"
$ git checkout master
$ git merge bundler
$ git branch -d bundler

Done.

No comments:

Post a Comment