# Snippet - svn\_grep.rb

**URL:** <https://www.ruby-forum.com/t/snippet-svn-grep-rb/115501>\
**Category:** Ruby\
**Created:** [September 25, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/snippet-svn-grep-rb/115501 "2007-09-25T20:27:32Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Phlip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ed8c4c/32.png) [@Phlip](https://www.ruby-forum.com/u/Phlip)\
**Post date:** [September 25, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/snippet-svn-grep-rb/115501/1 "2007-09-25T20:27:32Z")

</div>

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’?\>  
  
  
svn://repo/ibenwrkinondarailroad/config/environment.rb  
  
svn://repo  
6f9af763-49f8-0310-a517-bcf8306575d7  
  
  
normal  
2007-07-19T17:54:02.000000Z  
84ed977b7c0185aa70969675781e3d92  
  
  
wrecker  
2007-07-19T18:09:31.817664Z  
  
  
")

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

 svn.expects(:xml).returns REXML::Document.new('<?xml 

```

version=“1.0”?\>  
  
  
wrecker  
2007-07-20T18:09:31.817663Z  
refactor thingy  
  
  
wrecker  
2007-09-20T16:17:07.292212Z  
added test for daily\_count  
  
  
wrecker  
2007-09-19T20:25:47.765465Z  
refact-AAARRRR  
  
  
wrecker  
2007-07-11T15:08:20.585929Z  
Adding yummy COUNTRY\_HASH  
')

```
 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
