ExecTask or (Insert)Task, whats the difference? - phing

Can someone explain the use of using all the different tasks instead of using simply <exec/>?
The PHPunit task is giving me alot of problems at the moment for example, why bother and not go for a simple <exec/> ?
Cant seem to find anything in the docs at all.
The docs are f.e. very confusing giving examples such as:
https://www.phing.info/docs/guide/stable/ch04s02.html (4.2 Writing A Simple Buildfile)
<target name="build" depends="prepare">
<echo msg="Copying files to build directory..." />
<echo msg="Copying ./about.php to ./build directory..." />
<copy file="./about.php" tofile="./build/about.php" />
<echo msg="Copying ./browsers.php to ./build directory..." />
<copy file="./browsers.php" tofile="./build/browsers.php" />
<echo msg="Copying ./contact.php to ./build directory..." />
<copy file="./contact.php" tofile="./build/contact.php" />
</target>
The copy task has a description property, you would think that this would be somehow seem logical to interpret by summary reporters or something, instead of having a echo on top of every task..
Whats the best practise?

Phing's Copy Task does not have a description property...
...other than that, if expressing an action is more concise and less error-prone when written as a [custom] task than as an unwieldy exec task I usually take that as a hint to go looking and/or write that custom task.
Sometimes going a little further and submitting a pull-request ;-)

Related

CruiseControl.net, send dynamic values to some files

I have been searching for a few days, I have also asked a question on the cc.net forum, but still don't have the answer.
My task is to fill Web.config with specific values during the building using cc.net. Here is the example:
I'm developing an ASP.NET website, I have a Web.config with some configuration, e.g. connection string:
<add name="ContextName" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=DatabaseName;User Id = UserName;Password=UserPassword;" providerName="System.Data.SqlClient" />
After the building I want to replace some values and make the config look like this:
<add name="ContextName" connectionString="Data Source=%SERVER%;Initial Catalog=%DATABASE%;User Id = %USER%;Password=%PASSWORD%;" providerName="System.Data.SqlClient" />
I tried this solution, but it didn't help me (or maybe I didn't understand how to use it properly).
Please help me to solve the task.
Thanks!
You can try to use this Config Transformation Tool which is XDT transformation command tool based on XDT (web.config) transform engine, which allows you to run XDT transformation on any XML files. You can use ccnet's task block to run it after your msbuild
<tasks>
<exec>
</exec>
</tasks>
More on ccnet executable task see here.
For more information on XDT transformation see this link in MSDN library
You can create a target on your build file to update the web.config and call that target after the build. I use something similar in my build files, here is an example:
<target name="update-config" >
<property name="export.config" value="" unless="${property::exists('export.config')}" />
<call target="${config-settings}" /> <!-- test or stage -->
<xmlpoke file="${export.config}" xpath="/configuration/appSettings/add[#key='ContextName']/#connectionString" value="${configValue.connectionString}" failonerror="true" />
</target>
<target name="test">
<property name="configValue.connectionString" value="test connection string here" />
</target>
<target name="stage">
<property name="configValue.connectionString" value="stage connection string here" />
</target>
After executing the target that compile your code and export you can run the target update-config, in this case I'm expecting a variable export.config with the path of the exported web.config then calling another target that sets the the value of the connectionstring variable (this can be target test or stage) and finally xmlpoke the web.config with the value.
Hope this helps!

How can I let CruiseControl.NET/nant run all Unittest projects postfixed with .Test?

