Using NAnt filterchain to instantiate multiple template files - nant

I have a set of template files like
<!-- #TEMPLATE# -->
<!-- #DONOTEDIT# -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>SuperDuper #VARIANT#</title>
</head>
<body>
...
#PRODUCTCODENAME#
...
</body>
which I want to deploy using NAnt so that the embedded keywords are instantiated, as in
<target name="deployTemplates">
<property name="_buildstamp" value="${DestDir}/templates_buildstamp"/>
<uptodate property="_uptodate" verbose="${Verbose}">
<sourcefiles basedir="${TemplateDir}">
<include name="**"/>
</sourcefiles>
<targetfiles>
<include name="${_buildstamp}"/>
</targetfiles>
</uptodate>
<if test="${not _uptodate}">
<copy todir="${CourseDestDir}" verbose="${Verbose}" overwrite="True">
<!-- Have to specify the fileset again to maintain directory structure. -->
<fileset basedir="${TemplateDir}">
<include name="**"/>
</fileset>
<filterchain>
<replacetokens>
<token key="DONOTEDIT" value="Do not edit, will be overwritten."/>
<token key="PRODUCTCODENAME" value="${Product}"/>
<token key="VARIANT" value="${Variant}"/>
</replacetokens>
</filterchain>
</copy>
<touch file="${_buildstamp}"/>
</if>
</target>
but how do I embed the name of the individual template files in each deployed file, that is, get #TEMPLATE# replaced by the location of the template file so that others will know where to make permanent changes?

Looking into NAnt source code and <filterchain> documentation - you will have to implement a custom Filter, which makes the current file name available for replacements. The existing filters do not expose this information.

Related

Ant search in text file some text expression

Ant search in text file some text expression, if it NOT found I try to delete file that txt was. So my code in Ant is down, but I don't know how put NOT correctly
<target name="ifDelete">
<if>
<length when="greater" length="0">
<fileset file="MyText.txt">
<!--containsregexp negate="true"-->
<containsregexp expression="findME" />
<!--/containsregexp-->
</fileset>
</length>
<then>
<delete includeemptydirs="true">
<fileset dir="FileIgonnaDelete">
</fileset>
</delete>
</then>
</if>
</target>
To search and delete - means seek and destroy - files in a fileset that do not contain a specific text, use something like :
<delete verbose="true">
<fileset dir="rootdir/to/search" includes="**/*.txt">
<not>
<contains text="findMe"/>
</not>
</fileset>
</delete>
you may use one or more nested resource collections (fileset, dirset ...) within delete.
see Ant manual delete, fileset and selectors for details.

Is it possible to use run-jetty-run's eclipse plugin to debug this app?

Theres about 20 diff ant files, that make up the build. Im not sure how to configure run-jetty-runs eclipse plugin to use this information. Can anyone point me towards a tutorial or some documentation:
<target name="run-jetty" depends="build" description="Runs application in included Jetty container">
<property file="credentials.properties" />
<property name="jetty.port" value="8080" />
<java jar="${jetty.dir}/start.jar" fork="true" dir="${basedir}" maxmemory="512M">
<arg value="${jetty.conf.dir}/jetty.xml" />
<arg value="${jetty.conf.dir}/jetty-jndi.xml" />
<sysproperty key="jetty.port" value="${jetty.port}" />
<jvmarg value="-XX:MaxPermSize=128m" />
<jvmarg value="-Dfile.encoding=UTF-8" />
<jvmarg value="-Djetty.home=${jetty.dir}" />
<jvmarg value="-Djetty.datasource.lanter.username=${jetty.datasource.lanter.username}" />
<jvmarg value="-Djetty.datasource.lanter.password=${jetty.datasource.lanter.password}" />
<jvmarg value="-Djetty.datasource.vs.username=${jetty.datasource.us.username}" />
<jvmarg value="-Djetty.datasource.vs.password=${jetty.datasource.us.password}" />
<jvmarg value="-DSTOP.PORT=${jetty.stop.port}" />
<jvmarg value="-DSTOP.KEY=${jetty.stop.key}" />
</java>
</target>
You have two options:
Start the app using the run-jetty-run plugin; this will give you an entry in the debug menu which means that Jetty (and the app) will be launched in the debugger if you select it.
Use the information in the code block above to create your own run configuration. The classpath should already be correct; you just need to select the correct main class (open META-INF/MANIFEST.MF in start.jar to find that out). Replace all the properties with their values and put each into a new line into the argument text fields of the run configuration.
On the tab "Common", you can set a file name and save the launch config as a file in your project, so everyone working on it will get it.

