Err the Blog Atom Feed Icon
Err the Blog
Rubyisms and Railities
  • “Auto-Patch Rails”
    – PJ on January 08, 2007

    Advertisement

    Want to use a patch from the Rails’ Trac that DHH didn’t think was a good fit? Patching some core functionality of Rails that you don’t want to make into a plugin?

    Place the following code in config/environment.rb before boot.rb is required.
    require File.join(File.dirname(__FILE__), '../lib/rails_patcher')
    Rails::Patcher.run
    
    And this into lib/rails_patcher.rb
    module Rails
      module Patcher
        ROOT_DIR = File.join(File.dirname(__FILE__), '..')
        PATCHES_DIR = "#{ROOT_DIR}/lib/patches/" 
    
        def self.run
          `mkdir #{PATCHES_DIR}` unless File.directory?(PATCHES_DIR)
          `rake rails:freeze:gems` unless File.directory?("#{ROOT_DIR}/vendor/rails")
    
          Dir["#{PATCHES_DIR}/*"].each do |file|
            next if %w(. ..).include?(file) || file =~ /^APPLIED_/
            STDERR.print "Patching #{file}..." 
            `patch -d #{ROOT_DIR}/vendor/rails -p0 < #{PATCHES_DIR}/#{file}`
            STDERR.print "Done.\n" 
            `mv #{PATCHES_DIR}/#{file} #{PATCHES_DIR}/APPLIED_#{file}`
          end
        end
      end
    end
    

    All that is left is for you is to drop your diff’s into lib/patches, start your server, and the patches are automatically applied once to vendor/rails

    The only caveat is that this won’t work if you’re on Windows. Other than that, the code is fairly straightforward if you have any questions about what’s going on.

    Update: using the right rake task to freeze the rails gems now.

  • Stephen Bannasch, 4 months later:

    Thanks for the idea. To get it to work I had to add the following in the inner loop.

     file = File.basename(file)

    So the whole inner loop now looks like this:

          Dir["#{PATCHES_DIR}/*"].each do |file|
            file = File.basename(file)
            next if %w(. ..).include?(file) || file =~ /^APPLIED_/
            STDERR.print "Patching #{file}..." 
            `patch -d #{ROOT_DIR}/vendor/rails -p0 < #{PATCHES_DIR}/#{file}`
            STDERR.print "Done.\n" 
            `mv #{PATCHES_DIR}/#{file} #{PATCHES_DIR}/APPLIED_#{file}`
          end
    

    With file set to the complete path it didn’t work.

  • One person has commented.
    Chime in.



    Textile is permitted.

Projects

  • Cheat! Sheets
  • Subtlety: RSSin' Your SVN
  • cache_fu
  • acts_as_textiled
  • mofo [microformat parsing]
  • require 'errtheblog'

Information

  • Dynamite! — The Err Free Weblog
  • Err Free: Ruby Development & Consulting
  • Err on GitHub
  • Err on Twitter
  • Report Err Plugin Bugs (Lighthouse Tracker)
  • Contact
This is Err, the weblog of PJ Hyett and Chris Wanstrath.
All original content copyright ©2006-2008 the aforementioned.