NCover Exclusion Rules - msbuild

I have a couple of questions related to NCover:
1) I'm using MSBuild to build my project. In my .proj file I specify exclusions like so:
<propertygroup>
<Coverageexclusions>
<CoverageExclusion>
<ExclusionType>Assembly</ExclusionType>
<Pattern>/Testing.*/i</Pattern>
<IsRegex>true</IsRegex>
</CoverageExclusion>
</coverageexclusions>
</propertygroup>
In terms of the exclusion type, if I have a .exe file, would my pattern match it as well as a DLL?
2) Does NCover 2.1.0.0, support coverage inclusions (i.e. I specify one exe or dll and it only checks that one)?

1) Yes you only need the module name not the .exe or .dll suffix
2) Yes with the //a option you can specify the specific assemblies you want covered

Related

Include file to VS2017 c++ project by condition

I am trying to build the c/c++ project in VS2017
[https://git.postgresql.org/gitweb/?p=psqlodbc.git;a=blob;f=winbuild/psqlodbc.vcxproj;h=c54c93007c07c2b13bbea4ede14a6ee0e11fdf5a;hb=c54c93007c07c2b13bbea4ede14a6ee0e11fdf5a][1]
There are conditions in the project file
<ClCompile Include="$(srcPath)odbcapi30.c" />\r
<ClCompile Condition="'$(ANSI_VERSION)'=='no'" Include="$(srcPath)odbcapi30w.c" />\r
<ClCompile Condition="'$(ANSI_VERSION)'=='no'" Include="$(srcPath)odbcapiw.c" />\r
I have created
Unicode Debug/Release
ANSI Debug/Release
configurattions
and in the project properties->c\c++->Preprocessor I have added the ANSI_VERSION=no for Unicode and ANSI_VERSION=yes for ANSI.
But for any Platform/Configuration I see these files in the Solution Explorer and they are compiled by VS2017. How to include these files into project when condition is true only?
The condition requires that ANSI_VERSION is a MSBuild property. These are different from the C++ Preprocessor definitions (which are inputs used when compiling a file but not used by MSBUILD when testing for which files to compile - strictly speaking its used by the pre-processor but its part of the compile step from an msbuild point of view)
You can set the ANSI_VERSION as an MSBUILD property in your project file:-
For example:-
<PropertyGroup>
<ANSI_VERSION>no</ANSI_VERSION>
<ANSI_VERSION Condition="'$(Configuration)' == 'ANSI_DEBUG'">yes</ANSI_VERSION>
<ANSI_VERSION Condition="'$(Configuration)' == 'ANSI_RELEASE'">yes</ANSI_VERSION>
</PropertyGroup>
The above defaults ANSI_VERSION to no and overrides to yes when condition is met, but you could just as well test each possible configuration in turn instead if you prefer.
The conditions could also be combined into a single condition with an or if you prefer.
Personally I'd use true/false rather than yes/no. With true false you can just test the property as a Boolean rather than compare to string (although maybe this also works with yes/no - but I haven't tried that)
Edit in response to question:
The above conditionally excludes the files from the build, excluding them from the display is a little different as it would require the UI to re-parse the projects to update the list of files. You may find things works better for you to create a filter in the project for these files (i.e. right click on project in solution view and use Add->New Filter). Then conditionally use the ExcludeFromBuild setting to control which configurations actually compile them instead of making the CLCompile include conditional, something like:-
<ClCompile Include="SomeFile.cpp">
<ExcludedFromBuild Condition="'$(Configuration)'=='Debug'">true</ExcludedFromBuild>
</ClCompile>

Default or specify msbuild properties in an external file

