snippet - svn_grep.rb

P

Phlip

Rails and SVN aficionados:

My colleague wrote a lite Ruby wrapper on SVN --xml that helps those
of us getting on in years grep our log for some bygone code.

The result is completely brute force, and does not exclude log entries
that didn't change the grepped lines. This provides an added benefit -
you don't need to pipe | less to slow the output down!

The code also comes with a prototypical unit test illustrating
stubbing out the actual SVN call, and illustrating some of SVN's
sample XML output.

--
Phlip


#!/usr/bin/env ruby
require 'optparse'
require 'rexml/document'


module SvnGrepModule
class SvnGrepper

def initialize(dir)
@svn = dir
end

def find(regex)
@found_revisions = []
regex = /#{regex}/
revisions.each do |revision|
found = %x[svn cat -r#{revision} #{@svn}].grep(regex)
if found.length > 0
puts "#{revision}: #{found}"
@found_revisions << revision
end
end
end

def revisions
doc = xml('log --xml')
log_entries = REXML::XPath.match(doc, '//logentry')
return log_entries.collect{ |log| log.attributes['revision'] }
end

def xml(command)
REXML::Document.new(%x[svn #{command} #{@svn}])
end

def current_revision
doc = xml('info --xml')
@current_revision = REXML::XPath.first(doc, '/info/entry/@revision').value
end

end
end

if ARGV.include?('test')

require 'test/unit'
require 'rubygems'
require 'mocha'
include SvnGrepModule

class SvnGrepperTest < Test::Unit::TestCase

def test_svn_grepper
svn = SvnGrepper.new('/home/wrecker/projects/ibenwrkinondarailroad/config/environment.rb')

svn.expects:)xml).returns REXML::Document.new("<?xml version='1.0'?>
<info>
<entry
kind='file'
revision='42'
path='/home/wrecker/projects/ibenwrkinondarailroad/config/environment.rb'>
<url>svn://repo/ibenwrkinondarailroad/config/environment.rb</url>
<repository>
<root>svn://repo</root>
<uuid>6f9af763-49f8-0310-a517-bcf8306575d7</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2007-07-19T17:54:02.000000Z</text-updated>
<checksum>84ed977b7c0185aa70969675781e3d92</checksum>
</wc-info>
<commit revision='8902'>
<author>wrecker</author>
<date>2007-07-19T18:09:31.817664Z</date>
</commit>
</entry>
</info>")

assert_kind_of SvnGrepper, svn
assert_equal '42', svn.current_revision

svn.expects:)xml).returns REXML::Document.new('<?xml version="1.0"?>
<log>
<logentry
revision="8902">
<author>wrecker</author>
<date>2007-07-20T18:09:31.817663Z</date>
<msg>refactor thingy</msg>
</logentry>
<logentry
revision="8786">
<author>wrecker</author>
<date>2007-09-20T16:17:07.292212Z</date>
<msg>added test for daily_count</msg>
</logentry>
<logentry
revision="8730">
<author>wrecker</author>
<date>2007-09-19T20:25:47.765465Z</date>
<msg>refact-AAARRRR</msg>
</logentry>
<logentry
revision="8711">
<author>wrecker</author>
<date>2007-07-11T15:08:20.585929Z</date>
<msg>Adding yummy COUNTRY_HASH</msg>
</logentry>')

assert_equal 4, svn.revisions.length
# svn.find('DEBUG_LOGGER')
end

end

else

include SvnGrepModule
svn_dir = ARGV.shift
look_for = ARGV.shift
if File.directory?(svn_dir)
# TODO if it is a directory, recursively look at the files
else
SvnGrepper.new(svn_dir).find(look_for)
end

end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,060
Latest member
BuyKetozenseACV

Latest Threads

Top