4/25/2006 08:51:00 PM|W|P|Jay Flowers|W|P|

I have moved my blog to WordPress hosted at jayflowers.com.

New Blog Feed

|W|P|114601629846844058|W|P|Switching Blogs|W|P|4/20/2006 09:17:00 PM|W|P|Jay Flowers|W|P|

In my last post I explained a way to integrate nAnt into the IDE allowing a nAnt script in the editor or the solution explorer to be executed with a shortcut key.  I find this to be similar to macros and the command window, really somewhere in between the two.  Not quite as formal as a macro yet far more powerful than the command window.  This statement needs some support by itself you will most likely disagree with me.  I mentioned self contained projects in the last post and this is where I will start to support my statement.  Here is screenshot of the same project I was using as an example last time.

Build Directory

Notice the Packages directory is expanded.  It contains nAnt targets for all sorts of functionality.  The folder selected, VS.NETCompile, contains functionality related to compilation and VS.NET.  Below is the scratch file that was in the background of some the screenshots from the last post.

<?xml version="1.0" encoding="utf-8"?>
<
project xmlns="http://nant.sf.net/schemas/nant.xsd" name="scratch" default="test" basedir="..\Build" >
    <
loadtasks assembly=".\nAnt\bin\NAnt.Contrib.Tasks.dll" />
    <
property name="CCNetLabel" value="Dev"/>
    <
property name="CCNetProject" value="Doubler"/>
    <
property name="Compile.ConfigName" value="Release"/>
    <
include buildfile="Properties.build.xml"/>
    <
include buildfile="Common.Build.xml" />
    <
include buildfile=".\Packages\Deployment\Deployment.Target.xml"/>
    <
include buildfile=".\Packages\VS.NETCompile\Compile.Target.xml" />

    <
target name="test">
        <
property name="Compile.ConfigName" value="release"/>
        <
property name="Compile.Bin" value="${ProductDirectory}\ReleaseBin" />
        <
property name="Compile.ToCopyToBin" value="true" />
        <
property name="Compile.ToDeployZip" value="true"/>
        <
property name="Compile.ZipFileName" value="Doubler.zip"/>
        <
delete>
            <
fileset>
                <
include name="${Compile.Bin}\*.*"/>
            </
fileset>
        </
delete>
        <
call target="Private.Compile.CopyToWorkingBin" />
        <
call target="Private.Compile.DeployZip" />
    </
target>
</
project>


This script will copy files compiled under the release configuration to the ReleaseBin and make a zip file name Doubler.zip, this is something that happens during the build.  I can tap into those build scripts calling just the bits and pieces that I need to accomplish a task.  The build scripts become a library of targets that I can call on; similar to tasks but providing functioality at a higher level.  And there it is, the support for the statement that nAnt scratch is more powerful than the command window and not as formal as macros.

|W|P|114558584499303486|W|P|Scratching the Itch|W|P|4/18/2006 10:03:00 PM|W|P|Jay Flowers|W|P|

I love nAnt.  It can do so many things for me and I can get it to do those things for me so very quickly.  I do not like to leave the IDE, I try to keep the list of reasons for my leaving it short.  To help me keep that list short while still getting nAnt to pull it weight I have integrated nAnt into the IDE through the external tools feature of VS.NET.  This not a brainy thing.  I bet plenty of people have done it.  But I don’t see many and more people should.  Take a look at how I use it.  First I keep a scratch file as a solution item: Scratch.build.xml.  I edit this file to do repetitive tasks for me.

NAnt Menu Item

While I have the scratch file in focus I execute the nAnt external tool.

NAnt Command Execution

To get nAnt to show up as an external tool configure a new external tool like so:

NAnt Command Config

Some shops have self contained projects, meaning that everything the project needs to build is contained in its directory structure.  I follow this practice so nAnt is located in the project environment not in my machine environment.  This is important to note if you follow this practice too.  How will VS.NET find the nAnt.exe.  You don’t want to configure a path to a specific projects copy of nAnt.  I use bat files to start my IDE.

Scratch Dir

This OpenSolution batch file will set the PATH to include nAnt.exe.

set PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Program Files\Subversion\bin;..\Build\nAnt\bincall "C:\Program Files\Microsoft Visual Studio8\VC\vcvarsall.bat"devenv "Doubler.sln"

You may have noticed the RunScratch batch file as well.  This for situations when you need to call devenv.exe from the nAnt script. For some reason it will not compile a lick from the commanline if the IDE is open.  I don’t know why.

Something more we can do to make this easier is map a control key sequence to execute the nAnt script.  All external tool entries have a VS.NET command.  Look in the registry to find the external tool number.  On my machine nAnt is 2.

NAnt Command Reg Entry

I mapped mine to Ctrl+Shift+N.

NAnt Shortcut Keys

|W|P|114541579671192756|W|P|nAnt Scratch|W|P|4/12/2006 08:11:00 PM|W|P|Jay Flowers|W|P|

How to publish xml files for use by xsl with out merging into the ccnet build log using nAnt, xsl, and an IIS virtual directory.

Click to watch

CCNET Artifact Directory

P.S. When I say archive I mean to say artifact.

 

|W|P|114489069727292744|W|P|CCNET Artifact Directory|W|P|4/11/2006 08:51:00 AM|W|P|Jay Flowers|W|P|I have been accumulating nAnt tasks, types, and functions for a while.  I had asked on the nAnt dev group if they would like to include them but received no response.  The list seems to go through periods where users submit patches and enhancements but I see no evidence of the project leader(s) integrating them into the code line.  The project has not released in quite a long time.  So I have decided to release some nAnt extensions of my own.  A link to the release page can be found on my home page jayflowers.com.  Below is a quick example of some of the tasks, types, and functions.

<strings id="Numbers">
    <
string value="1"/>
    <
string value="2"/>
    <
string value="3"/>
    <
string value="4"/>
</
strings>

<
function execute="${stringlist::add('Numbers', '5')}"/>

<
ifthenelse test="${stringlist::contains('Numbers', '5')}">
    <
then>
        <
echo message="Added number 5 to StringList, count = ${stringlist::count('Numbers')}."/>
    </
then>
    <
elseif if="false" >
        <
echo message="This won't happen."/>
    </
elseif>
    <
else>
        <
echo message="Did not add number 5 to StringList, count = ${stringlist::count('Numbers')}."/>
    </
else>
</
ifthenelse>

<
function execute="${stringlist::remove('Numbers', '2')}"/>

<
loopthrough property="Number">
    <
items>
        <
strings refid="Numbers" />
    </
items>
    <
do>
        <
echo message="Number ${Number}!"/>
    </
do>
</
loopthrough>
|W|P|114476346465095433|W|P|A collection of nAnt goodness|W|P|4/08/2006 08:53:00 PM|W|P|Jay Flowers|W|P|

I created a custom fixture extending MbUnit some time ago.  I am just now getting around to releasing it.  I thought about contributing it to the MbUnit project but then people would only be able to use it with the next release of MbUnit on, not previous releases.  So here is the silly little home page for it.  I made a quick video of using it on a real life project from my work.  Yes we use this at my work so that should inspire some level of trust.

Click to watch

FactoryObjectFixtureVideo

|W|P|114454759228584331|W|P|MbUnit Extensions|W|P|4/07/2006 06:45:00 PM|W|P|Jay Flowers|W|P|Too often I see delimited strings being passed around in nAnt scripts and not often enough data elements.  The id and refid of data elements let you reference it.  Below is a fileset with its id set.

<fileset id="UnitTest.TestAssemblies" >
    <
include name="${UnitTest.TestPath}\**\bin\${UnitTest.TestAssemblyFormat}" />
    <
include name="${UnitTest.TestPath}\**\bin\${Compile.ConfigName}\${UnitTest.TestAssemblyFormat}" />
</
fileset>

The id can be reference later in the script like so:

<mbunit report-types="${UnitTest.ReportFormat}"
             
report-filename-format="${UnitTest.ReportNameFormat}"
             
report-output-directory="${UnitTest.ReportFolder}">
      <
assemblies refid="UnitTest.TestAssemblies" /> 
</
mbunit>

Unfortunately I see strings being used like so:

<property name="UnitTest.TestAssemblies1" value="${UnitTest.TestPath}\**\bin\${UnitTest.TestAssemblyFormat}" />
<
property name="UnitTest.TestAssemblies2" value="${UnitTest.TestPath}\**\bin\${Compile.ConfigName}\${UnitTest.TestAssemblyFormat}"/>

