I haven’t blogged for a while about our build environment as I’ve been busy, firstly playing around with and integrating TeamCity as part of Continuous Integration (I won’t go into detail about TeamCity apart from say that it’s excellent, and we’ll be migrating across all of our build projects from CruiseControl.Net to TeamCity). And secondly, I’ve been learning Ruby to write build scripts with.

Part of this shift allowed me to get familiar with Ruby as a build language. I’ve been writing Ruby at home for various tasks in Linux, such as doing incremental backups using Rsync, Hard Linking and SSH for all of my files, but hadn’t yet applied it to building .Net applications.

Regarding Ruby, the first thing you should know is that Ruby is awesome for writing build scripts. Here are some ruby benefits:

Less Code

Compared to something like NAnt, the amount of code you need to write is a lot less. It’s also more re-usable being OO. The “sh” Rake task allows you to call tools such as MsBuild, or AspNetCompiler via the command line easily. In the below example I’m still actually using NAnt to tokenise some configs for me. But with Ruby I can use an “each” loop and save repeating myself.

[‘Project1′, ‘Project2′, ‘Project3′].each do |target| sh "#{$NAnt} -buildfile:src/#{target}/Web.tokens.config #{$Environment}" sh "#{$NAnt} -buildfile:src/#{target}/AppSettings.tokens.config #{$Environment}" sh "#{$NAnt} -buildfile:src/#{target}/log4net.tokens.config #{$Environment}" end

Or in this example, I can replace a token in a config for a number of projects. I especially like the line where it opens a file, writes to it, and closes it all on one line while still being reasonably readable.

[‘Word’, ‘Excel’, ‘PowerPoint’].each do |target| text = File.read "Office.2007.#{target}/App.config" text = text.gsub(/key="Environment" value="(.+)"/, "key=\"Environment\" value=\"#{config.Environment}\"") File.open("Office.2007.#{target}/App.config", ‘w’) { |f| f.write(text) } end

Another example and one of the most useful, is getting the latest svn revision all via one line of code. I made this into a re-usable method

revision = %x[svn log http://svn/trunk/ –non-interactive –xml –limit 1].scan(/revision="(\d+)"/).to_s

My Ruby is by no means perfect, and I’m sure there are further improvements, but the above examples prove a point. I can do more with less code than I can compared with another build runner such as NAnt, while keeping it nice and readable.

More Control

I personally found NAnt buggy in some places. For example “verbose=false” often doesn’t work and you end up with log files full of output you don’t want. I’ve had no such issues with Ruby and Rake.

Colour output in the console in Windows is easily achievable. You can do easily creating readable output, for example… puts ‘hello huddle’.green …which will output ‘hello huddle’ in green text. In order to use this there is a pre-requisite you need to install via command line:

gem install win32console term-ansicolor

require ‘term/ansicolor’ require ‘win32console’ class String include Term::ANSIColor end def Display(message) puts ” puts "%s" % message.cyan puts "##########################".magenta end Display ‘Hello huddle’

Controlling the output allows the logs to be more readable. This makes reading through them when there is a breakage much faster. Using colours in the output also helps developers when checking the code on their pc. Green for Pass, and Red for Fail makes it easy to see messages between all the other log noise.

Testable

I’ve been a bit bad here, and not tested any of our build scripts… yet. This is something I’m currently going back to do, and may update the post (or write a new one) when I’ve managed to get to grips with RSpec.

However, despite me not doing it, my point is that you can in Ruby test all of your code. And it’s fairly easy to do so. Making your build scripts testable, and robust is a good thing, and ensures you won’t release anything live that hasn’t been built properly.

Community

I did look at alternatives such as PSMake (Powershell Make), Cake (C# Make), and Python. All good options, but I felt with Ruby the documentation is simple, and there’s an active community out there.

I have come across a few problems when writing my scripts. For example, getting the latest svn revision easily, reading a file via HTTP, and zipping multiple files with exclude patterns. I’ve been able to find examples for all of these problems without much pain. Whether it be directly via the documentation, or a blog/discussion forum I’ve found through Google.

Juicer

The last but by no means least of the ruby benefits. Juicer (gem install juicer) is an additional Ruby library that allows you to compress and validate CSS and JavaScript. It basically acts as a wrapper to tools such as YUICompressor and JSLint with some additional logic thrown in. There is a similar library called Sprockets written by the RoR guys, but I think it only handles CSS.

Simply put Juicer allows you to manage and optimize your CSS and JavaScript very easily. To find out more the author has written a good article explaining what Juicer can do.

Conclusion

I’ve kept the article relatively short, but just wanted to highlight some of the ruby benefits as a build language. It is easily possible to build .Net applications with Ruby, and I’d recommend it over any other build language. Combined with TeamCity it has hugely improved out build environment. I just can’t imagine going back to the days of using NAnt now. Ruby is a very handy language every developer should know how to use.

Colin Grossman


Request a Demo
trillatron

© 2006 - 2019. All Rights Reserved.