MSBuild - How to dynamically include generated *.razor files - razor

It seems the following csproj is including my generated .razor files as it complains of duplicates if I run it twice.
What it is not doing is generating the g.cs files or compiling them into the project.
If I rebuild they are included but my requirement is to generate and build in one step.
The generator is a command line generator MudBlazor.Docs.Compiler
I have been trying to sove this for 3 days so any help greatly received
<!--https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reference -->
<!--Use: dotnet msbuild -preprocess:<fileName>.xml to evaluate this project-->
<Project Sdk="Microsoft.NET.Sdk.Razor">
<!--Make sure this projects build targets run before other referenced projects-->
<PropertyGroup>
<BuildDependsOn>
CompileDocs;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<!--Outside Visual Studio SolutionDir is not available-->
<PropertyGroup>
<SolutionDir Condition=" '$(SolutionDir)' == '' ">$(MSBuildThisFileDirectory)..\</SolutionDir>
</PropertyGroup>
<!--Look for a compiled version of this project for performance-->
<Choose>
<When Condition="Exists('$(SolutionDir)MudBlazor.Docs.Compiler/bin/Debug/netcoreapp3.1/MudBlazor.Docs.Compiler.dll')">
<PropertyGroup>
<RunCommand>dotnet "$(SolutionDir)MudBlazor.Docs.Compiler/bin/Debug/netcoreapp3.1/MudBlazor.Docs.Compiler.dll"</RunCommand>
</PropertyGroup>
</When>
<When Condition="Exists('$(SolutionDir)MudBlazor.Docs.Compiler/bin/Debug/net5.0/MudBlazor.Docs.Compiler.dll')">
<PropertyGroup>
<RunCommand>dotnet "$(SolutionDir)MudBlazor.Docs.Compiler/bin/Debug/net5.0/MudBlazor.Docs.Compiler.dll"</RunCommand>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<RunCommand>dotnet run --configuration release --project "$(SolutionDir)MudBlazor.Docs.Compiler/MudBlazor.Docs.Compiler.csproj"</RunCommand>
</PropertyGroup>
</Otherwise>
</Choose>
<!--Execute the code generator-->
<Target Name="CompileDocs" BeforeTargets="BeforeBuild;BeforeRebuild" DependsOnTargets="IncludeGeneratedFiles">
<Message Text="Generating Docs and Tests using $(RunCommand)" Importance="high"/>
<Exec Command='$(RunCommand)' />
</Target>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;LIVESHARP_DISABLE</DefineConstants>
</PropertyGroup>
<!--Because we have a dynamic content .cs and .razor files comming from the code generator
we need to start from no content and recreate MSBuild rules so evreything is included.
If we dont do this the compiler takes 2 passes to compile all the content-->
<Target Name="IncludeGeneratedFiles" BeforeTargets="BeforeBuild;BeforeRebuild" >
<ItemGroup>
<Compile Include="Models\Snippets.generated.cs" Condition="!Exists('Models\Snippets.generated.cs')" />
<Compile Include="Models\DocStrings.generated.cs" Condition="!Exists('Models\DocStrings.generated.cs')" />
<RazorComponent Include="**/*ExampleCode.razor" />
</ItemGroup>
</Target>
<!--https://learn.microsoft.com/en-gb/aspnet/core/razor-pages/sdk?view=aspnetcore-5.0 -->
<Target Name="ExampleCode" BeforeTargets="PrepareForRazorComponentGenerate" >
<ItemGroup>
<RazorComponent Include="**/*ExampleCode.razor" Condition="!Exists('Models\DocStrings.generated.cs')" />
<Content Update="$(_RazorComponentInclude)">
<Generator>MSBuild:RazorGenerateComponentDeclarationDesignTime</Generator>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Target>
<ItemGroup>
<EmbeddedResource Include="Data\Elements.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.10" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Toolbelt.Blazor.HeadElement" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MudBlazor\MudBlazor.csproj" />
</ItemGroup>
</Project>