<
mbunit report-types="${UnitTest.ReportFormat}"
       
report-filename-format="${UnitTest.ReportNameFormat}"
       
report-output-directory="${UnitTest.ReportFolder}">
    <
assemblies>
        <
include name="${UnitTest.TestAssemblies1}"/>
        <
include name="${UnitTest.TestAssemblies2}"/>
    </
assemblies>
</
mbunit>

Even worse:

<property name="UnitTest.TestAssemblies"
value="${UnitTest.TestPath}\**\bin\${UnitTest.TestAssemblyFormat};${UnitTest.TestPath}\**\bin\${Compile.ConfigName}\${UnitTest.TestAssemblyFormat}"/>

<
foreach item="String" in="${UnitTest.TestAssemblies}" delim=";" property="UnitTest.TestAssemblyPattern">
    <
do>
        <
mbunit report-types="${UnitTest.ReportFormat}"
               
report-filename-format="${UnitTest.ReportNameFormat}"
               
report-output-directory="${UnitTest.ReportFolder}">
            <
assemblies>
                <
include name="${UnitTest.TestAssemblyPattern}"/>
            </
assemblies>
        </
mbunit>
    </
do>
</
foreach>

I wish that more tasked used data elements so that refids could be passed around.  Any thing that takes more than two attributes should consider accepting a data element instead of the attributes and three or should just pain do it.  When witting a task to use data elements be sure not feel the need to create just one data element.  Group that data that needs to be passed in to logical sets and create a data element for each set.  For example I have create PVCS Tracker tasks.  One is a task named trackerchange and needs a ticket id number (scrid), server connection information, and what fields to change to what new values.

<trackerchange scrid="">
    <
connectioninformation
       
dbmsloginmode=""
        dbmsserver=""
        dbmstype=""
        dbmsusername=""
        dbmspassword=""
        projectname=""
        username=""
        password=""/>
    <
trackerfields >
        <
field name="" value=""/>
        <
field name="" value=""/>
    </
trackerfields>
</
trackerchange>

This design allows for scripts like:

<target name="Tracker.MoveTrackersTo">
    <
call target="Private.Tracker.ConstructTrackerNote"/>

    <
foreach item="String" in="${Tracker.QueryScrList}" delim="," property="Private.Tracker.MoveTrackersTo.foreach.Id">
        <
trackergetfield scrid="${Private.Tracker.MoveTrackersTo.foreach.Id}"
               
fieldname="Submit Type"
                fieldvalueproperty="Private.Tracker.MoveTrackersTo.foreach.SubmitType">
            <
connectioninformation refid="Tracker.Connection"/>
        </
trackergetfield>

        <
if test="${Private.Tracker.MoveTrackersTo.foreach.SubmitType == 'Unit Test'}">
            <
trackerchange scrid="${Private.Tracker.MoveTrackersTo.foreach.Id}">
                <
trackerfields refid="Tracker.UnitTest" />
                <
connectioninformation refid="Tracker.Connection"/>
            </
trackerchange>
        </
if>

        <
ifnot test="${Private.Tracker.MoveTrackersTo.foreach.SubmitType == 'Unit Test'}">
            <
trackerchange scrid="${Private.Tracker.MoveTrackersTo.foreach.Id}">
                <
trackerfields refid="Tracker.ChangeFields" />
                <
connectioninformation refid="Tracker.Connection"/>
            </
trackerchange>
        </
ifnot>

        <
trackeraddnote title="${Tracker.NoteTitleForMoveTrackersTo}"
               
text="${Private.Tracker.NoteForMoveTrackersTo}"
                scrid="${Private.Tracker.MoveTrackersTo.foreach.Id}" >
            <
connectioninformation refid="Tracker.Connection"/>
        </
trackeraddnote>
    </
foreach>
</
target>

Notice that the connection information is referenced four times and only one line for each.  This far more readable than using properties and attributes.  It is easier to maintain as well.|W|P|114445351792169667|W|P|nAnt id and refid|W|P|4/07/2006 06:15:00 AM|W|P|Jay Flowers|W|P|So I kinda dropped of the face of the blog sphere back in December.  I had to focus on Family and work.  The situation seems to have changed on both fronts so you should see more of my effort in my blog and my web site. |W|P|114440850769923940|W|P|Back in the Saddle|W|P|