Luke Melia

personal

September 18, 2007

A rake task to apply a patch from a Trac ticket

Tracks uses a Trac for a bug tracker, and the awesome Tracks community helpfully attaches patches to tickets for a committer (me) to review and apply. I wanted an easy way to do this, so I whipped up this rake task that let’s you select a ticket and attachment to apply to the app as a patch:

namespace :trac do
  desc 'Apply a patch from a trac ticket.' 
  task :patch => :environment do
    require 'hpricot'
    require 'open-uri'
    require 'rubygems'
    require 'action_view/helpers/text_helper'
    include ActionView::Helpers::TextHelper
    trac_url = "http://dev.rousette.org.uk"
    unless ENV['TICKET']
      print "Enter the ticket number: "
      ENV['TICKET'] = STDIN.gets.chomp
    end
    doc = Hpricot(open("#{trac_url}/ticket/#{ENV['TICKET']}"))
    attachments_dts = doc/"#attachments"/"dt"
    attachment_index = 0
    if attachments_dts.length > 1
      print "\nThere are multiple attachments for this ticket.\n"
      attachments_dds = doc/"#attachments"/"dd"
      attachments_dts.each_with_index do |dt, i|
        print "\n[#{i + 1}] " + strip_tags(dt.inner_html) + " - " + attachments_dds[i].inner_html
      end
      print "\n\nEnter the number of the attachment you want to apply as a patch: "
      attachment_index = STDIN.gets.to_i - 1
    end
    filename = attachments_dts[attachment_index].search("a").inner_html
    patch_url = "#{trac_url}/attachment/ticket/#{ENV['TICKET']}/#{filename}?format=raw"
    
    patch = open(patch_url).read

    File.open('patch.diff', 'w+') do |f|
      f.puts patch
    end

    `patch -p0 < patch.diff && rm patch.diff`

    print "\nPatched with #{filename} from Trac ticket #{ENV['TICKET']}.\n"
  end
end

Here’s a sample shell session demonstrating the case when there is more than one patch attached:

$ rake trac:patch
Enter the ticket number: 560

There are multiple attachments for this ticket.

[1] cleanup_stats_controler.diff (25.9 kB) - added by foo@barcom on 09/16/07 19:32:35. - cleanup of stats_controller
[2] cleanup_stats_controler.2.diff (25.9 kB) - added by foo@barcom on 09/16/07 19:46:51. - whoeps old patch introduced an error. fixed with this patch

Which number attachment do you want to use as the patch to apply: 2

Patched with cleanup_stats_controler.2.diff from Trac ticket 560.

If there is only one attachment, it will be applied without you having to make a selection. Also, you can specify the ticket number on the command line (i.e. rake trac:patch TICKET=155).

That’s it. Hope this is useful!

Thanks to Chris Wansrath of err.the_blog for the inspiration via pastie:patch.

Leave a Reply

LukeMelia.com created 1999. ··· Luke Melia created 1976. ··· Live With Passion!