This is what I ended up doing
The most important bit is
<RazorComponent Include=
<!--https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reference -->
<!--Use: dotnet msbuild -preprocess:<fileName>.xml to evaluate this project-->
<Project Sdk="Microsoft.NET.Sdk.Razor">
<!--Make sure this projects build targets run before other referenced projects-->
<PropertyGroup>
<BuildDependsOn>
CompileDocs;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<!--Outside Visual Studio SolutionDir is not available-->
<PropertyGroup>
<SolutionDir Condition=" '$(SolutionDir)' == '' ">$(MSBuildThisFileDirectory)..\</SolutionDir>
</PropertyGroup>
<PropertyGroup>
<RunCommand>dotnet run --configuration release --project "$(SolutionDir)MudBlazor.Docs.Compiler/MudBlazor.Docs.Compiler.csproj"</RunCommand>
</PropertyGroup>
<!--Execute the code generator-->
<Target Name="CompileDocs" BeforeTargets="BeforeBuild;BeforeRebuild">
<Message Text="Generating Docs and Tests using $(RunCommand)" Importance="high" />
<Exec Command="$(RunCommand)" />
</Target>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;LIVESHARP_DISABLE</DefineConstants>
</PropertyGroup>
<!--This file contains any ExampleCode that is new and needs including in the build -->
<Target Name="ReadFromFile" DependsOnTargets="CompileDocs">
<ItemGroup>
<NewFiles Include="NewFilesToBuild.txt"/>
</ItemGroup>
<ReadLinesFromFile
File="#(NewFiles)" >
<Output
TaskParameter="Lines"
ItemName="NewExampleCodeToBuild"/>
</ReadLinesFromFile>
</Target>
<!--Because we have a dynamic content .cs and .razor files comming from the code generator we need to add them -->
<Target Name="IncludeGeneratedFiles" BeforeTargets="BeforeBuild;BeforeRebuild" DependsOnTargets="CompileDocs;ReadFromFile">
<Message Text="Found '#(NewExampleCodeToBuild->Count())' new ExampleCode files" Importance="high" />
<ItemGroup>
<Compile Include="Models/Snippets.generated.cs" Condition="!Exists('Models/Snippets.generated.cs')" />
<Compile Include="Models/DocStrings.generated.cs" Condition="!Exists('Models/DocStrings.generated.cs')" />
<RazorComponent Include="#(NewExampleCodeToBuild)" Condition="#(NewExampleCodeToBuild->Count()) != 0" />
</ItemGroup>
</Target>
<ItemGroup>
<EmbeddedResource Include="Data/Elements.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.10" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Toolbelt.Blazor.HeadElement" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../MudBlazor/MudBlazor.csproj" />
</ItemGroup>
</Project>

Related

Executing Junit Tests in ant - noclassdeffounderror wrong name

