Monday 19 January 2009

NAnt HowTo #4: How To Create And Use Custom NAnt Task

new class named OK, let's start. What is a NAnt task? Formally, it's a class that extends NAnt.Core.Task class from NAnt.Core.dll assembly located in your NAnt installation folder. As any class it will be placed in an assembly, and this assembly is the way you interact with NAnt. So, let's get it! The following steps describe how to create a simple HelloTask task.

1. Create new project

Create an empty class library project that will compile to .dll file.

2. Create new class derived from NAnt.Core.Task

Create new class named HelloTask and derive from NAnt.Core.Task:

public class HelloTask : Task
{

}

3. Override ExecuteTask method

As NAnt.Core.Task class is abstract VS will suggest you to override the ExecuteTask method - do it. Put the following implementation into it (assume that Person property is already defined ;)):

protected override void ExecuteTask()
{
Project.Log(Level.Info, String.Format("Hello, {0}!", Person));
}
Have a look at Project.Log() call - it will output some message with needed level.

4. Define task name

To define task name, you should apply NAnt.Core.Attributes.TaskNameAttribute attribute to your class:
[TaskName("hello")]
public class HelloTask : Task


5. Define task attributes

To define task attributes, you should define property of appropriate type and mark it with the NAnt.Core.Attributes.TaskAttributeAttribute attribute:

[TaskAttribute("person", Required = true)]
public String Person
{
get;
set;
}
Attribute constructor allows you to specify several options, like whether this attribute is required.

6. Load assembly with you class in NAnt

To use your new task you should place your assembly somewhere NAnt has access to. Two most appropriate options are in NAnt installation folder and in build execution folder. Though I prefer the last one, the first one may be useful if you use your custom tasks regularly though not changing them often.

As soon as assembly is properly placed, you should load tasks from it in your build file. Use loadtasks attribute to load it:

<loadtasks assembly="Leaves.NAnt.Custom.dll" />

7. Use your task

Just use it in the most obvious way:

<hello person="world" />
The output will be the following:

all:

[loadtasks] Scanning assembly "Leaves.NAnt.Custom" for extensions.
Hello, world!

It works!

8. Summarize

This is what we've got in our task:

using System;
using NAnt.Core;
using NAnt.Core.Attributes;

namespace Leaves.NAnt.Custom
{
[
TaskName("hello")]
public class HelloTask : Task
{
protected override void ExecuteTask()
{
Project.Log(Level.Info, String.Format("Hello, {0}!", Person));
}

[
TaskAttribute("person", Required = true)]
public String Person
{
get;
set;
}
}
}
And build file:

<?xml version="1.0"?>

<project
name="NAnt HowTo 4" default="all" xmlns="http://nant.sf.net/release/0.85-rc2/nant.xsd">
<target
name="all">
<loadtasks
assembly="Leaves.NAnt.Custom.dll" />
<hello
person="world" />
</target>
</project>
kick it on DotNetKicks.com

No comments: