Open Source .NET Development [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Open Source .NET Development [Electronic resources] - نسخه متنی

Brian Nantz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


Data Types


In addition to the syntax of the build files, there are several useful datatypes in NAnt. These datatypes can change the way a task functions and can simplify complex actions.

Fileset


Frequently, a build operates on a file: it compiles a file, copies a file, deletes a file, and so forth. A fileset is a set or collection of files to apply an operation to. For example, look at the copy task's use of filesets:

<copy todir="release">
<fileset basedir="bin">
<includes name="*.*"/>
<excludes name="*.pdb"/>
<excludes name="*.obj"/>
</fileset>
</copy>

This code will copy all files except .pdb and .obj from the bin directory to the release directory.

Patternset


Patternsets allow modification to a fileset based on a pattern (see Table 4.1).

Table 4.1. Patternsets

Pattern

Description

*

Wildcard, matches 1 or more characters

?

Wildcard, matches 1 character

**

When used for a directory, this includes all subdirectories.

Trailing / or \

Implies a trailing **

Applying a patternset to the csc's (C# compiler task) sources fileset is demonstrated in Listing 4.2:

Listing 4.2. Patternsets with the csc Task

<csc target="library" debug="${debug}" output="${releasedir}\LogKit.Net.dll" doc="${docdir
}\LogKit.Net.xml">
<sources basedir="..\src\org\apache\log">
<includes name="**/*.cs" />
</sources>
<references>
<includes name="System.dll" />
<includes name="System.Collections.dll" />
<includes name="System.Data.dll" />
</references>
<arg value="/nowarn:1591" />
</csc>

This compiles all C# files under the ..\src\org\apache\log directory.

Optionsets


An optionset is an alternative way for a task to receive input. Typically, tasks use XML attributes to receive input, but this doesn't always make sense. Consider the SlingshotTask's use of an optionset:

<slingshot solution="MySolution.sln" format="nant" output="MySolution.build">
<parameters>
<option name="build.basedir" value="..\bin"/>
</parameters>
</slingshot>

Environment Variables


By using the <sysinfo> task, you can access any environment variables in the build. Listing 4.3 is an example of using system environment variables:

Listing 4.3. The sysinfo Task

<sysinfo verbose="true"/>
<copy todir="${sys.env.BASEDIR}"> _ Copy to a directory set in
<fileset basedir="bin"> the environment.
<includes name="*.dll"/>
<includes name="*.exe"/>
</fileset>
</copy>

Properties


Properties allow for changing the behavior of a build, just as properties on a component alter that component's behavior (see Executing NAnt" in this chapter).

Table 4.2. Built-in NAnt Properties

Property Name

Explanation

${nant.version}

The version of NAnt.

${nant.filename}

The full path to the NAnt assembly.

${nant.location}

The location of the nant.exe file.

${nant.onsuccess}

Properties to target names that you want executed when the build file is done.

${nant.onfail}

Properties to target names that you want executed when the build file is done.

${nant.project.basedir}

The absolute path of the project's basedir.

${nant.project.buildfile}

The absolute path of the buildfile.

${nant.project.name}

The name of the project.

${nant.project.default}

The name of the project's default target.

${nant.task.*}

Each task available to nant has a "true" value, e.g., nant.task.copy.

${nant.settings.currentframework.frameworkassemblydirectory}

The fully qualified path to the current .NET framework global aasembly cache.

${nant.settings.currentframework.name}

The name of the current .NET framework.

${nant.settings.currentframework.version}

The current .NET framework version.

${nant.settings.currentframework.description}

The description of the current .NET framework.

${nant.settings.currentframework.csharpcompilername}

The C# compiler for the current CLI framework.

${nant.settings.currentframework.resgentoolname}

The resgen tool for the current CLI framework.

${nant.settings.currentframeworkframeworkdirectory}

The fully qualified path to the current .NET framework directory.

${nant.settings.currentframework.runtimeengine}

The runtime engine for the current CLI framework.

${nant.settings.currentframework.sdkdirectory}

The fully qualified path to the current .NET sdk directory.

Handling Multiple Versions of .NET

Through the use of the nant.settings.currentframework.version property, you can safeguard your builds against a user who has the wrong version of the .NET runtime.

References

The version of .NET used to compile mainly affects what .NET framework assemblies are used as references in the compiler task. Listing 4.4 shows a common use of reference filesets.

Listing 4.4. Filesets

<csc target="library" output="${output}" debug="${debug}" define="${define}" doc="${doc}">
<sources>
<includes name=" *.cs" />
</sources>
<references>
<includes name="System.dll" />
<includes name="System.Data.dll" />
<includes name="System.Drawing.dll" />
<includes name="System.Windows.Forms.dll" />
<includes name="System.Xml.dll" />
<includes name="Accessibility.dll" frompath="true" />
<includes name="System.Web.dll" />
<includes name="System.Web.Services.dll" />
</references>
</csc>

For a second, I want to take a brief sidetrack and talk about how NAnt knows to compile C# code. Currently, the NAnt csc task wraps the command-line compiler, but how does it know where to find that compiler, you might ask? That is a great question. The csc task in Listing 4.5 will compile using the default framework version of .NET (or other CLI implementation) that is specified in the nant.exe.config. The first frameworkinfo element is complete, and the following ones are abbreviated just to show you the CLI frameworks supported by NAnt.

