Using rake to manage your software project
Do you have some of those projects where you have to be sure that you jump the same loops every time you edit some code? Take a look at the bio-graphics code. Every time I change anything in the code, I have to do the following things:
- regenerate the RDoc documentation
- regenerate the ruby gem
- check SVN status
- do an SVN update
- perform the SVN commit
- upload the new documentation to the website
How's this work? You basically create a file containing tasks and tell rake to execute one or more of them, the Rakefile. There are several good tutorials on rake, like the one from Martin Fowler and from the Rails Envy guys. I'm not going into the nitty-gritty of how they're written. These tutorials are much better at that. What I will do here, is describe the Rakefile I use for Bio::Graphics. (Someone already asked in the comments on my post on using ActiveRecord outside of rails what the Rakefile was that I used. Actually, the one mentioned in that post was empty and just a place holder.)
Without further ado, here it is:
#
# Rakefile.rb
#
# Copyright (C):: Jan Aerts
# License:: The Ruby License
#
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
task :default => :svn_commit
file_list = Dir.glob("lib/**/*.rb")
desc "Create RDoc documentation"
file 'doc/index.html' => file_list do
puts "######## Creating RDoc documentation"
system "rdoc --title 'Bio::Graphics documentation' -m TUTORIAL TUTORIAL README.DEV lib/"
end
desc "An alias for creating the RDoc documentation"
task :rdoc do
Rake::Task['doc/index.html'].invoke
end
desc "Create a new gem"
file 'bio-graphics-1.0.gem' => file_list do
puts "######## Creating new gem"
system "gem build bio-graphics.gemspec"
end
desc "An alias for creating the gem"
task :create_gem do
Rake::Task['bio-graphics-1.0.gem'].invoke
end
desc "Check SVN status"
task :check_svn_status do
puts "######## Checking SVN status"
message = String.new
message << "# SVN status requires manual intervention\n"
message << "# For items with '?': either svn add or svn propedit svn:ignore\n"
message << "# For items with '~': don't know yet\n"
message << "# Please see http://svnbook.red-bean.com/en/1.4/svn-book.html#svn.ref.svn.c.status"
output = `svn status`
puts output
allowed_status = ['A','D','M','R','X','I'] # See http://svnbook.red-bean.com/en/1.4/svn-book.html#svn.ref.svn.c.status
output.each do |line|
status = line.slice(0,1)
if ! allowed_status.include?(status)
raise message
end
end
end
desc "Check if SVN updates available"
task :check_svn_update do
puts "######## Checking SVN update"
output = `svn update`
puts output
if output !~ /^At revision [0-9]/
raise "Please update your working copy first"
end
end
desc "Commit to SVN repository"
task :svn_commit => [:check_svn_update, :check_svn_status, :create_gem, :rdoc] do
puts "######## Doing SVN commit"
system 'svn commit'
end
rake -T lists all available tasks:
rake bio-graphics-1.0.gem # Create a new gemThe file_list at the top contains all files in the library itself, and will be used to check all timestamps. The file 'doc/index.html' task looks at the timestamp of the index.html file and if it's older than any of the files in file_list, it will regenerate the documentation. If it's newer, nothing happens. Same goes for bio-graphics-1.0.gem.
rake check_svn_status # Check SVN status
rake check_svn_update # Check if SVN updates available
rake create_gem # An alias for creating the gem
rake doc/index.html # Create RDoc documentation
rake rdoc # An alias for creating the RDoc documentation
rake svn_commit # Commit to SVN repository
The check_svn_update and check_svn_status tasks just check if subversion needs some manual intervention before being able to commit. This should be able to catch conflicts in the working copy and the repository, or files that you forgot to add the SVN.
Note: why didn't I use the special Rake::RDocTask instead of the one I use here? Because the built-in RDoc task first removes your whole doc directory, also deleting the subversion metadata contained in it.



2 comments:
That's a great post, I love Ruby and I love automated build scripts. They especially go well together with unit testing. You can change things and run the build script and see if anythings broken, and so can anyone else who wants to tinker with your code.
You're completely right. I forgot about the unit testing because this happens to be the one library where I don't have them... (due to the nature of the creature: creating PNGs; which can't be tested).
Post a Comment