I was recently given the unenviable task of providing my manager with a spreadsheet listing all the code artificacts (.java files, xml files, JSPs, etc.) that my team was working on. The list should include, among other things, all the source files under my src directory, JSPs under the web directory, and XML configuration files under web/WEB-INF. But it should exclude things like generated source code, .class files, and jar files.

My desktop at the client site runs Windows, so I thought I would try out the dir command. That got me nowhere. Then I jumped into cygwin and tried ls -R. Of course, this listed everything under my project directory, including the CVS directories and their contents. Plus, the file listing didn’t specify the full path. If I was going to use this output to create my spreadsheet it would take quite a lot of cutting, pasting, and deleting to make it suitable for the spreadsheet — there had to be a better way.

I’ve spoken fluent Java for almost 10 years now, so I thought, hey, I can do this in Java! I looked at the API for java.io.File … and then thought again.

Well, that Ruby language seems pretty popular … I’ll try that.

I googled “Ruby recursive directory” and found a couple of interesting hits. This looks darn easy to do in Ruby. I installed Ruby (cake with the one-click install), fired up TextPad and cranked out this little script in just a few minutes. It did the job perfectly.

Oh, and by the way, it’s my first Ruby script.

require 'find'
dirs = ["src/java","src/hbm", "src/conf", "src/unit-test", "src/integration-test", "web"]
excludes = ["CVS","classes","images","lib","tlds"]
for dir in dirs
  Find.find(dir) do |path|
    if FileTest.directory?(path)
      if excludes.include?(File.basename(path))
        Find.prune       # Don't look any further into this directory.
      else
        next
      end
    else
      p path
    end
  end
end

The next time you’ve got a tedious task like this, give Ruby a try. I was impressed at the quality of the documentation, and just as importantly, the quality of the error messages spat out by the Ruby interpreter when my language guesses weren’t quite right. Every good repair man knows that it takes more than one tool to get a job done — pick the right one and you can save yourself a lot of time and frustration — and maybe have some fun along the way.