These structures are a good starting point for creating and managing assets through the
process, and are again similar to the structure of the build file skeleton and the build use case
itself.
Now let us move on to the first part of the process: creating the build file.
Creating the Build File
In Chapter 2 we proposed a skeleton for the build file. Using that skeleton, we can make some
initial system-specific changes to detail our intent for the build file. Also, we can give the build
file a more informative name. In this case, we will call it Transformer.Build.xml.
Finally, reviewing the skeleton once more allows us to identify the areas that we need to
complete.
Note
At this point I have dropped the .buildextension from the file-naming conventions.This is
because we will not always be “building”but perhaps performing other activities.I will use .xmlfor the
names from now on (otherwise,Transformer.Deploy.buildcould be a little confusing ...).
<?xml version="1.0" encoding="utf-8" ?> 
<project name="Transformer" default="help">
<description>Build file for the Transformer application.</description>
<property name="nant.onfailure" value="fail"/>
<target name="go" 
description="The main target for full build process execution."
depends="clean, get, version, build, test, document, publish, notify"
/>
<target name="clean" description="Clean up the build environment.">
</target>
<target name="get" description="Grab the source code.">
</target>
<target name="version" 
description="Apply versioning to the source code files.">
</target>
<target name="build" description="Compile the application.">
</target>
<target name="test" description="Apply the unit tests.">
</target>
CHAPTER 4 A SIMPLE CASE STUDY
100
Batch convert pdf to jpg - Convert PDF to JPEG images in C#.net, ASP.NET MVC, WinForms, WPF project
How to convert PDF to JPEG using C#.NET PDF to JPEG conversion / converter library control SDK
convert pdf to jpg for; convert online pdf to jpg
Batch convert pdf to jpg - VB.NET PDF Convert to Jpeg SDK: Convert PDF to JPEG images in vb.net, ASP.NET MVC, WinForms, WPF project
Online Tutorial for PDF to JPEG (JPG) Conversion in VB.NET Image Application
convert multiple page pdf to jpg; convert pdf to jpg converter
<target name="document" description="Generate documentation and reports.">
</target>
<target name="publish" 
description="Place the compiled assets in agreed location.">
</target>
<target name="notify" 
description="Tell everyone of the success or failure.">
</target>
<target name="fail">
</target>
<target name="help">
<echo message="The skeleton file for the build process ➥
is designed to execute the following targets in turn:"/>
<echo message="-- clean"/>
<echo message="-- get"/>
<echo message="-- version"/>
<echo message="-- build"/>
<echo message="-- test"/>
<echo message="-- document"/>
<echo message="-- publish"/>
<echo message="-- notify"/>
</target>
</project>
With the specific descriptions of the project in place, we can move on to the details of
each target. But before we do, we should consider a very important question: What if it all goes
wrong?
Error Handling in NAnt
NAnt was not designed as a robust platform for error handling. It does not have notions of
such things as try-catchconstructs, though it does have a basic idea of an On Error Goto
construct, which may bring a tear to the eye of any VB 6–using reader.
NAnt has two properties (which we discussed briefly in Chapter 2) that can be used to
perform actions upon either a successful or failed execution of the build script. These proper-
ties are called nant.onsuccessandnant.onfailure, respectively. 
In terms of error handling, the property we are interested in is nant.onfailure. This prop-
erty is set as follows:
<property name="nant.onfailure" value="dosomething"/>
The value dosomethingmust be a target of the same name in the current script, or the
build script will not execute. Effectively, using this setting means that if the build script fails
during execution, the target dosomethingwill be called before the failure is reported and
CHAPTER 4 A SIMPLE CASE STUDY
101
C# Create PDF from images Library to convert Jpeg, png images to
Batch convert PDF documents from multiple image formats, including Jpg, Png, Bmp, Gif, Tiff, Bitmap, .NET Graphics, and REImage.
convert pdf images to jpg; convert pdf file to jpg format
VB.NET PDF Convert to Images SDK: Convert PDF to png, gif images
VB.NET components for batch convert high resolution images from PDF. Convert PDF documents to multiple image formats, including Jpg, Png, Bmp, Gif, Tiff, Bitmap
change pdf into jpg; convert pdf pictures to jpg
execution stops. This gives you the opportunity to perform some corrective action or other
similar activity, such as a mail task to notify someone of the error. You should be aware of
some specific points about this property. Consider the following script:
<?xml version="1.0" encoding="utf-8" ?> 
<project name="ErrorHandlingExample" default="DoomedToFail">
<target name="DoomedToFail">
<property name="nant.onfailure" value="GiveUp"/>
<fail message="This target is not going to work"/>
</target>
<target name="GiveUp">
<echo message="I give up, I really do."/>
<call target="CleanUp1"/>
<call target="CleanUp2"/>
</target>
<target name="CleanUp1">
<echo message="Doing CleanUp1..."/>
<property name="nant.onfailure" value="CleanUp2"/>
<fail/>
</target>
<target name="CleanUp2">
<echo message="Doing CleanUp2..."/>
</target>
</project>
The target DoomedToFailmakes use of the onfailureproperty to target GiveUpto perform
corrective action. Immediately afterwards we call the <fail>task to throw a BuildException,
which will cause the GiveUptarget to be called.
TheGiveUptarget is then used to call two corrective targets, CleanUp1andCleanUp2. This is
a legal use of the onfailuretarget. 
However, in CleanUp1we then use the onfailuretarget again to target CleanUp2(which
will be called anyway by the GiveUptarget). Then we cause CleanUp1to fail. The CleanUp2target
is never called, though. This is because subsequent to the first failure, no other failure can be
accounted for and execution halts immediately. It is not possible to “chain” error handling in
any way. Therefore, it is important that the corrective steps that you require will not fail them-
selves, or otherwise the error handling is fairly pointless. The output of running the script is as
follows:
---------- NAnt ----------
NAnt 0.85 
Copyright (C) 2001-2004 Gerry Shaw
http://nant.sourceforge.net
CHAPTER 4 A SIMPLE CASE STUDY
102
JPEG to PDF Converter | Convert JPEG to PDF, Convert PDF to JPEG
JPEG to PDF Converter is able to convert image files to PDF directly without the software Adobe Batch conversion is supported by JPEG to PDF Converter.
convert from pdf to jpg; best way to convert pdf to jpg
JPG to GIF Converter | Convert JPEG to GIF, Convert GIF to JPG
speed JPEG to GIF Converter, faster than other JPG Converters; output files with high good quality; Batch process mode support; let you convert a hundred of
convert pdf to jpeg; best pdf to jpg converter online
Buildfile: file:///ErrorHandlingExample.xml
Target(s) specified: DoomedToFail 
DoomedToFail:
GiveUp:
[echo] I give up, I really do.
CleanUp1:
[echo] Doing CleanUp1...
[call] ErrorHandlingExample.xml(20,7):
[call] No message.
BUILD FAILED - 1 non-fatal error(s), 0 warning(s)
ErrorHandlingExample.xml(8,7):
This target is not going to work
Total time: 0 seconds.
Output completed (1 sec consumed) - Normal Termination
We can see in the output that following the second failure (in target CleanUp1) halts the
script execution immediately; target CleanUp2is never called.
The net result of this is that there is some utility to the error handling in NAnt—but not to
the extent that it provides robust rollbacks, transaction reversals, and so on. 
We will see a suitable use of the onfailureproperty when we look at the testing part of the
build script for the Transformer application in just a little while. So, after a pessimistic start to
proceedings, let us move on to the real work.
Clean
The first section for attention is the Cleantarget. In this particular target, we will clean out
existing content ready for the execution of the build file. The only folder we want to persist is
thepublishfolder, since this will contain artifacts from prior builds.
After we have removed the old material, we will then set about re-creating the environ-
ment as necessary. 
These particular actions are quite straightforward. The following code shows the target as
required:
<target name="clean" description="Clean up the build environment.">
<delete dir="D:\dotNetDelivery\BuildArea\Source\" failonerror="false"/>
<delete dir="D:\dotNetDelivery\BuildArea\Output\" failonerror="false"/>
<delete dir="D:\dotNetDelivery\BuildArea\Docs\" failonerror="false"/>
<delete dir="D:\dotNetDelivery\BuildArea\Reports\" failonerror="false"/>
<delete dir="D:\dotNetDelivery\BuildArea\Distribution\" failonerror="false"/>
CHAPTER 4 A SIMPLE CASE STUDY
103
JPG to DICOM Converter | Convert JPEG to DICOM, Convert DICOM to
Select "Convert to DICOM"; Select "Start" to start conversion How to Start Batch JPEG Conversion to DICOM. JPEG to DICOM Converter first; Load JPG images from
best pdf to jpg converter for; convert pdf to jpg 100 dpi
JPG to JBIG2 Converter | Convert JPEG to JBIG2, Convert JBIG2 to
Ability to preserve original images without any affecting; Ability to convert image swiftly between JPG & JBIG2 in single and batch mode;
change pdf to jpg format; change pdf file to jpg file
<mkdir dir="D:\dotNetDelivery\BuildArea\Source\"/>
<mkdir dir="D:\dotNetDelivery\BuildArea\Output\"/>
<mkdir dir="D:\dotNetDelivery\BuildArea\Docs\"/>
<mkdir dir="D:\dotNetDelivery\BuildArea\Reports\"/>
<mkdir dir="D:\dotNetDelivery\BuildArea\Distribution\"/>
<mkdir dir="D:\dotNetDelivery\BuildArea\Publish\" failonerror="false"/>
</target>
The core aspects of this target are as follows:
failonerror. Most of the time it is acceptable, and usually desirable, for a build file to fail
when a task fails. In this target, though, this is not the case. We are performing create and
delete actions against assets that may not exist. For instance, suppose we were to run the
build file for the first time without having created the initial environment; the delete tasks
would therefore fail. Or suppose we are not sure that we have created the publishfolder
(but we mayhave), so we need to make sure that there is no problem in the event the
folder does already exist.
publish.We do not attempt to delete the publish folder; we just want to create it in the
event it does not already exist.
Running this script should cause no problems and will generate a clean environment
ready for use.
Checkout/Get
This particular target takes care of an important task—the retrieval of the source code from
the VSS database—in a very simple way. The NAntContrib task <vssget>is all we need to satis-
factorily complete this step in the process. The code for the target is as follows:
<target name="get" description="Grab the source code.">
<vssget
user="builder"
password="builder"
localpath="D:\dotNetDelivery\BuildArea\Source\"
recursive="true"
replace="true"
dbpath="D:\dotNetDelivery\VSS\srcsafe.ini"
path="$/Solutions/Transformer/"
/>
</target>
The attribute values for the task are quite self-explanatory. Notice that we use the builder
user account to access the VSS database. We then only grab the particular solution we are
interested in and place it into the specified sourcefolder of the build area.
In order to use the NAntContrib tasks, we must use the <loadtasks>task to load the NAnt-
Contrib tasks as follows:
CHAPTER 4 A SIMPLE CASE STUDY
104
JPG to Word Converter | Convert JPEG to Word, Convert Word to JPG
Select "Convert to Word"; Select "Start" to start conversion How to Start Batch JPEG Conversion to Word. Open JPEG to Word Converter first; Load JPG images from
change pdf to jpg; convert pdf file to jpg format
JPG to JPEG2000 Converter | Convert JPEG to JPEG2000, Convert
Select "Convert to JPEG2000"; Select "Start" to start conversion How to Start Batch JPEG Conversion to JPEG2000. to JPEG2000 Converter first; ad JPG images from
pdf to jpg converter; bulk pdf to jpg
<loadtasks
assembly="D:\dotNetDelivery\Tools\NAntContrib\0.85rc1\bin\➥
NAnt.Contrib.Tasks.dll"
/>
<loadtasks
assembly="D:\dotNetDelivery\Tools\NUnit2Report\1.2.2\bin\➥
NAnt.NUnit2ReportTasks.dll"
/>
I have also included the <loadtasks>task for the NUnit2Report that we will use later in
the script. Both of these tasks appear in the build script at the beginning of the script following
the property declarations. There is no point in processing much of the script only to find that
crucial assemblies are missing.
Version
We must provide versioning for the code. Because the version number of an assembly is man-
aged by attributes on the assembly, we need to know the versioning and application of the
version number prior to compiling the code. We also need to use the version number again
later on in the process.
We will use a combination of tasks to achieve the desired results through a series of steps.
Maintaining a Version Number
Before we apply a version number, we want to be sure that we can adequately maintain ver-
sion number information. 
NAntContrib provides a task specifically for this purpose: <version>. This task reads the
content of a text file (by default, this file is called build.number) and updates the version num-
ber based on the strategy marked by the buildtypetask attribute. Once done, the task sets a
property (by default sys.version) with the required version number. This can then be used in
the build file.
The<version>task can use a number of strategies. The one I have selected here is to
increment the buildnumber of the version number, so that my first build is 1.0.1.0, then
1.0.2.0, and so on. This is achieved with the following code:
<version 
buildtype="increment" 
revisiontype="increment" 
path="Transformer.Build.Number" 
/>
Notice that I have also changed the default file to Transformer.Build.Numberto improve
its identity. This file simply contains the text “1.0.0.0” and will be managed by the process
from now on. If we wish to change the numbers—for example, to represent a major or minor
release—we will need to edit the file.
Before we move on, we want to make one more point. As we begin the debugging of the
build file and attempt to run the process successfully, the build number will be incremented
as we hit this target. In some cases, we can test the targets in isolation, but not always. We do
not really want to impact the version numbers because of unsuccessful debugging runs.
CHAPTER 4 A SIMPLE CASE STUDY
105
Note
This is different from a failed build.It may not be a problem to increment the version when the
build itself fails for some reason.I am talking specifically about the construction and debugging phase of
thebuild file.
So, in order to ensure there is no increment during debugging, we can add a test for a debug
property setting, and also provide a default debugging value of the sys.versionproperty—in
this case I have decided on “0.0.0.0” as a suitable number. The code for this looks like this:
<property name="sys.version" value="0.0.0.0"/>
<ifnot test="${debug}">
<version 
buildtype="increment" 
revisiontype="increment" 
path="Transformer.Build.Number" 
/>
</ifnot>
We can be sure now that version numbers are incremented only when required. The
result of this test is that we need to include a Boolean debugproperty when running the script.
We can enter this information into the helptarget with the addition of the following messages:
<echo message="This file should be run with a Boolean value for 'debug'."/>
<echo message="-- True indicates that no versioning be set (0.0.0.0)."/>
<echo message="-- False indicates that a regular version be set(1.0.x.0)."/>
<echo message="Example: -D:debug=true"/>
Versioning the Assemblies
Now that we have the version number, we can apply it to the code for the assemblies we are
going to compile. As we know, VS .NET creates a file containing Assembly-level attributes
when we create a project in the integrated development environment (IDE). By convention
this file is called AssemblyInfo.cs, but of course this is just for organization and convenience.
Inside the file are a number of attributes that are ready to be used:
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyVersion("1.0.*")]
The last attribute is the one that is of interest to us, though we can make use of the others
as well. All we need to do is overwrite the AssemblyVersionattribute with our version number.
Fortunately, NAnt provides a task called <asminfo>that can do just that. We just need to point
the task to the correct location of the AssemblyInfo.csfile. 
The problem with this is that we potentially need to do this several times to update sev-
eral assemblies. We can use VS .NET to improve this effort. 
CHAPTER 4 A SIMPLE CASE STUDY
106
If we create a file called, say, CommonAssemblyInfo.cs, under Solution Items in VS .NET and
then link it to the other projects in the solution, we can achieve the effects of versioning and
perform the task only once. 
This is done by adding the required attributes to CommonAssemblyInfo.csand then remov-
ing the same attributes from the individual AssemblyInfo.csfiles of each project. In the sample
application,CommonAssemblyInfo.cscontains the following code:
using System;
using System.Reflection;
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyVersion("1.0.*")]
Note
We will be replacing this information shortly,so there is no need to worry about the actual settings
in the file at this point,as long as the solution actually builds,of course.
The three attributes are removed from each AssemblyInfo.csfile. 
Following this, the CommonAssemblyInfo.csfile is linked to the other projects. Figure 4-5
shows how this is done by using the Add Existing option and then the Link File option in the
file browser window. On the right you can see how the solution looks after the linking process.
Notice the slightly different icons representing the linked CommonAssemblyInfo.csfile.
With the link formed, we need to perform the update to the CommonAssemblyInfo.csfile.
The<asminfo>task detail looks like this:
<asminfo 
output="D:\dotNetDelivery\BuildArea\Source\CommonAssemblyInfo.cs" 
language="CSharp">
<imports>
<import name="System" />
<import name="System.Reflection"/>
</imports>
<attributes>
<attribute type="AssemblyVersionAttribute" value="${sys.version}"/>
<attribute type="AssemblyProductAttribute" value="Transformer" />
<attribute 
type="AssemblyCopyrightAttribute" 
value="Copyright (c) 2005, Etomic Ltd."
/>
</attributes>
</asminfo>
CHAPTER 4 A SIMPLE CASE STUDY
107
The structure of this task is reminiscent of the actual code, and in effect all this task is
doing is writing out the code declared in the task. Notice that I have used the sys.version
property as the value for the assembly version attribute. I have also provided other standard
information to the compiled assemblies. Several other options can be found in the NAnt
documentation.
Since we have obtained the source code from VSS, the CommonAssamblyInfo.csfile is actu-
ally read-only. In order to perform the action described, we must alter the file to read-write
and then back again so as not to confuse ourselves (and potentially NAnt). We can use the
<attrib>task for this:
<attrib
file="D:\dotNetDelivery\BuildArea\Source\CommonAssemblyInfo.cs" 
readonly="false" 
/>
<!-- ASMINFO TASK SNIPPED -->
<attrib 
file="D:\dotNetDelivery\BuildArea\Source\CommonAssemblyInfo.cs" 
readonly="true" 
/>
CHAPTER 4 A SIMPLE CASE STUDY
108
Figure 4-5.Linking CommonAssemblyInfo.cs
Labeling VSS
There are two other aspects to versioning apart from the assemblies themselves. The first is
the labeling of the published assets. We will handle this in the Publish step. The second is the
labeling of the VSS database.
At this point, we do not perform any other action with VSS, but in future scripts we may
want to manipulate assets in VSS later in the process. Therefore, we do not want to update the
VSS label until later. We can split the versiontarget into two sections: version1andversion2.
version1contains all of the work up until this point, such as obtaining a number and
rewriting CommonAssemblyInfo.cs.version2will contain directions for updating the VSS
database.
<target name="version2">
<ifnot test="${debug}">
<vsslabel
user="builder"
password="builder"
dbpath="D:\dotNetDelivery\VSS\srcsafe.ini"
path="$/Solutions/Transformer/"
comment="Automated Label"
label="NAnt - ${sys.version}"
/>
</ifnot>
</target>
The label we want to apply is “NAnt - 1.0.x.0,” which corresponds to the version marked
on the assemblies and aids the versioning process. I have also included a test for the debug
property so that the version 0.0.0.0 is not labeled throughout the VSS database when we are
debugging the script, which would also be confusing.
All of this scripting means that the assembly will be versioned as required when the code
is compiled in the next step. It has taken longer to explain the necessary steps than it takes to
actually implement the solution. The full script for the version1target follows:
<target name="version1" description="Apply versioning to the source code files.">
<property name="sys.version" value="0.0.0.0"/>
<ifnot test="${debug}">
<version 
buildtype="increment" 
revisiontype="increment" 
path="Transformer.Build.Number"
/>
</ifnot>
<attrib 
file="D:\dotNetDelivery\BuildArea\Source\CommonAssemblyInfo.cs"
readonly="false" 
/>
<asminfo 
output="D:\dotNetDelivery\BuildArea\Source\CommonAssemblyInfo.cs"
CHAPTER 4 A SIMPLE CASE STUDY
109
Documents you may be interested
Documents you may be interested