Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Glimpse Into CAKE

DZone's Guide to

A Glimpse Into CAKE

If you're a C# developer, read on to see if using the CAKE open source development framework is right for you and your team.

· Web Dev Zone
Free Resource

Should you build your own web experimentation solution? Download this whitepaper by Optimizely to find out.

For a couple of years now, I've been using C# Make to configure my builds. Also, at my company, we use FAKE in some projects. One of the projects has been using it more and more over the last two years. FAKE is really great and I love using it, but there is one problem with it: most C# developers don't really like to use new things. The worst case scenario for most C# developers - it seems - is a new tool, that uses an exotic language like F#.

This is why I have to maintain the FAKE build scripts since I introduced FAKE to the team.

It is that new tool and the F# language that must be scary for them, even if they don't really need to learn F# for the most common scenarios. That's why I asked my fellow developers to use CAKE (C# Make).

  • It is C# make instead of F# make.
  • It looks pretty similar.
  • It works the same way.
  • It is a scripting language.
  • It works almost everywhere.

They really liked the idea of using CAKE. Why? Just because of C#? It seems so...

It doesn't really make sense to me, but anyway, it makes absolute sense that the developers who need to use and to maintain their own build configurations.

How Does CAKE Work?

CAKE is built using a C# scripting language. It uses the Roslyn compiler to compile the scripts. Instead of using batch files, as FAKE does, it uses a PowerShell script (build.ps1) to bootstrap itself and to run the build script. The bootstrapping step loads CAKE and some dependencies using NuGet. The last step that the PowerShell script runs is to call the cake.exe and to execute the build script.

The bootstrapping needs network access to load all the stuff. It also loads the nuget.exe, if it's not available. If you don't like this, you can also commit the loaded dependencies to the source code repository.

The documentation is great. Just follow the getting started guide to get a working example. There's also nice documentation available about setting up a new project.

Configuring the Build

If you know FAKE or even MSBuild, this will look pretty familiar. Let's have a quick look into the first simple example of the getting started guide:

var target = Argument("target", "Default");

Task("Default")
  .Does(() =>
        {
          Information("Hello World!");
        });

RunTarget(target);

The first line retrieves the build target to execute from the command line arguments. Starting from line 3, we see a definition of a build target. This target just prints a "Hello World!" as an information message.

The last line starts the initial target by its name.

A more concrete code sample is the build script from the CAKE example (I removed some lines in this listing to get a shorter example):

#tool nuget:?package=NUnit.ConsoleRunner&version=3.4.0

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");

// Define the build directory.
var buildDir = Directory("./src/Example/bin") + Directory(configuration);

Task("Clean")
  .Does(() =>
        {
          CleanDirectory(buildDir);
        });

Task("Restore-NuGet-Packages")
  .IsDependentOn("Clean")
  .Does(() =>
        {
          NuGetRestore("./src/Example.sln");
        });

Task("Build")
  .IsDependentOn("Restore-NuGet-Packages")
  .Does(() =>
        {
          MSBuild("./src/Example.sln", settings =>
                  settings.SetConfiguration(configuration));
        });

Task("Run-Unit-Tests")
  .IsDependentOn("Build")
  .Does(() =>
        {
          NUnit3("./src/**/bin/" + configuration + "/*.Tests.dll", new NUnit3Settings {
            NoResults = true
          });
        });

Task("Default")
  .IsDependentOn("Run-Unit-Tests");

RunTarget(target);

This script uses another NuGet package to run the NUnit3 tests and references it. A nice way to take advantage of this feature is to configure the NuGet dependency at the beginning of the script.

This build script contains five targets. The method IsDependentOn("") wires the targets together in the right execution order. This way is a bit different from what you would do in FAKE and maybe a little bit confusing. It needs to write the targets in the right execution order. If you don't write the script like this, you need to find the initial target and to follow it back to the very first target. You will read the execution order from the last to the first target.

FAKE does this a little easier and wires the targets up in a single statement at the end of the file:

// Dependencies
"Clean"
  ==> "Restore-NuGet-Packages"
  ==> "Build"
  ==> "Run-Unit-Tests"
  ==> "Default"

RunTargetOrDefault "Default"

This could possibly look like this dummy code in CAKE:

// Dependencies
WireUp("Clean")
  .Calls("Restore-NuGet-Packages")
  .Calls("Build")
  .Calls("Run-Unit-Tests")
  .Calls("Default");

RunTarget(target);

Running the Build

To run the build, just call .\build.ps1 in a PowerShell console:

If you know FAKE, the results look pretty familiar:

Conclusion

Anyway, I think CAKE was accepted much faster by my fellow developers at work than FAKE was. Some things will work a little easier in CAKE than in FAKE, and some a little different, but most of the code stuff will work the same way. 

Implementing an Experimentation Solution: Choosing whether to build or buy?

Topics:
web dev ,cake ,c#

Published at DZone with permission of Jurgen Gutsch. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}