I'm trying to execute a few junit test suits with ant.
Here's my folder structure
bin
lib
src
test
build.xml
First of all I compile all files in source location, later on java files in test folder.
Whole structure of test folder (compiled .class files) are saved in bin folder which looks like this inside.
bin-test-alltests
|
-suites - SetupSuite.class
- StartSuite.class
in allTests folder are tests that are used in suites in suites folder
I'm trying to start those suites but constantly I've got an error:
ant junit java.lang.noclassdeffounderror wrong name
I'm pretty sure that's something wrong with the class path but I don't know what. I've tried to changed
<test name="SetupSuite"/>
to
<test name="SetupSuite.class"/>
and I get another error:
java.lang.ClassNotFoundException: SetupSuite.class
Here's my build.xml file
<project name="MyTest" basedir=".">
<!--Common properties -->
<property name="src.dirname" value="src" />
<property name="test.dirname" value="test" />
<property name="lib.dirname" value="lib" />
<property name="bin.dirname" value="bin" />
<property name="src.encoding" value="utf8" />
<property name="src.version" value="1.7" />
<property environment="env" />
<!-- Paths for MyTest -->
<property name="MyTest.dir" value="${basedir}" />
<property name="MyTest.src.dir" value="${MyTest.dir}\${src.dirname}" />
<property name="MyTest.test.dir" value="${MyTest.dir}\${test.dirname}" />
<property name="MyTest.dest.dir" value="${MyTest.dir}\${bin.dirname}" />
<property name="MyTest.lib.dir" value="${MyTest.dir}\${lib.dirname}" />
<path id="classpath">
<pathelement location="${MyTest.lib.dir}\junit.jar" />
<pathelement location="${MyTest.test.dir}\test\suites\" />
</path>
<target name="compile-MyTest-src" >
<myjavac srcdir="${MyTest.src.dir}" destdir="${MyTest.dest.dir}" classpath="{MyTest.lib.dir}\junit.jar"/>
</target>
<target name="compile-MyTest-test" depends="compile-MyTest-src">
<path id='libs'>
<fileset dir= "${MyTest.lib.dir}\" includes="**/*.jar"/>
</path>
<myjavac srcdir="${MyTest.test.dir}\" destdir="${MyTest.dest.dir}" classpathref = 'libs'/>
</target>
<target name="execute-tests" depends="compile-MyTest-src,compile-MyTest-test">
<junit printsummary="yes" haltonfailure="no" showoutput="yes">
<formatter type = "brief" usefile = "false" />
<classpath refid="classpath" />
<test name="SetupSuite"/>
</junit>
</target>
<!-- General compiler settings -->
<presetdef name="myjavac">
<javac classpathref="classpath" debug="on" includeantruntime="false" encoding="${src.encoding}" source="${src.version}" target="${src.version}" />
</presetdef>
</project>
Solved. I had to add hamcrest-core-1.3.jar file to classpath
You need to set test name to full name of your SetupSuite:
<test name="alltests.suites.SetupSuite"/>

In Cobertura Report all the percentages are 0 and message is coming have you mentioned the correct path

Here is my build.xml. Here all the paths are mentioned.
In report all the percentages are 0(ZERO).
And It is also prompting me that "Have you mentioned the specified source directory"
Please suggest where is the mistake.
Either I have to change the build.xml or have to perform some steps.
First I ran all the junit test cases, then stoped the server and then run the build.xml as ant-build.
<project name="RFM2" default="cobertura_REPORT">
<property name="BASEDIR" value="D:/SIT/busnessservice" />
<property name="cobertura.dir" value="D:/SIT/JUNIT_jars/cobertura-1.9.1" />
<property name="src.dir" value="${BASEDIR}/src" />
<property name="build.dir" value="${BASEDIR}/build" />
<property name="dist.dir" value="${BASEDIR}/dist" />
<property name="lib.dir" value="D:/SIT/JUNIT_jars/jars" />
<property name="report.dir" value="${BASEDIR}/reports" />
<property name="cobertura.ser.file" value="${cobertura.dir}/cobertura.ser" />
<property name="server.ser.file" value="D:/Program Files/cobertura.ser" />
<property name="instrumentedDir" value="${cobertura.dir}/instrument" />
<property name="junit.data.dir" value="${report.dir}/junit/data" />
<property name="junit.report.dir" value="${report.dir}/junit/html" />
<property name="junit.dir" value="D:/SIT/JUNIT_jars/jars" />
<property name="test.dir" value="D:/SIT/JUNITTESTFILES" />
<!--class path for cobertula -->
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura-1.9.4.1.jar" />
<include name="*.jar" />
</fileset>
</path>
<!--class path for JUNIT -->
<path id="junit.classpath">
<fileset dir="${junit.dir}">
<include name="**/*.jar" />
</fileset>
<pathelement location="${junit.dir}/junit-4.1.jar" />
<pathelement location="${BASEDIR}/bin" />
<path refid="cobertura.classpath" />
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<!-- PATH FOR LIB -->
<path id="lib.classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<path id="runtime.classpath">
<pathelement location="${build.dir}" />
<path refid="lib.classpath" />
</path>
<!--Initialization -->
<target name="init">
<mkdir dir="${dist.dir}" />
</target>
<!-- Clean files-->
<target name="clean" description="Remove all generated files.">
<delete dir="${build.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- Compile the java file -->
<!--Instrument the files -->
<target name="cobertura_instrument">
<cobertura-instrument todir="${instrumentedDir}" datafile="${server.ser.file}">
<fileset dir="${lib.dir}">
<include name="businessServices.jar" />
</fileset>
</cobertura-instrument>
<!-- Copy cobertula.ser file in server-->
</target>
<!--copy the instrumented file in class file-->
I have removed this block as I think it is not getting used .
But still my report is getting generated with zero percentage.
<!--Make EAR-->
<target name="making ear">
<echo>come in making ear</echo>
<ear destfile="${build.dir}/myapp.ear" appxml="${src.dir}/metadata/application.xml">
<fileset dir="${build.dir}" includes="*.jar,*.war" />
</ear>
</target>
<!--Run the JUNIT Test Case-->
<target name="runJunitTest">
<junit fork="yes" dir="${test.dir}" failureProperty="test.failed">
<!--
Specify the name of the coverage data file to use.
The value specified below is the default.
-->
<sysproperty key="net.sourceforge.cobertura.datafile" file="${server.ser.file}" />
<classpath location="${instrumentedDir}" />
<classpath refid="junit.classpath" />
<classpath refid="cobertura.dir" />
<formatter type="plain" usefile="false" />
<formatter type="xml"/>
<test name="${test.dir}/ColorConfigurationTest" />
<batchtest todir="${report.dir}" unless="testcase">
<fileset dir="${test.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
<!--rEPORTING-->
<target name="cobertura_REPORT">
<delete dir="${report.dir}" />
<mkdir dir="${report.dir}" />
<cobertura-report srcdir="${src.dir}" format="html" destdir="${report.dir}" datafile="${server.ser.file}">
</cobertura-report>
</target>
</project>
<!--Make EAR-->
<target name="making ear">
<echo>come in making ear</echo>
<ear destfile="${build.dir}/myapp.ear" appxml="${src.dir}/metadata/application.xml">
<fileset dir="${build.dir}" includes="*.jar,*.war" />
</ear>
</target>
<!--Run the JUNIT Test Case-->
<target name="runJunitTest">
<junit fork="yes" dir="${test.dir}" failureProperty="test.failed">
<!--
Specify the name of the coverage data file to use.
The value specified below is the default.
-->
<sysproperty key="net.sourceforge.cobertura.datafile" file="${server.ser.file}" />
<classpath location="${instrumentedDir}" />
<classpath refid="junit.classpath" />
<classpath refid="cobertura.dir" />
<formatter type="plain" usefile="false" />
<formatter type="xml"/>
<test name="${test.dir}/ColorConfigurationTest" />
<batchtest todir="${report.dir}" unless="testcase">
<fileset dir="${test.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
I noticed one thing that should be easy to correct - that doesn't match the Cobertura doc or my working copy. Hopefully this will fix your problem.
Your JUnit task references <classpath refid="cobertura.dir" /> but the cobertura.dir is not a path id, it is the name of a property pointing to your cobertura directory. (IntelliJ IDEA flagged it in red, which caught my eye!)
In my script, I have:
Then my JUnit task references the cobertura.classpath like so:
<classpath refid="cobertura.classpath" />
Hope this helps!