Ok, so I have a few dozen solutions all built using the exact same command line.
msbuild SolutionName.sln /p:property1=value1;property2=value2;etc etc etc.
Except the number of properties just grows and grows.
Is there a way to specify an external file some how so I don't end up with a 10 line msbuild command? (Think property 100, property 101, etc).
I'm aware of .wpp.target files. However, having to copy them into each project folder really... is my last resort.
And no, I'm not modifying any default MSBuild targets/files whatsoever.
To answer the original question, yes you can specify properties in an external file. They are called MSBuild response files.
msbuild somesolution.sln #PathToResponseFile.rsp
Inside the response file you can put your properties, one per line.
/verbosity:detailed
/target:build
/platform:AnyCPU
/configuration=Release
Some links to better understand:
http://dailytechlearnings.wordpress.com/2011/08/24/msbuild-response-file/
http://msdn.microsoft.com/en-us/library/vstudio/ms404301.aspx
However, using an msbuild file to build your solutions and projects is a better solution. You can create global targets that will do exactly as you want. You can create your own custom Clean and Build targets that will then build/clean your solutions.
First of all - I would recommend you to use msbuild scripts to build your solutions, instead of direct building sln file using command line. E.g. use something like this:
msbuild SolutionName.Build.proj
and inside this Solution1.Build.proj you can put anything as simple as
<Project ToolsVersion="4.0" DefaultTargets="BuildMe" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="BuildMe">
<MSBuild Projects="SolutionName.sln" Properties="property1=value1;property2=value2;"/>
</Target>
</Project>
After this step, which adds flexibility to your build process, you can start leverage AdditionalProperties metadata for MSBuild task.
Then you can use <Import construction to store your list of shared properties in a separate file and item metadata for passing property values:
<Project ToolsVersion="4.0" DefaultTargets="BuildMe" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="MySharedProperies.props" />
<ItemGroup>
<ProjectToBuild Include="SolutionName.sln">
<AdditionalProperties>SomeProjectSpecificProperty</AdditionalProperties>
</ProjectToBuild>
</ItemGroup>
<Target Name="BuildMe">
<MSBuild Projects="#(ProjectToBuild)" Properties="#(MySharedProperies)"/>
</Target>
</Project>
You can check this post for more details about properties and additional properties metadata or this original MSDN reference (scroll to Properties Metadata section)
This is the base idea how to do it, if you have any questions - feel free to ask.
I use an Import file for things that are common across various projects.
<Import Project="CommonBuildProperties.proj"/>
That file contains a PropertyGroup that has the things I want to have the same value across build projects. There's also a conditional statement there that sets certain folder names depending on the name of the computer it's running on. At runtime, if I need to override anything on the command line I do that.
I also have some project-specific Import files (one of our builds is a Powerbuilder application with its own toolset and pecadilloes); order of Import ensures if they require different values for the same element name I get what I want.
My command lines aren't horrible unless I'm doing something odd that needs most everything overridden. About the only things I have to pass in are version number and build type (release or debug).

MSBuild: Generate XML documentation for main project but not dependency projects