In our continuous integration setup, I would like to set up CruisControl.NET to automatically run all our unittests. However, I don't want to have to specify every unittest dll seperately in the configuration.
All the unittest projects are all postfixed with .Test (and all non-unittest projects are not). How can I configure CruiseControl.NET to run all the unittests from these projects (I am using v1.5.7256.1 of CruiseControl.NET)?
My current config attempt:
<nunit>
<path>$(nunit.path)</path>
<assemblies>
<assembly>$(working.dir)\**\*.Test.dll</assembly>
</assemblies>
</nunit>
I'm finding it very difficult to find documentation on this specific nunit element. Most pages I can find talk about using exec, nunit2 or another nunit element or the nunit-console commandline options.
I don't have much experience with managing the build environment and am working on an existing configuration where every assembly was specified separately in the following manner.
<nunit>
<path>$(nunit.path)</path>
<assemblies>
<assembly>$(artifact.dir)\test1.dll</assembly>
<assembly>$(artifact.dir)\test2.dll</assembly>
</assemblies>
</nunit>
Hence my failed attempt using wild cards.
EDIT:
Here is some extra xml of my configuration file to show the context a little bit:
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name="MyProject">
<!-- whole bunch of other elements -->
<tasks>
<nunit>
<!-- see above -->
</nunit>
</tasks>
</project>
</cruiscontrol>
After Mightmuke's suggestion, I tried replacing the <nunit> element with his suggestion, but got the following exception: Unable to instantiate CruiseControl projects from configuration document. Configuration document is likely missing Xml nodes required for properly populating CruiseControl configuration. Unable to load array item 'property' - Cannot convert from type System.String to ThoughtWorks.CruiseControl.Core.ITask for object with value: ""
Then I tried to move the <property> and <foreach> element outside the element. Then I get the exception: Unused node detected: <property name="nunit.filelist" value="" />
I'm now trying to find out more about the <foreach> element and where I can put that, but somehow I find it hard to find any documentation about it.
EDIT2:
I found the documentation of the nunit task I'm using: http://ccnet.sourceforge.net/CCNET/NUnit%20Task.html
I specifies the element to be of type String[]. I'm not sure what that means... but it seems from the example that it just means that it must contain a list of child elements of the same name in Singular form.
PS: I realize this question is getting a bit out of hand... When the whole thing is solved, I'll try to edit it in such a format so that it might be useful to someone else later.
This is an example configuration if you were to use the nunit console.
<property name="nunit.filelist" value="" />
<foreach item="File" property="testfile" verbose="true">
<in>
<items basedir=".">
<include name="${working.dir}\**\*.Test.dll" />
</items>
</in>
<do>
<property name="nunit.filelist" value="${nunitfile.list + ' ' + testfile}" />
</do>
</foreach>
<exec program="nunit-console-x86.exe" failonerror="true" verbose="true">
<arg value="${nunit.filelist}" />
<arg value="/xml=nunit-results.xml" />
<arg value="/nologo" />
<arg value="/nodots" />
</exec>
This hasn't been tested, and there are likely better ways to skin it, but it will hopefully provide a starting point for you.

acceleoCompiler not showing output in console output with ant

I am using acceleoCompiler inside an ant script and when i run the ant script everything shows an output except acceleoCompiler.
For instance, [javac] and [mkdir] shows up. But nothing relating to acceleoCompiler shows up. Am i doing something wrong?
The ant script:
<eclipse.refreshLocal resource="${F_FOLDER}/bin/" depth="infinite"/>
<eclipse.refreshLocal resource="${FE_FOLDER}/bin/" depth="infinite"/>
<mkdir dir="${F_OUTPUT}"/>
<mkdir dir="${FE_OUTPUT}"/>
<javac
srcdir="${F_SRC}generator/"
destdir="${FR_OUTPUT}"
executable="${JAVA_JDK}/javac"
fork="true"
includeantruntime="false"
failonerror="false"
/>
<javac
srcdir="${FE_SRC}generator/"
destdir="${FE_OUTPUT}"
executable="${JAVA_JDK}/javac"
fork="true"
includeantruntime="false"
failonerror="false"
/>
<acceleoCompiler sourceFolder="${F_SRC}"
outputFolder="${F_OUTPUT}"
dependencies=""
binaryResource="true"
packagesToRegister="org.eclipse.emf.ecore.EcorePackage">
</acceleoCompiler>
<acceleoCompiler sourceFolder="${F_SRC}"
outputFolder="${FE_OUTPUT}"
dependencies=""
binaryResource="true"
packagesToRegister="org.eclipse.emf.ecore.EcorePackage">
</acceleoCompiler>
The absence of logging messages doesn't mean you're doing anything wrong. If you look at the source for mkdir or javac you'll see that they call the Ant Task method log() in most cases. The Acceleo Ant task however only calls log() if it finds a problem - if all is well it is silent and enigmatic.
References:
Ant mkdir task source.
AcceleoCompiler source via the Acceleo wiki FAQ.

