04 March 2007

Using Rake to build Firefox extensions

I've been use rake to build my Firefox extension and found that it's been quite a pleasant experience. I needed to write a new build script as my old one was a Windows batch script and no longer use Windows for doing any development. Ant was a instant non-starter, I've had a enough XML config/programming to last me a lifetime. XML is great for data definition, not for configuration or programming. Rake seems very readable, and easy to maintain. Anyway, here's my build script for those of you interested in extension development:


require 'rexml/document'
include REXML

EXTENSION_NAME="translate"
BUILD_DIR="build/#{EXTENSION_NAME}"

# here we have a directory task, it will create the
# build directory if it doesn't already exists
directory "#{BUILD_DIR}/chrome"
task :create_buildchrome_dir => ["#{BUILD_DIR}/chrome"]

# we copy the manifest file to the build dir
# then iterate through each line and change the directory references
# to references to the jar file. this allows us to debug/develop normally
# and let the Rakefile deal with the changes necessary for release.
desc "prepare the chrome.manifest file"
file "#{BUILD_DIR}/chrome.manifest" => [:create_buildchrome_dir] do
open("#{BUILD_DIR}/chrome.manifest",'w') do |infile|
open("chrome.manifest", "r") do |outfile|
while line = outfile.gets
infile.puts line.gsub(/chrome\//, "jar:chrome/#{EXTENSION_NAME}.jar!/")
end
end
end
end
task :create_chrome_manifest => ["#{BUILD_DIR}/chrome.manifest"]

# not much to do here, just copy the install.rdf file over
# to the build dir.
desc "prepare the install.rdf file"
file "#{BUILD_DIR}/install.rdf" => [:create_buildchrome_dir] do
cp 'install.rdf', "#{BUILD_DIR}/install.rdf"
end
task :create_install_rdf => ["#{BUILD_DIR}/install.rdf"]

# here we create the jar file. ruby does natively support the creation of zip files
# so I have to use the shell to do it. the zip command allows the exclusion of certain file
# and in this case I want to exclude my svn files.
desc "create the chrome jar file"
task :create_chrome_jar => [:create_buildchrome_dir] do
sh "cd chrome && zip -qr -0 ../#{BUILD_DIR}/chrome/#{EXTENSION_NAME}.jar * -x \*.svn\*"
end

# this task makes sure the we've created the jar, prepared the manifest and install.rdf
# then we zip all of those files. We also extract the extension's version number from
# the install.rdf in order to generate the correct xpi file name.
desc "create the xpi file and use the version number in the file name"
task :create_extension_xpi => [:create_chrome_jar, :create_chrome_manifest, :create_install_rdf] do
install_rdf_file = File.new('install.rdf','r')
install_rdf_xmldoc = Document.new(install_rdf_file)
version_number = ""
install_rdf_xmldoc.elements.each('RDF/Description/em:version') do |element|
version_number = element.text
end

sh "cd #{BUILD_DIR} && zip -qr -9 ../../#{EXTENSION_NAME}-#{version_number}-fx.xpi *"
rm_rf "build"
end

task :default => [:create_extension_xpi]

1 comment:

sishen said...

Great, I really enjoy it.

I also made some changes of the Rakefile.

1. no chrome directory in the development mode. So while jar, choose the related folder.
2. put the chromes file in a JAR while packaging. So add extra "jar:chrome/helloworld.jar!/" in the right column, exactly, content/locale/skin column. I use regular expression to do the replacement.

Pls see the post for details, :)