run nunit tests with TestCase Attribute from nant

i was using this nant task for my nunit tests.
<nunit2 failonerror="false">
<formatter usefile="true"
outputdir="build"
type="Xml"
extension=".xml"/>
<test>
<assemblies>
<include name="Build/*.Tests.dll"/>
</assemblies>
<references >
<include name="Tools/**/*.dll"/>
<include name="Build/*.dll"/>
</references>
</test>
</nunit2>
It had the nice benefit that I could use it in multiple projects without changing anything. The problem is that it seems to be ignoring the TestCase and ExpectectException attributes on some of my tests causing them to fail. I've seen the suggestion to use the exec task to call nunit-console.exe, but then I have to specify all of the test dll's individually. Which means I can no longer use it in all of my projects without having to edit it. I'd all so have to edit it any time I add a test project to one of my solutions.
Is there any way to get the best of both worlds?
You can use <foreach> to run your tests:
<foreach item="File" property="test-assembly">
<in>
<items>
<include name="${binaries-dir}/*" />
</items>
</in>
<do>
<exec program="${nunit.exe}" workingdir="${binaries-dir}"
managed="true">
<arg value="/nologo" />
<arg value="${test-assembly}" />
</exec>
</do>
</foreach>

In nant, how to delete contents of a directory, but not the directory itself?

Suppose I were scripting a deployment using nant on a Windows server to a file share: \\server\share. I want a nant script to delete all files from the share then copy in new files.
I have this code to delete the files, but I'm getting an error that it can't delete "\server\share". But I didn't want to delete the share, just the contents in it.
<delete>
<fileset basedir="\\server\share">
<include name="**/**" />
</fileset>
</delete>
Output:
BUILD FAILED
D:\code\xxx\xxx.deploy(177,8):
Cannot delete directory '\\server\share'.
Access to the path '\\server\share' is denied.
If I modified it to instead delete contents of a directory in the share, say \\server\share\somedir, it'll delete "somedir" without error. But still, I didn't want to delete the dir, just the contents. Is there a way?
This works for me - no workarounds required:
<delete>
<fileset basedir="\\server\share">
<include name="**\*" />
</fileset>
</delete>
You could introduce an "exclude" tag and exclude a dummy file. That'll leave the root folder intact.
I'm using the following:
<target name="clean">
<delete>
<fileset basedir="${DeployTo}">
<include name="**/*" />
<exclude name="**/aspnet_client/**" />
</fileset>
</delete>
</target>
Taking cue from nsr81, I was able to come up with this workaround that works for me:
<touch file="${DeployTo}/deleteme" />
<delete>
<fileset basedir="${DeployTo}">
<include name="**/**" />
<exclude name="deleteme" />
</fileset>
</delete>
<delete file="${DeployTo}/deleteme" />

nAnt Deleting files older than 7 days old

I would like to create a target that cleans log files older than 7 days old in a specific folder. I get an error when I try to put in a "date" element inside a fileset. How can I go about this?
<delete>
fileset basedir="${StageIISRoot}/MySite/App_Data/ErrorLog">
<date datetime="${datetime::now() - timespan::from-days(7)}" when="before"/>
<include name="*.xml" />
</fileset>
</delete>
I don't see any documentation for using the "date" element. You might consider something like this:
<fileset id="thelogs" basedir="${StageIISRoot}/MySite/App_Data/ErrorLog">
<include name="*.xml" />
</fileset>
And then reference that fileset later in a loop that checks the file date and deletes:
<foreach item="File" property="filename">
<in>
<items refid="thelogs" />
</in>
<do>
<if test="${timespan::get-days(datetime::now() - file::get-last-write-time(filename)) >= 7}">
<delete file="${filename}" />
</if>
</do>
</foreach>
What about something like:
<tstamp>
<format property="last.week" pattern="MM/dd/yyyy hh:mm" locale="en,UK" offset="-7" unit="day"/>
</tstamp>
<echo>Delete backups before ${last.week}</echo>
<delete>
<fileset dir="${dst.dir}">
<date datetime="${last.week}" when="before"/>
</fileset>
</delete>
It seems to work for me :-)