Overview
NAnt is a is a free and open source software tool for
automating software build processes. It uses its own XML based
syntax for defining business logic of the build process. The native
functionality of NAnt can be extended with custom
Tasks implemented
as an external .NET assemblies. However in some cases when you do not
want to develop a full scale assembly for the task that is frequently
changes or not to be reused it might be preferable to specify an
assembly in a form of C# script file or even embedded C# code
(CDATA). In fact if you can even use other (non-C#) .NET languages if
supported.
Thus CS-Script extends NAnt functionality and logically this article should belong to
Extending Applications with Scripting
chapter but it is represented here as the majority of developers would
expect any information about NAnt to be placed in the
Development Tools chapter.
This
functionality is similar, in some degree, to the NAnt <script>
task. However CS-Script implementation allows unrestricted
bi-directional data exchange between NAnt runtime and CS-Script
script code and also execution o the standalone C# files which can be
developed ans maintained outside of the NAnt environment if required.
CS-Script task can be defined in NAnt script by its name
<CSScript />:
<?xml version="1.0"?> <project name="MyProject" default="build" basedir=".">
<loadtasks assembly="CSScript.Tasks.dll"/>
<target name="scriptTest"> <CSScript file="script.cs" /> </target> ... |
CSScript task interface is very simple and supports only a few attributes:
Attribute |
Type | Description | Context | Required |
file |
string | Absolute or relative path of the script file to execute.
| No embedded C# code (CDATA) specified. | false |
method |
bool | Indicates if the embedded script code is a method definition only (true) or a full script (false). | Embedded C# code (CDATA) specified. | false |
entryPoint |
string | Defines static entry point (method name) of the script code. | Embedded C# code (CDATA) specified. | false |
verbose |
bool |
Determines whether the task should report detailed build log messages. The default is false. |
| false |
Note: CSScript task interface may very from version to
version.Executing C# script files from NAnt script
You can execute C# file by specifying its path as the
file attribute value. The C# script (as any other CS-Script script) needs to have traditional CLR assembly entry point "static Main".
Executing C# script file in isolation
NAnt script:
<?xml version="1.0"?> <project name="CSScriptTest" default="build" basedir=".">
<loadtasks assembly="CSScript.Tasks.dll"/> <target name="ioTest"> <CSScript file="script.cs" /> </target ... |
C# script (script.cs):
using System;
class Script { static public void Main(string[] args) { Console.WriteLine("Hi there"); } } |
Reading and writing project properties from the scriptIn the following code sample demonstrates how NAnt project property
strData can be accessed from the C# script. The C# script also adds a new property
data.out.value to the NAnt project.
NAnt script:
<property name="strData" value="Hi there"/> <target name="ioTest"> <CSScript file="script.data.io.cs" /> <echo message="Data returned by the task: ${data.out.value}" /> </target>
|
C# script (script.data.io.cs):
using System;
class Script { static public void Main(string[] args) { Console.WriteLine("strData = " + NAntRuntime.Project.Properties["strData"]); NAntRuntime.Project.Properties["data.out.value"] = "test return data"; } } |
Returning an error from the scriptIf
you want to return an error from the C# script you just need to throw
an exception and it will be propagated to the NAnt runtime as a task
error:
using System;
class Script { static public void Main(string[] args) { throw new Exception("The script file has raised an error."); } } |
Executing C# code from NAnt script
Executing a single C# methodYou
can execute C# code embedded as CDATA into NAnt script. With
embedded code you have an option of specifying a single method or full
scale script.
The following is an example of a single method embedded script:
<target name="methodTest"> <CSScript method="true" > <![CDATA[ public static void Task() { Console.WriteLine("Hello World (from method)"); } ]]> </CSScript> </target>
|
Note
that name of the method is irrelevant as long as it is static void
method with no arguments it will be found and executed by CSScript task.
Executing a full C# script with custom entry pointIf
you need to execute complete C# script with the class infrastructure
you can choose what static method to execute by specifying the
entryPoint attribute value:
<target name="codeTest"> <CSScript entryPoint="Task" > <![CDATA[ using System; public class Script { public static void Task() { SayHello("Hello World (from 'Task' method)"); } public static void SayHello(string greeting) { Console.WriteLine(greeting); } } ]]> </CSScript> </target>
|
Executing a full C# script with standard entry point
Should you decide to use the usual CLR assembly entry point you do not need to specify any task attributes:
<target name="codeTest"> <CSScript> <![CDATA[ using System;
public class Script { public static void Main() { SayHello("Hello World (from code)"); }
public static void SayHello(string greeting) { Console.WriteLine(greeting); } } ]]> </CSScript> </target>
|
Reading project properties from C# script
You can access NAnt project variables through
NAntRuntime.Project.Properties
as in one of the examples above but if you need only to read property
value from the script you can specify it directly in the C# code in the
traditional NAnt way:
<property name="strData" value="Hi there"/>
<target name="codeTest"> <CSScript method="true" > <![CDATA[ public static void Task() { Console.WriteLine("${strData}"); } ]]> </CSScript> </target>
|
Debugging C# scriptsYou
can trigger attaching the system CLR debugger to C# script being
executed by placing an Assert statement directly into the embedded
code:
<target name="debugTest"> <CSScript method="true" > <![CDATA[ public static void Task() { System.Diagnostics.Debug.Assert(false); Console.WriteLine(NAntRuntime.Project.Properties["strData"]); } ]]> </CSScript> </target>
|
The all samples above are taken from <cs-script>\Samples\NAnt\default.build NAnt script file.