Tagged: scriptcs

Scripting Builds with C#, Yes I Said Scripting

If you haven’t partaken of the delicious goodness that is Roslyn, don’t fret it’s easy to get in on the fun. Have you heard of ScriptCS? It’s kind of what I hoped Powershell would become, scripting with C#. No stinking compiling and complex builds, no having to learn new complex syntax and functionality, just code in C# and go. This is what ScriptCS brings by way of Roslyn. I had fun just writing C# and running it, but I needed to find a practical reason to script C# in the real world.

Then it hit me. I was in the middle of writing a build script for a project and I wondered how I could do it with ScriptCS. Looking at my NAnt script I started looking for a way to port my build script to ScriptCS and failed to envision an easy way to do it. So, I ended up doing some searching and stumbled upon Nake (actually I think a co-worker may have told me about it, can’t remember) . As the author, Yevhen Bobrov, describes Nake, “Write you build automation scripts in C# without paying the angle bracket tax!” According to Yevhen, he uses the ScriptCS pre-processing engine and takes advantage of Roslyn’s syntax re-writing features to rewrite task invocations.

Enough talk, let’s code. We will start with a build in NAnt using the sample from nant.org.

<?xml version="1.0"?>
<project name="Hello World" default="build" basedir=".">
<description>The Hello World of build files.</description>
<property name="debug" value="true" overwrite="false" />
<target name="clean" description="remove all generated files">
<delete file="HelloWorld.exe" failonerror="false" />
<delete file="HelloWorld.pdb" failonerror="false" />
<target name="build" description="compiles the source code">
<csc target="exe" output="HelloWorld.exe" debug="${debug}">
<includes name="HelloWorld.cs" />

We can do similar in Nake like so:

using System;
using Nake;
//The Hello World of build files.
public static string basedir = ".";
public static string configuration = "Debug";
public static string platform = "AnyCPU";
[Task] public static void Default()
//remove all generated files
[Task] public static void Clean()
//compiles the source code
[Task] public static void Build()
 .Property("Configuration", configuration) 
 .Property("Platform", platform)
 .Targets(new[] {"Rebuild"})

I really like Nake, it feels like regular C# coding to me. There may be more lines, but its easily readable lines IMHO. Not to mention, I have access to the power of C# and not just features added to a scripting tool like NAnt.

After working with Nake for a little while I found another project that targets task scripting with C#, Bau. Bau’s author, Adam Ralph, tags the project with “The C# task runner.” It’s built as a scriptcs script pack and is inspired by Rake, Grunt and gulp.” He uses an interesting approach where tasks are chained together like a long fluent build train. I haven’t had the chance to actually use Bau, but I read through some of the source and documentation. Having to chain tasks together in Bau seems foreign and limiting as I am not sure how to achieve a reusable, composable design in a manner that I am accustom to. It’s probably very simple, just not readily apparent to me like it is in Nake.

Well, I’ll keep it short. It’s good to see that there are options beginning to emerge in this space. I hope the community contributes to them. Both Nake and Bau open up scripting builds to C# developers. We get to leverage what we know about C# and script with syntax and tools we are already familiar with. We get the task based nature of NAnt with the familiarity of C#. So, if you aren’t ready to take the plunge in Roslyn, how about testing the waters with C# build scripting.

Footnote: Nake hasn’t had any commits in 5 months, Yevhen lists his location as Kiev, Ukraine. Yevhen, I have been watching the news about all of the violence happening in the Ukraine and if you are there I hope that you are OK and thanks for Nake.