Rake: The only sensible way to build on Windows

05 January 2013 |

If you’re still using NAnt or MSBuild to build your .NET projects on Windows, stop! You’re doing it wrong!

Instead, use Rake.

What is it?

Rake is the Ruby version of Make and is used to build Ruby projects, such as Rails. It reads a rakefile which contains tasks to help you build, test, manage and deploy your code.

Rake is superior to NAnt or MSBuild because you don’t need to mess around with XML. You get a simple-to-use DSL with full access to the entire Ruby language at your disposal. No more hacks to make NAnt do what you want. If you need to do something exotic, just write the code in pure Ruby.

I’m a .NET guy. Isn’t Rake just for Ruby projects?

No. With a handy gem called Albacore, Rake is able to work with .NET tools such as MSBuild, CSC, NUnit and Mono’s xbuild.

Getting started

  1. Install Ruby or get Ruby for “free” with Git

  2. Open up a command line window. I recommend Console2 because it supports tabs and multiple shells. I use the version of Bash that comes with Git.

  3. From command line, install Albacore using RubyGems, a Ruby package manager.

     gem install albacore
    
  4. Navigate to your solution directory and create your first rakefile.

     touch rakefile.rb
    
  5. Open up your favorite text editor and edit rakefile.rb

     require 'albacore'
    
     msbuild :build do |b|
         b.properties = { :configuration => :Debug }
         b.targets = [ :Build ]
         b.solution = "HelloWorld.sln"
     end
    
  6. Return to the command line and type

     rake build
    

Congrats! You just built your first .NET solution using Rake.

Woah there, slow down! What just happened?!

If you’re note familiar with Ruby, this might be a lot to absorb, especially the syntax. I’ll walk through the rake file from a C# perspective.

First thing we do is include ‘albacore’.

A rakefile is a collection of tasks, so next we set up an MSBuild task called :build. Rake has a rich Domain Specific Language, which allows us to write build scripts more naturally. What we’re actually doing here is calling the msbuild function in the albacore namespace to register a new msbuild task by giving it a name and an anonymous function.

In case you’re wondering what :build is, it’s a Ruby symbol. The simplified answer is that you can think of them as enums that you can use like strings. In fact, we could have easily used a string instead symbol to name our task:

msbuild "build" do |b|
  # ...
end

As I mentioned earlier, msbuild is a function that expects an anonymous function as its second parameter. In C#, that would be an Action or Func object. Ruby uses do-end blocks. In our anonymous method we have access to the parameter b and we set the necessary properties on it.

In C#, this rakefile would look something like this:

using Albacore;

namespace HelloWorldRakefile
{
    class Program
    {
        static void Main(string[] args)
        {
            var rake = new Rakefile();

            rake.AddTask<MSBuildProps>("build", b => {
                b.Properties = new Dictionary<string, string> { { "Configuration", "Debug" } };
                b.Targets = new [] { "Build" };
                b.Solution = "HelloWorld.sln";
            });

            rake.AddTask("default", "build");

            rake.Run(args);
        }
    }
}

And you would run it like this:

HelloWorldRakefile.exe build

Let’s make this better

Now that you’re familiar with Rake, you can make this even better by setting up a default task that runs the :build task

task :default => :build

This allows you to simply run the rake command without specifying a task.

Rake also allows for sequencing tasks together. If we had a :clean task, we could update :default to call :clean before calling :build.

require 'albacore'

msbuild :build do |b|
    b.properties = { :configuration => :Debug }
    b.targets = [ :Build ]
    b.solution = "HelloWorld.sln"
end

msbuild :clean do |b|
    b.properties = { :configuration => :Debug }
    b.targets = [ :Clean ]
    b.solution = "HelloWorld.sln"
end

task :default => [ :clean, :build ]

To infinity and beyond

I’ve only scratched the surface… Rake and Albacore can do a lot more.

Rake isn’t simply useful for compiling code and copying files. You can make a Rake task for anything scriptable, like sending a tweet. You can even create a cron job to execute a rake task. I often find it easier to create a rakefile than to write a ruby or batch script.

Cheers!

Console2: A better command prompt for Windows

05 January 2013 |

I found out about Console2 from Scott Hanselman’s blog and haven’t looked back. On Windows, it’s a great replacement for vanilla cmd.exe. It supports tabs and can host multiple shells, including cmd, Powershell, Msysgit and Cygwin. Even if you prefer the Windows command line over these Unix-inspired shells, you should still use Console2 to launch cmd sessions.

Scott’s blog tells you how to set up Powershell on Console2, but I use it primarily with the version of Bash that comes with standard Git for Windows installer.

Here’s how I set up a new install of Console2:

  1. Download and install Git for Windows. Preferably to c:\bin\git
  2. Download and unzip Console2 somewhere. Preferably to c:\bin\console2
  3. Launch Console2
  4. Go to Edit → Settings → Tabs
  5. Rename the default Console entry to Windows. This points to cmd
  6. Add a new tab
    • Title: Git
    • Icon: c:\bin\git\etc\git.ico
    • Shell: c:\bin\git\bin\sh.exe --login -i
    • Startup dir: c:\
  7. If you prefer to use this as your default shell, like I do, move Git to the top of the list.
  8. Press OK and you’re done!

I also like to edit a few other settings. These are all personal preferences:

  • Open Edit → Settings
  • Under Behavior, check the Copy on Select option
  • Under Hotkeys
    • Set New Tab 1 to Ctrl-T
    • Set New Tab 2 to Ctrl-Shift-T
    • Set Paste to Ctrl-V

Cheers!

Yoeun Pen

Developer / Designer / Technologist

Washington, DC



Latest tweets