Custom Subversion Rake Tasks, Part 1

One of the most tedious aspects of working with Ruby on Rails with Subversion is setting up the initial project to exclude the right files and set up all of the directorypropsets. Having fallen into the role of checking in the initial Rails project for a new platform I have been asked to help build at work, I thought it was about time to get the Rails Subversion Setup down to 3 steps. This post is not going to talk about how to setup and run Subversion, there are plenty of articles out there on that. So, once your project is setup in svnadmin, check out the empty trunk directory, and from there:

  1. Run rails . from inside trunk to have Ruby on Rails build a blank project
  2. Copy svn.rake into the lib/tasks directory and run rake svn:setup
  3. There is no step 3

That’s it! You are now be all set to begin development on your application and are one step closer to being bought out by !

svn rake:setup

You could just believe that the above process works by magic, but let’s take a step-by-step look at what the svn:setup rake task actually does.

if File.exists? 'config/database.yml'
  move 'config/database.yml', 'config/database.example.yml'
end

Pretty straight forward, we don’t want to store our database.yml file in subversion because, let’s face it, access to your production database should probably be safe-guarded just a little bit. We first make sure the default config/database.yml exists, then rename it to what it is, an example file: config/database.example.yml.

files = Dir.glob('log/*') + Dir.glob('tmp/*') + Dir.glob('db/*.sqlite3')
files.each { |file| remove_entry file }

We don’t want to store log files, temporary files, or development databases in subversion. Dir.glob returns a list of filenames (paths) that match a given pattern. Combine all the paths found into one list and use remove_entry to delete each file or directory.

mkdir_p ['doc/api', 'doc/app']

f you want to have Ruby on Rails documentation (rake doc:rails) or your application’s documentation (rake doc:app) on your local machine, you shouldn’t pollute subversion with it. Let’s make the doc/api and doc/app directories now, so we can setup subversion rules later to prevent the documentation from being added to the repository.

Rake::Task["rails:freeze:gems"].invoke
Rake::Task["rails:update"].invoke

You should freeze rails in your application to ensure you are developing against the same version of Rails no matter where the code is checked out or deployed. SeeFreezing Your Rails Application for more information.

Rake::Task["svn:add"].invoke
`svn commit -m "Initial checkin with frozen rails"`

We then invoke another helpful Subversion Rake task I wrote (to be explained in Part II) to mark all of the files we have in trunk to be added to the subversion repository and make a system call to actually make the commit.

`svn propset svn:ignore "database.yml" config/`
`svn propset svn:ignore "*" log/`
`svn propset svn:ignore "*" tmp/`
`svn propset svn:ignore "*" doc/app/`
`svn propset svn:ignore "*" doc/api/`
`svn propset svn:ignore "*.sqlite3" db/`

Finally, we set up our svn propsets so subversion will ignore (svn:ignore) all unnecessary files:

  • config/database.yml – ignore local database settings
  • log/* – ignore all log files
  • tmp/* – ignore all temporary files
  • doc/app/* – ignore all application documentation
  • doc/api/* – ignore all Rails documentation
  • db/*.sqlite3 – ignore all local SQLite database files (development, test, etc.)
`svn commit -m "Initial svn:ignore list - config/database.yml log/* tmp/* doc/app/* doc/api/* db/*.sqlite3"`

And commit the settings to our subversion repository.

Check out Custom Subversion Rake Tasks, Part II for an explanation of the rest of the custom Subversion Rake Tasks (svn:add, svn:delete, svn:update, svn:commit, andsvn:status).