I have a .sln file with several projects in it. To keep this simple, let's call them...
ProjectA
ProjectB
ProjectC
...where A is the main project which references B and C. My goal is to update my build script to generate an XML "Intellisense" documentation file for ProjectA, without giving build warnings about missing documentation from B and C.
Current Build Script
I have an MSBuild script which includes the following in the build step:
<PropertyGroup>
<CustomOutputPath>C:\build\output\</CustomOutputPath>
</PropertyGroup>
<ItemGroup>
<Projects Include="ProjectA\ProjectA.csproj">
<Properties>OutputPath=$(CustomOutputPath)</Properties>
</Projects>
</ItemGroup>
<MSBuild Projects="#(Projects)" />
(There are actually multiple Projects listed in the ItemGroup, but again, let's keep this simple.)
When I run the build script, it's smart enough to compile B, C, and A for me, even though I've only specified A. All output appears in the "CustomOutputPath" location.
The closest I've gotten...
If I add a 'DocumentationFile' property to my Project entry...
<ItemGroup>
<Projects Include="ProjectA\ProjectA.csproj">
<Properties>OutputPath=$(CustomOutputPath);DocumentationFile=ProjectA.xml</Properties>
</Projects>
</ItemGroup>
...then 'ProjectA.xml' appears in "CustomOutputPath". However, I also get files named 'ProjectA.xml' in the project folder for all three projects:
ProjectA/ProjectA.xml
ProjectB/ProjectA.xml
ProjectC/ProjectA.xml
These files contain the "Intellisense" documentation for their respective projects, even though they're all named "ProjectA.xml".
This creates undesired and misleadingly-named files in the project folders, and (more importantly) generates build warnings for the missing documentation comments in B and C. I don't want to add documentation comments to those projects, so I'd prefer to find a way to have MSBuild generate the documentation only for ProjectA.
Can anyone provide any insight, or an alternative solution?
Based on what I've found - DocumentationFile is a global-level property (and will be used in creation of DocFileItem - global level items list). From my understanding you won't be able to alter it in any easy way in a single logical script.
What you can do is to define special target in separate file that will be imported to every proj file (directly editing proj files or using properties like $CustomBeforeMicrosoftCommonTargets) that will overwrite DocumentationFile with project-dependent value.
As a result - you probably can generate different documentation file names for different projects.
Another solution - just clean-up all unnecessary doc files right after all projs were built.

Msbuild get OutputPath from main project

Say I have a game.exe that depends on engine.dll. When I build the game.csproj I want the engine.csproj to copy some stuff to the OutputPath of the project that is referencing it.
So in this example case, I want engine.csproj to copy something to the OutputPath of game.csproj
How do I get the $(OutputPath) of game.csproj in engine.csproj?
The reason I want to do this is because I'm building a content project in game and engine like this:
<Target Name="BuildContent">
<MSBuild Projects="Content\Content.contentproj"
Properties="OutputPath=MAINPROJECTPATH" />
</Target>
So I need to specify the OutputPath to the 'main project' which is the game.
With a bit nosing around in some of the msbuild targets I found the solution.
I should pass through the Parent properties like this
<Target Name="BuildContent">
<MSBuild Projects="Content\Content.contentproj"
Properties="ParentOutputDir=$(ParentOutputDir);
ParentIntermediateDir=$(ParentIntermediateDir);
ParentProjectDir=$(ProjectDir);" />
</Target>
First off, it is not clear from the question exactly what extra files you need to be copied that will not happen automatically using inter-project references.
If the Game project includes a project reference (rather then just a DLL file reference) to the Engine project, msbuild should copy all the output from Engine into the Game output directory, doesn't it?
If you really do need to manually copy files between projects, then I do not believe there is any easy way to find out which projects reference the current project, so it would probably be simpler to create a level of indirection with Engine pushing files half way and Game (or any other projects that need to include those files) pulling the files the rest of the way:
Some post-build event code in Engine.csproj created a "References" directory under SolutionDir and copies the files it wants to share into there.
Then Game.csproj can include the files from the "References" directory - either as direct file references, or by copying with some pre-build event code in Game.csproj

Tfs2010 Build Number and Assembly File Versions & MSBuild targets

I read John Robbins' article TFS 2010 Build Number and Assembly File Versions: Completely In Sync with Only MSBuild 4.0, and I'm wondering about the best way to go about integrating this.
The download for the article has two files, one is a targets file and one is a proj file.
The targets file has a number of tasks to scrape out a build number based on the Tfs build number (the same one used for the builds) and write that number out to some location (call it BuildNumberFile) for consumption by other proj files.
The proj file is very simple. It just imports the aforementioned targets file, and then declares a target with name "All" while also declaring DefaultTargets on the Project element to be All as well.
<Project ToolsVersion="4.0" DefaultTargets="All" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- The two required properties so the Wintellect.TFSBuildNumber tasks knows your major and minor values.-->
<TFSMajorBuildNumber>3</TFSMajorBuildNumber>
<TFSMinorBuildNumber>1</TFSMinorBuildNumber>
</PropertyGroup>
<Import Project="Wintellect.TFSBuildNumber.targets"/>
<!-- Just ask for the version information files you need. These are here to show all the diffent ones in
Wintellect.TFSBuildNumber.Targets. You can change the names -->
<Target Name="All"
DependsOnTargets="WriteSharedCSharpAssemblyVersionFile;
WriteSharedVBAssemblyVersionFile;
WriteSharedCPPCLIAssemblyVersionFile;
WriteSharedCPPAssemblyVersionFile;
WriteSharedWiXAssemblyVersionFile;
WriteSharedTextAssemblyVersionFile;"/>
</Project>
I have two questions about this:
I'm still learning MSBuild. If the name of the target isn't specified elsewhere in the targets, is the target executed? How do I ensure that this target is run?
Are the csproj files supposed to declare an Include item for the location where BuildNumberFile is, even though it doesn't exist until compiletime?
Do ItemGroups and Include have a DependsOnTargets or something that allows them make sure the file exists before they build?
Are the entire contents of the csproj file using this supposed to be wrapped in a target that expresses DependsOnTargets for BuildNumberFile?
Thanks!
I think I've got this figured out, but two people promoted my question so I'll answer it here:
You can ensure that a target is run by expressing a dependency on it from another target. Microsoft.Common.targets exposes two targets--BeforeBuild and AfterBuild--expressly for the purpose of being overridden for customizability. I found the easiest way to do this was <Target Name="BeforeBuild" DependsOnTargets="WriteSharedCSharpAssemblyVersionFile" /> where WriteSharedCSharpAssemblyVersionFile is the target declared in the download from the link in the original post. Also, if you're new to MSBuild, this BeforeBuild target must be declared after the Microsoft.CSharp.targets is imported, but the default csproj template guides you in doing this.
The WriteSharedCSharpAssemblyVersionFile target should indeed write the file to some central location, since when building a solution, all targets are executed only once. All projects should reference the file from that location even if it doesn't exist, since by the time compilation happens (or more importantly, by the time references are resolved), the BeforeBuild target will have run and the file will be in place.
In my structure, I have these versioning files in a folder directly underneath the branch root folder. Furthermore, since the file being built is generated, I have it build to the output directory. It seems a little strange to be referencing things from the output, but it preserves the invariant of having all build products in one place so that the output directory can be blown away as a means of performing a clean.
In MSBuild items constitute inputs into the system (usually files) so it's weird to think of them depending on targets. After some learning this question doesn't make a lot of sense. In any case, the answer is no.
The entire contents of the file should indeed not be all in one target--all that is required is to import the Wintellect.TFSBuildNumber.targets file at the beginning of your csproj file, and declare BeforeBuild's dependency on WriteSharedCSharpAssemblyVersionFile at the end.
Hope this helps!