How to build a SWC with documentation

UPDATE
solved: embed doc with swc
solved: weird param names: param0, param1, etc.
I created a swc lib using compc.
Then I created the lib doc with asdoc.
But I dont know how to bind them together, since when I use the .swc in another project params names are weird (like myMethod(param0:Number)) and there is no doc description.
I'm using Ant, this is my config file:
<?xml version="1.0" encoding="utf-8" ?>
<project name="uil" default="compile" basedir=".">
<property name="flexsdk" location="C:/sdks/flex_sdk_4.6/bin"/>
<property name="compc" location="${flexsdk}/compc.exe"/>
<property name="asdoc" location="${flexsdk}/asdoc.exe"/>
<property name="src" location="../src"/>
<property name="bin" location="../bin"/>
<target name="compile" depends="doc">
<exec executable="${compc}" failonerror="true">
<arg line="-debug=false" />
<arg line="-optimize=true" />
<arg line="-strict=true" />
<arg line="-locale=en_US" />
<arg line="-include-sources=${src}" />
<arg line="-output=${bin}/uil.swc" />
</exec>
</target>
<target name="doc">
<exec executable="${asdoc}" failonerror="true">
<arg line="-main-title 'UIL API Documentation'" />
<arg line="-window-title 'UIL API Documentation'" />
<arg line="-source-path ${src} -doc-sources ${src}" />
<arg line="-output ${bin}/uil-asdoc" />
</exec>
</target>
</project>
Edit: How it was solved
The line that make all the magic is this:
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
Then I replaced all my <exec> tags to <compc> and <asdoc> and everything worked. You can see the entire code here.
Try to use zip ant target as in the build.xml of the Starling framework:
<!-- call asdoc to generate dita xml files -->
<asdoc output="${temp.dir}" lenient="true" failonerror="true" keep-xml="true" skip-xsl="true" fork="true">
<compiler.source-path path-element="${basedir}/src" />
<doc-sources path-element="${basedir}/src" />
</asdoc>
<!-- update swc with asdoc xml -->
<zip destfile="${deploy.dir}/${ant.project.name}.swc" update="true">
<zipfileset dir="${temp.dir}/tempdita" prefix="docs">
<include name="*.*"/>
<exclude name="ASDoc_Config.xml" />
<exclude name="overviews.xml" />
</zipfileset>
</zip>

