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
[/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.