Listing 4.5. Configuration File Showing NAnt CLI Framework Support

<nantsettings
defaultframework="net-1.0">
<frameworks>
<frameworkinfo

name = "net-1.0"

description = "Microsoft .NET Framework 1.0"
version = "1.0.3705"
runtimeengine="
csharpcompilername = "csc"
basiccompilername = "vbc"
jsharpcompilername = "vjc"
jscriptcompilername = "jsc"
resgenname = "resgen">
<sdkdirectory useregistry="true" regkey="Software\Microsoft\.NetFramework"
regvalue="sdkInstallRoot" />
<frameworkdirectory useregistry="true" regkey="Software\Microsoft.NetFramework" regvalue="InstallRoot" />
<frameworkassemblydirectory useregistry="true" regkey="Software\Microsoft.NetFramework" regvalue="InstallRoot"/>
</frameworkinfo>
<frameworkinfo

name = "net-1.1"

description = "Microsoft .Net Framework 1.1"
...
</frameworkinfo>
<frameworkinfo

name = "netcf-1.0"

description = "Microsoft .Net Compact Framework Framework 1.0"
...
</frameworkinfo>
<frameworkinfo

name = "mono-1.0"

description = "gnome projects port of the .Net Framework"
...
</frameworkinfo>
</frameworks>

NOTE

Regarding the nant.exe.config in Listing 4.5, if you get an error from NAnt saying that it cannot find the DefaultFramework, then you know right where to go: the config file.

OK, back to the references discussion. The references in Listing 4.4 would be the same as using the asis parameter and setting it to true, as seen here:

<includes name="System.dll" asis="true" />

Unfortunately, filesets do not handle relative paths very well, so if you are using a third-party assembly like Log4Net, then you have to do something different. The following relative path will NOT always work, depending upon what the basepath is.

<includes name="..\..\log4net.dll" />

In order to include this assembly reference, you can either use the basedir property on the references fileset:

<references basedir="${build.dir}/bin">
<includes name=" log4net.dll" />.
</references>

use the frompath property on the include node:

<includes name=" log4net.dll" frompath="true" />

or read the path from the environment variables:

<includes name=" ${sys.env.AssemblyDirectory}\log4net.dll" />

Handling Multiple Versions of NAnt

Similarly to multiple versions of .NET, you may run into a problem with a user who has an outdated version of NAnt. Depending on the tasks used in your build, this could either produce the wrong result or cause a NAnt build exception for a missing task. If this is a concern, check the nant.version property and ensure it is at least the version you require.

Embedded Scripting

Although not technically a property, the example of Embedded Scripting fits well under this section of the chapter. For the truly advanced user who wants functionality that NAnt just does not support, there is an answer: Embedded Scripting. NAnt allows for embedded C# and VB.NET scripts to be executed within a target. Most often the base tasks within NAnt are sufficient enough, and embedded scripts are not needed. The danger of embedded scripts is that the code is obviously unique and has the potential for bugs. In contrast, the tasks that are intrinsic to NAnt have a considerable runtime and testing user base. Listing 4.6 is from the NAnt WIKI site (http://nant.sourceforge.net/wiki/) and lists all available properties.

Listing 4.6. NAnt Scripting

<script language="C#">
<code><![CDATA[
public static void ScriptMain(Project project)
{
Log.WriteLine("Properties:");
foreach(DictionaryEntry entry in project.Properties)
{
Log.WriteLine(string.Format("{0}={1}", entry.Key, entry.Value));
}
}
]]></code>
</script>

Error Handling

When an error occurs in a NAnt build, the build automatically fails and does not continue. The output to the command window will indicate what line the build failed on. If the failure is a compiler error, the offending code's line number is given. NAnt provides two special properties for handling error conditions in a build project: nant.onsuccess and nant.onfailure. Listing 4.7 shows the use of nant.onfailure to email a failure report.

Lisitng 4.7. Emailing Failures

<property name='nant.onfailure' value='emailfailure'>
<target name="email failure">
<mail
from="buildmaster "
tolist="devgroup@yourdomain.com"
cclist="
subject="Build Failed"
message=" Build Failed "
mailhost="mail.yourdomain.com" />
</target>

The value of the onfailure task is the name of task in the existing project that you want to execute on a failure.

Logging

Chapter 8, "Application Logging") to log to an output file. This will log the messages that are put to the screen. Some tasks may include more logging information than others, but you can always use the <echo> task to indicate milestones in the build. Used together with error handling, Listing 4.7 can be extended to include emailing the results of the build, as in Listing 4.8.

Listing 4.8. Emailing Build Results

<property name='nant.onfailure' value='failure'>
<property name='nant.onfailure' value='success>
<target name="success">
<property name='emailsubjet' value='Build Success'>
<property name=' emailmessage' value='Build Succeeded.'>
<call target="email">
</ target>
<target name="failure">
<property name='emailsubjet' value='Build Failed'>
<property name=' emailmessage' value='Build Failure See attached log.'>
<call target="email">
</ target>
<target name="email ">

<mail

from="buildmaster "

tolist="devgroup@yourdomain.com"

cclist="

subject="${emailsubjet}"

message=" ${emailmessage}"

file="build.log"

mailhost="mail.yourdomain.com" />
</target>

To set the location of the build file's log, look back to the section "Executing NAnt."


    / 275