1. rails-upgrade: Automating a portion of the Rails 3 upgrade process

    If you’re looking for more info on upgrading, don’t miss out on my other posts on Rails 3 starting here.

    NOTE: This is now an official, blessed plugin, so use that rather than this gem. More info here.

    I’ve been playing with upgrading some apps to Rails 3 (some open-source, some not), and I’ve sort of gotten some of the process down to a science. So what does a developer do when something is down to a process? Automate!

    I’ve created a (pretty hacky) gem named rails-upgrade (installable by a simple gem install rails-upgrade) to automate some of the more annoying parts of the upgrade from Rails 2.x to Rails 3. So far, it has three parts…

    Find out what parts need to be upgraded

    I’ve assembled a battery of checks to run on your app for obvious things that need to be upgraded. To get a report, simply run this in a Rails root:

    rails-upgrade check

    It checks over some things, then generates a report like this:

    named_scope is now just scope
    The named_scope method has been renamed to just scope.
    More information: http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914
    The culprits: 
        - app/models/group.rb
        - app/models/post.rb
    Deprecated ActionMailer API
    You're using the old ActionMailer API to send e-mails in a controller, model, or observer.
    More information: http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3
    The culprits: 
        - app/controllers/application.rb
        - app/controllers/feedback_controller.rb
    Old ActionMailer class API
    You're using the old API in a mailer class.
    More information: http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3
    The culprits: 
        - app/models/post.rb
        - app/models/user.rb

    It shows and explains the issue, where to get more information on it, and which files the issue was found in. It checks a lot more than that report shows (e.g., looks for old generators, busted plugins, environment.rb conversion requirements, old style routes, etc.). It doesn’t cover everything 100% probably, but I’ve found it’s great for quickly identifying some low hanging fruit in upgrading.

    Upgrading routes

    The gem will also upgrade your routes as best it can. To generate a new routes file, simply run this inside of a Rails application:

    rails-upgrade routes

    I’ve tested it on some quite complicated routes files and it did fine, but it does have some minor quirks (i.e., it flattens with_options blocks currently…that might change if I feel like putting the effort into it…or if one of you patches it :). It takes a routes file like:

    ActionController::Routing::Routes.draw do |map|
      map.resources :posts, :collection => {:drafts => :get, :published => :get}
      map.login  '/login',  :controller => 'sessions', :action => 'new'
      map.logout '/logout', :controller => 'sessions', :action => 'destroy'
      map.connect '/about', :controller => 'static', :action => 'about'
      map.connect ':controller/:action/:id.:format'
      map.connect ':controller/:action/:id'

    And makes a new one like this:

    YourApp::Application.routes do
      resources :posts do
        collection do
          get :drafts
          get :published
      resources :users
      resources :groups
      resources :pictures
      match '/login' => 'sessions#new', :as => :login
      match '/logout' => 'sessions#destroy', :as => :logout
      match '/about' => 'static#about'
      match '/:controller(/:action(/:id))'

    The formatting isn’t quite this nice when it comes straight out of the script (I’m working on that), but you get the idea. I’m still tweaking/adding things to this script, but as far as I know it supports every feature of the Rails 2.x router. Fixing the formatting bugs are my first priority, simply because they’re really annoying.

    Creating Gemfiles

    The last piece is a Gemfile generator; it takes your config.gem directives and generates a nice Gemfile (even including the required Rails stuff). To run it, simply execute:

    rails-upgrade gems

    That will take an environment.rb with these config.gem calls:

    config.gem "bj"
    config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
    config.gem "sqlite3-ruby", :lib => "sqlite3"
    config.gem "aws-s3", :lib => "aws/s3"

    And generate this Gemfile:

    # Edit this Gemfile to bundle your application's dependencies.
    # This preamble is the current preamble for Rails 3 apps; edit as needed.
    directory "/path/to/rails", :glob => "{*/,}*.gemspec"
    git "git://github.com/rails/arel.git"
    git "git://github.com/rails/rack.git"
    gem "rails", "3.0.pre"
    gem 'bj', 
    source 'http://code.whytheluckystiff.net'
    gem 'hpricot', '0.6'
    gem 'sqlite3-ruby', :require_as=>"sqlite3"
    gem 'aws-s3', :require_as=>"aws/s3"

    Then it’s just as simple as gem bundle. Again, I’ve tested this on some fairly complex sets of gem requirements, so it should stand up to most sets.

    If you find a bug or want to expand the checks and upgrade scripts or, like, add some tests (please do!), then hit it up on Github, fork it, and send me a message. If you want to simply install the gem and run it, then just run gem install rails-upgrade then rails-upgrade <whatever> inside the Rails application directory.

    NOTE: This is now an official, blessed plugin, so use that rather than this gem. More info here.

    If you’re looking for more info on upgrading, don’t miss out on my other posts on Rails 3 starting here.


Powered by Tumblr; designed by Adam Lloyd.