Update app.config from WIX setup?

I am trying Wix 3.6 and this is how it looks right now :
<?xml version="1.0" encoding="UTF-8"?>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="myappINSTALLDIR" Name="myapp5Service">
<Component Id="SampleServiceComponent" DiskId="1" Guid="6f51c0f3-776c-4aec-a200-1f199352c6c3" Win64="yes">
<File Id="myapp5.WindowsService.exe" Name="myapp5.WindowsService.exe" Source="$(var.myapp.WindowsService.TargetDir)\myapp5.WindowsService.exe" KeyPath='yes'/>
...
<ServiceInstall Id="InstallmyappService" DisplayName="myappService" Name="myapp5.WindowsService.exe" Description="myapp 5 Service - För effektivare och enklare operationsplanering" Account="LocalSystem" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" />
<ServiceControl Id="ControlmyappService" Name="myapp5.WindowsService.exe" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
</Directory>
</Directory>
<WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Image\myappTopBanner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Image\myappDialogBackground.bmp" />
<Property Id="WIXUI_INSTALLDIR" Value="myappINSTALLDIR" />
<UIRef Id="WixUI_InstallDir" />
<Feature Id="ProductFeature" Title="Wix_myapp.WindowsService" Level="1">
<ComponentRef Id="SampleServiceComponent" />
</Feature>
<Media Id="1" Cabinet="SampleServiceComponent.cab" EmbedCab="yes" />
</Product>
Now I need to add a dialog to the Wix setup where one appSetting and one baseadress(WCF) is set to the app.config. This most be done before the installation becouse it will decide the name of the Windows Service that the Wix is installning.
And exampel would be great!
Edit 1:
<WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Image\myappTopBanner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Image\myappDialogBackground.bmp" />
<Property Id="SERVICEADDRESS" Value="http://serviceaddress"/>
<Property Id="WIXUI_INSTALLDIR" Value="myappINSTALLDIR" />
<UIRef Id="WixUI_InstallDir" />
<util:XmlFile Id="UpdateBaseAddress"
Action="setValue"
File="$(var.myapp.WindowsService.TargetDir)\myapp5.WindowsService.exe.config"
SelectionLanguage="XPath"
Permanent="yes"
ElementPath="/configuration/applicationSettings/ServiceName"
Name="baseAddress" Value="[SERVICEADDRESS]" />
<Feature Id="ProductFeature" Title="Wix_myapp.WindowsService" Level="1">
<ComponentRef Id="SampleServiceComponent" />
</Feature>
<Media Id="1" Cabinet="SampleServiceComponent.cab" EmbedCab="yes" />
</Product>
You could add in a reference to the WixUtilExtension.dll to the installer project, then use XmlFile to update the app.config like:
<Property Id="SERVICEADDRESS" Value="http://serviceaddress"/>
<util:XmlFile Id="UpdateBaseAddress"
Action="setValue"
File="[DirApplication]$(var.app.config)"
SelectionLanguage="XPath"
Permanent="yes"
ElementPath="/configuration/applicationSettings/...."
Name="baseAddress" Value="[SERVICEADDRESS]" />
Note that you'll need to set the directory and the name of the .config file (you could just use $(var.ProjectName.TargetFileName).config which should work it out for you automatically

How do I determine what target is calling my current target in Nant?

