Archive for the 'Continuous Integration' Category

Avoiding duplicated items in Fxcop analysis using MSBuild

In my previous post, I started with a posts series that describe the tasks we’ve included in the Southworks SDC Tasks we recently published at Google Code.

Today, I’m going to focus in a useful and interesting task which is RemoveDuplicatedFileNames and the reason of why we had the need to create it.

So let’s start.

The Problem

Imagine you have a solution where your assemblies are referenced as depicted in the picture below:

image

When you compile this solution you’ll realize that the Contracts.dll assembly will be generated into the Services and in WebUx folders, that’s right?

So far, there is no problem regarding compilation, but what happens if we define an ItemGroup in our MSBuild project that includes all our solution assemblies to be examined by FxCop by using WildCards like this?

<ItemGroup>
  <Assemblies Include="$(SampleDirectory)\**\*.dll" />
</ItemGroup>

The answer is that FxCop will analyze the same assembly twice, which will generate duplicated warnings and Code Analysis errors.

Our solution approach

As I told you previously we created a simple task called RemoveDuplicatedFileNames that basically remove items from an ItemGroup on the MSBuild process, to avoid the problem described above.

So let me show you how you should configure your project file to use this task

  1. Reference the Southworks SDC Tasks assembly RemoveDuplicatedFileNames in your project file
    <UsingTask AssemblyFile="$(ToolsPath)\Southworks.Sdc.Tasks.dll"
               TaskName="RemoveDuplicatedFileNames"/>

  2. Create your ItemGroup including your assembly files
    <ItemGroup>
      <Assemblies Include="$(SampleDirectory)\**\*.dll" />
    </ItemGroup>

  3. Inside the target that runs FxCop include the following lines
    <RemoveDuplicatedFileNames Input="@(Assemblies)">
      <Output TaskParameter="FilteredItems" 
              ItemName="CodeAnalysisItems" />
    </RemoveDuplicatedFileNames>

  4. Finally, instead of using the Assemblies defined in the first point, you should use the new filtered ItemGroup generated in the previous point
    <FxCop Assemblies="@(CodeAnalysisItems)"
           OutfileName="$(CCNetArtifactDirectory)\fxcop.xml"
           ProjectFilePath="$(CCNetArtifactDirectory)\project.fxcop"
           ToolPath="$(FxCopPath)"
           ProjectTemplateFilePath="$(ToolsPath)\template.fxcop" />

Note: The FxCop task is not part of Southworks SDC Tasks, you can get it from the Microsoft SDC Tasks at Codeplex. There are many useful tasks for your build process!

Verification

in order to verify if your assemblies are no duplicated you should add a Message task on the same target to display the contained values on both ItemGroup, Assemblies and CodeAnalysisItems.

<Message Text="Unfiltered Assemblies" />
<Message Text="=====================" />
<Message Text="@(Assemblies)" />
 
<Message Text="Filtered Assemblies" />
<Message Text="===================" />
<Message Text="@(CodeAnalysisItems)" />

Technorati Profile

Updating your Assembly Info files with Southworks SDC tasks

Spanish Version

Johnny and Ezequiel had published in they blogs about the Southworks SDC Tasks we published two weeks ago in Google Code. This project is a set of comprehensive MSBuild tasks that we built along with the maturity of our build process.

I’ll give you a walkthrough for these tasks we developed by giving you a sample of each one of them.

In this post you will find how you can easily update your assembly info files with company information by using the UpdateAssemblyinfo task.

This task is pretty much straight-forward, so I will create a simple .proj file to demonstrate how it works.

Reference the SDC assembly in your project file

The first step is to add the assembly reference for this specific task by giving the AssemblyFile and the TaskName values:

<Project DefaultTargets="UpdateAssemblyInfos" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask AssemblyFile="d:\test\Southworks.Sdc.Tasks.dll"
             TaskName="UpdateAssemblyInfo"/> 
</Project>

Notice that the DefaultTargets property indicates which target will be first executed, I’m going to include this target later.

Defining the files to be updated

Then, you need to specify which files will be updated and where they’re located. To do that create a new ItemGroup. If you want to know more about including and/or including Items, see http://msdn.microsoft.com/en-us/library/646dk05y.aspx.

<Project DefaultTargets="UpdateAssemblyInfos"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
  <UsingTask AssemblyFile="d:\test\Southworks.Sdc.Tasks.dll"
             TaskName="UpdateAssemblyInfo"/>  
  <ItemGroup>
    <AssemblyInfos Include="d:\test\**\AssemblyInfo.cs"/>
  </ItemGroup>
 
</Project>

Configure the UpdateAssemblyinfo target

Finally create and configure a new target by specifying the information to be replaced on the files we defined in the previous step.

<Project DefaultTargets="UpdateAssemblyInfos" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
  <UsingTask AssemblyFile="d:\test\Southworks.Sdc.Tasks.dll"
             TaskName="UpdateAssemblyInfo"/>
  
  <ItemGroup>
    <AssemblyInfos Include="d:\test\**\AssemblyInfo.cs"/>
  </ItemGroup>
 
  <Target Name="UpdateAssemblyInfos">
    
    <UpdateAssemblyinfo Include="@(AssemblyInfos)"
                      AssemblyCopyright="Southworks (r) copyright"
                      AssemblyCompany="Southworks"
                      AssemblyProduct="Sample product " />
  </Target>
  
</Project>

To see if all it’s working as expected, you could run the project file with MSBuild as depicted bellow:

image

Open the sample AssemblyInfo.cs file and see how it was updated:

image

thanks, stay tuned!

Folder wildcards like \**\ in CruiseControl.Net

Spanish Version

Last week we were working on our Build Server using CruiseControl.Net to allow multiple Test / Code Coverage tasks for two or more solutions.

Once we’ve configured the .proj file to run a set of two RunTests / RunCodeCoverage tasks we needed to merge the results file to the MSBuild log after running them.

So, our first approach was modifying the ccnet.config file to merge the files generated by these tasks using the same pattern of MSBuild, I mean, using "\**\", something like this:

<merge>
  <files>
    <file>D:\srv\ccnet\logs\project\**\*.trx</file>
    <file>D:\srv\ccnet\logs\project\**\*.cvg</file>
  </files>
</merge>

At this point, we have figured out that Cruise Control .Net does not have this functionality, only it allows to run something like D:\srv\ccnet\logs\project\theProject\*.trx, and since the CruiseControl.Net source code is available I started to writing some lines to modify the ThoughtWorks.CruiseControl.Core assembly to allow that.

In this post you will find the source code of the spike I wrote with a series of tests to implement that feature and the WildCardPath.cs source code from the core CruiseControl.Net project updated.

  • Spike solution with tests [Download]
  • WildCardPath class file of CruiseControl.Net Core assembly [Download]

Once you have updated the Core project with the new implementation of the WildCardPath class, you need to do the following tasks to keep it running.

  1. Compile the Core project
  2. Stop the CruiseControl.Net service
  3. Replace the ThoughtWorks.CruiseControl.Core assembly with the new one.

And that’s it, use wildcards as in MSBuild :)