Luke Melia


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 = “”
unless ENV[‘TICKET’]
print “Enter the ticket number: ”
ENV[‘TICKET’] = STDIN.gets.chomp
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
print “\n\nEnter the number of the attachment you want to apply as a patch: ”
attachment_index = STDIN.gets.to_i – 1
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‘patch.diff’, ‘w+’) do |f|
f.puts patch

`patch -p0 < patch.diff && rm patch.diff` print "\nPatched with #{filename} from Trac ticket #{ENV['TICKET']}.\n" end end [/ruby] Here's a sample shell session demonstrating the case when there is more than one patch attached: [code] $ 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. [/code] 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 created 1999. ··· Luke Melia created 1976. ··· Live With Passion!