Include/Exclude buildfiles

How do you do this? Given several build files, I only want to include the ones where the target (specified from the command line) exists. Using target::exists in does not seem to work. Thanks.
<target name="*">
<property name="curr.target" value="${target::get-current-target()}"/>
<nant target="${curr.target}">
<buildfiles>
<include name="*.build" if="${target::exists(curr.target)}"/>
<!-- avoid recursive execution of current build file-->
<exclude name="${project::get-buildfile-path()}" />
</buildfiles>
</nant>
</target>
Using robaker's solution, my final build file looks like this. It does not fail anymore if the target is not found in a certain build file (unlike my previous code).
<project>
<include buildfile="A.build"/>
<include buildfile="B.build"/>
<target name="*">
<nant target="${target::get-current-target()}"/>
</target>
</project>
Why not just use the include task to include all your child build scripts instead?

How to stop MSBuild _WPPCopyWebApplication target cleaning App_Data folder

I'm using the _WPPCopyWebApplication MSBuild target in a CruiseControl.net build-and-deploy script, but it appears that this target cleans files not part of the project before the deployment - specifically, App_Data files (which for this app, include uploaded images, etc).
From Microsoft.Web.Publishing.targets;
<OnBefore_WPPCopyWebApplication>
$(OnBefore_WPPCopyWebApplication);
CleanWebProjectOutputDir;
PipelineTransformPhase;
</OnBefore_WPPCopyWebApplication>
How can I stop it doing the CleanWebProjectOutputDir, given this target;
<Target Name="Deploy" DependsOnTargets="Tests">
<MSBuild Projects="$(TargetPath)Website.csproj" Properties="Configuration=Debug;WebProjectOutputDir=\\servername\share;Outdir=$(ProjectDir)bin\;" Targets="ResolveReferences;_WPPCopyWebApplication" />
</Target>
This is from a VS2010 solution, albeit built under CC.Net; I'm aware of MSDeploy, but haven't got my head around that fully yet, so would prefer to stick with MSBuild/_WPPCopyWebApplication for now.
EDIT:
I've further narrowed this to this part of the target;
<!-- In the case of the incremental Packaging/Publish, we need to find out the extra file and delee them-->
<ItemGroup>
<_AllExtraFilesUnderProjectOuputFolder Include="$(WebProjectOutputDir)\**" />
<_AllExtraFilesUnderProjectOuputFolder Remove="#(FilesForPackagingFromProject->'$(WebProjectOutputDir)\%(DestinationRelativePath)')" />
</ItemGroup>
<!--Remove all extra files in the temp folder that's not in the #(FilesForPackagingFromProject-->
<Delete Files="#(_AllExtraFilesUnderProjectOuputFolder)" />
So I guess the question becomes, how can I supress this specific Delete task, or at least add App_Data** to the _AllExtraFilesUnderProjectOuputFolder exclusions?
Add CleanWebProjectOutputDir=False to your properties:
<Target Name="Deploy" DependsOnTargets="Tests">
<MSBuild Projects="$(TargetPath)Website.csproj" Properties="Configuration=Debug;CleanWebProjectOutputDir=False;WebProjectOutputDir=\\servername\share;Outdir=$(ProjectDir)bin\;" Targets="ResolveReferences;_WPPCopyWebApplication" />
</Target>