I am modifying a Nant build script to run some unit tests. I have different targets for locally run tests and tests to be run on team city.
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<call target="do-unit-tests"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<call target="do-unit-tests"/>
</target>
in the target do-unit-tests I set up which test assemblies are run by setting a property and calling for NCover to do a code coverage run as follows:
<target name="do-unit-test">
<property name="test.assemblies" value="MyProject.dll">
<call target="do-unit-test-coverage" />
</target>
<target name="do-unit-test-coverage">
<ncover <!--snip -->
commandLineArgs="${test.args}"
<!--snip-->
</ncover>
</target>
As you can see in the ncover part I need a property called "test.args". This property depends on "test.assemblies"
ie: <property name="test.args" value="${test.assemblies} <!--snip -->" />
test.args needs to be set up differently between the locally run unit test and the one on team city...so I'm trying to figure out how to set this up.
if i put the property for test.args in "do-unit-test" after the property "test.assemblies" I can't specify one test.args if do-unit-test is called by run-unit-tests and another for run-unit-tests-teamcity.
I've been trying to do something like the following in "do-unit-test":
<if test="${target::exists('run-unit-tests-teamcity')}">
<property name="test.args" value="..." />
</if>
but obviously that doesn't work because the target will always exist.
What I'd like then is to test if my current target do-unit-test has been called by run-unit-tests-teamcity
Is this possible? I can't see it in the Nant documentation? Since its not there it either means that it will be a feature in the future or that I'm not understanding how things are specified in a Nant build script.
You can define properties in one target, and use their values in the other... For example, you can define
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<property name="test.extratestargs" value="foo,bar,baz"/>
<call target="do-unit-tests"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="test.extrtestargs" value="foo,baz,quux,xyzzy"/>
<call target="do-unit-tests"/>
</target>
<target name="do-unit-test-coverage">
<property name="test.args" value="${test.assemblies} ${test.extratestargs} <!--snip -->" />
<ncover <!--snip -->
commandLineArgs="${test.args}" >
<!--snip-->
</ncover>
</target>
Or if you need them to be structured completely differently, not just have some different values, take advantage of the fact that the property substitution is delayed:
<?xml version="1.0"?>
<project name="nanttest">
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<property name="test.args" value="foo bar -assembly ${test.assemblies} baz" dynamic="true"/>
<call target="do-unit-test"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="test.args" value="foo,baz,quux /a:${test.assemblies} xyzzy" dynamic="true"/>
<call target="do-unit-test"/>
</target>
<target name="do-unit-test-coverage">
<echo message="test.executable = ${test.executable}, test.args = ${test.args}" />
</target>
<target name="do-unit-test">
<property name="test.assemblies" value="MyProject.dll"/>
<call target="do-unit-test-coverage" />
</target>
</project>
user#host:/tmp/anttest$ nant run-unit-tests
[...snip...]
run-unit-tests:
do-unit-test:
do-unit-test-coverage:
[echo] test.executable = tools\nunit\nunit-console.exe, test.args = foo bar -assembly MyProject.dll baz
BUILD SUCCEEDED
Total time: 0 seconds.
user#host:/tmp/anttest$ nant -D:teamcity.dotnet.nunitlauncher=nunitlauncher run-unit-tests-teamcity
[...snip...]
run-unit-tests-teamcity:
do-unit-test:
do-unit-test-coverage:
[echo] test.executable = nunitlauncher, test.args = foo,baz,quux /a:MyProject.dll xyzzy
BUILD SUCCEEDED
Total time: 0 seconds.
If you really, really just need to know if you're running in TeamCity, then this should help:
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="running.in.teamcity" value="true"/>
<call target="do-unit-tests"/>
</target>
I've managed to solve the problem. I don't know if it's the best solution but it is a solution.
I set a property called test.type and then use an if statement to determine which target it came from.
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<property name="test.type" value="unit-tests" />
<call target="do-unit-tests"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="test.type" value="unit-tests-teamcity" />
<call target="do-unit-tests"/>
</target>
<target name="do-unit-test">
<property name="test.assemblies" value="MyProject.dll">
<call target="do-unit-test-coverage" />
</target>
<target name="do-unit-test-coverage">
<if test="${test.type=='unit-tests'}">
<property name="test.args" value="${test.assemblies} ..."/>
</if>
<if test="${test.type=='unit-tests-teamcity'}">
<property name="test.args" value="... ${test.assemblies}"/>
</if>
<ncover <!--snip -->
commandLineArgs="${test.args}"
<!--snip-->
</ncover>
</target>