Nake is a magic build automation tool for .NET. It was built by unicorns flying in a rainbows and it's well seasoned by lots of fairy dust. Nake is simply that build\deployment\ops automation tool you were dreaming of.
Jokes aside, it's the only tool which can give you the imperative\functional convenience of Rake\MSBuild, but without forcing you (and your team) to learn yet another language and without pricking you eyes by hordes of angle brackets.
At last! Now you can automate your tasks by writing a 100% idiomatic C# code without any limitations (and with all the power of .NET framework) using a lightweight scripting approach. No projects, no pre-compilation, using any text editor.
Nake's DSL for defining tasks is uniquely minimal and it was carefully crafted to be a 100% IntelliSense compatible. If you're happy to edit your .csx
scripts by using Visual Studio (2012), you can get all of that editing goodness by simply installing Roslyn CTP extension.
And no worries, Nake has great MSBuild interoperability story, so you can easily import and execute any built-in or third-party MSBuild tasks.
There multiple ways in which Nake could be installed. You can install it by using NuGet package, or you can install it by downloading a standalone executable from GitHub releases page, and of course you can always build it from sources.
To install Nake via NuGet, run this command in NuGet package manager console:
PM> Install-Package Nake
Open up you favorite text editor and enter the following code:
[Task] public static void Welcome()
{
Console.WriteLine("Hello, world!");
}
Save it to the root folder of your solution and give file Nake.csx
name. Now you can invoke your task from command line by using Nake console application.
NOTE: If you installed Nake via NuGet package manager console in Visual Studio, during an installation a sample script (
Nake.csx
) was created in the root directory of your solution. You can use it as the starting point.
To invoke a task from a command line you just need to pass it's name to the Nake's console application. Task names are case insensitive, so to invoke the task you've just created, simply execute the following in your favorite console:
Nake welcome
You should see the following output:
Hello, world!
Cool, ya? ๐ฌ
That for sure will only work if you have Nake.exe
somewhere in your path. That's not good as Nake should be used as local dependency. Assuming that you have installed it via NuGet, your actual path might look like the one below:
Packages\Nake.1.0.0.7\tools\net45\Nake.exe welcome
That, without doubt, is tedious to enter every time you want to invoke a task, but there is nothing in the world that cannot be fixed with a duct tape and bit of cleverness. Let's create a simple batch file which will act as the proxy for running Nake. Create Nake.bat
file in the root directory of your solution and put there the text below:
@ECHO OFF
Packages\Nake.1.0.0.7\tools\net45\Nake.exe %*
Now you have an easy (and recommended) way to launch Nake.
NOTE: If you installed Nake via NuGet package manager console in Visual Studio, during an installation a sample batch runner file (
Nake.bat
) was created in the root directory of your solution. if that didn't happen - check Nakesamples
directory inside respective package folder.
Now if you invoke Nake with -T
switch it should show you all tasks defined in the script. Nevertheless, running it for the script which we've just created will produce no output. Why is that? Well, that's because by default Nake won't list tasks that don't have descriptions.
Now guess how can we give a meaningful descriptions to our tasks, which are simply methods? Right, you will just use standard XML documentation comments:
/// <summary>
/// This is a demo task
/// </summary>
[Task] public static void Welcome()
{
Console.WriteLine("Hello, world!");
}
Now if you run Nake with -T
switch you should see the following output:
C:\Demo>Nake -T
Nake welcome # This is a demo task
With Nake, it's ridiculously easy to define task parameters and pass them to a task from a command line.
[Task] public static void Welcome(string who)
{
Console.WriteLine("Hello, {0}!", who);
}
Now you can simply invoke it using the following command-line:
Nake welcome amigo
That will print as expected:
Hello, amigo!
Nake also supports optional parameters, so you can define the task above as follows:
[Task] public static void Welcome(string who = "baby", string greeting = "Hello")
{
Console.WriteLine("{0}, {1}!", greeting, who);
}
Invoking it with the following command line:
Nake welcome greeting: "Hasta la vista"
Will produce the following output:
Hasta la vista, baby!
NOTE: At the moment Nake supports the following parameter types: bool, string and int. Support for
params
arrays and some other types is on a road-map. Nevertheless, it's possible to code pretty much anything with just the types already supported by Nake.
Suppose we have the following build related tasks defined in a script:
[Task] public static void Clean()
{
// here goes code, which cleans build output directory
}
[Task] public static void Build(string configuration = "Debug")
{
// here goes code, which builds sources using given configuration
}
We want to specify that the Clean()
task should always be executed before the Build()
task is executed. Regarding to this, we can say that the Clean()
task is the prerequisite of the Build()
task or that the Build()
task is dependent on the Clean()
task.
Now, how can we specify that relationship in Nake script? That Build()
task is dependent on the Clean()
task? Check out the following example:
[Task] public static void Clean()
{
// here goes code, which cleans build output directory
}
[Task] public static void Build(string configuration = "Debug")
{
Clean();
// here goes code, which builds sources using given configuration
}
Yes, it's just a regular method call. There is no any special syntax in Nake for specifying prerequisites - you simply invoke one task from within another task using native C# language constructs. Everything is 100% statically bound. No strings whatsoever, and you can put task invocations in any place you want (so that you can easily replicate advanced MSBuild features like Before/After targets ๐).
TODO: Describe how Nake is unique in its approach to specifying tasks and their prerequisites, and how it extends C# language semantics in order to implement dependency based style of computation (link), while still keeping its DSL (pure C#) rather imperative. Describe how Nake uses Roslyn's syntax re-writing features to rewrite task invocations.
TODO
TODO
TODO
TODO
TODO
TODO
TODO
Point to relevant topics in scriptcs documentation
Cmd line reference Calling multiple tasks (note about PowerShell escaping of ';')
- Ask for required arguments, ala PowerShell
- Interactive mode, task name tab completion
- Once Roslyn finally start respecting #load directive, move both Meta and Utility to
.csx
files, so global install is possible
Bugs - no need to ask anything, just fix it and do a pull request
Features - ideally should be discussed via GitHub issues or Nake's discussion group to avoid duplicate work and to make sure that new stuff is still inline with original vision.
Have a look at Nake.csx or Publish.csx. Those are the Nake files used to build and publish Nake itself (ye, we're eating our own dog food). Also, additional samples can be contributed to samples repository. Detailed documentation (soon) can be found on wiki.
General discussion group could be found here. Also, for news you can follow Nake's official twitter account (or my account for that matter). The twitter's hashtag is #naketool
.
- To all contributors (check out GitHub statistics)!
- Thanks to all members of the scriptcs team for lending me their script pre-processing code
- Special thanks to Anton Martynenko for giving me an idea and steering Nake's DSL in the right direction
- Hugs and kisses to my lovely Valery for being so patient and supportive, and for feeding me food and beer, while I was sitting in my cage working on Nake, instead of spending that time with her
Apache 2 License