BM-Bloggers

The blogs of Black Marble staff

Free CodeRush ( and bits of Refactor Pro ) Xpress for C#

One of the great announcements at the PDC was that Microsoft and DevExpress have done a deal to giveaway a version of CodeRush which includes some of the more popular features of CodeRush and Refactor Pro

For those of you lucky enough to come to our evening event with the legendary Oliver Sturm, you will have already got it or its fully featured versions. I would not endorse this product if I really didn’t believe in it. To answer someone's question at our event, every developer at Black Marble is given a copy (full) of CodeRush and Refactor Pro.

you can get the Xpress version here (tell them boss sent you ;) )

b.

Seasonal Spirit at Black Marble

Once again, Black Marble, with friends and family, had a great Xmas lunch at the Chaophraya in Leeds.  Everyone who attended enjoyed the food, the company and the great gifts!  I’m now looking forward to the first Annual Black Marble Magic Show in the New Year  on our next Home Day!

I would like to take this opportunity to wish staff, friends, customers and partners a wonderful Christmas and prosperous New Year.

bmlogo

Black Marble and Microsoft Architecture in the North

At the start of December Black Marble was very proud to co-host Architecture in the North with Microsoft.

I would like to thank everybody who came and to the great Microsoft speakers who came to educate us all.

 

Session Decks

Sustainability from Data Centre to the Cloud - Matt Deacon 

Architecture Guidance - Simon Thurman

Making Sense of Windows Azure -Simon Davies

Oslo,Microsoft's vision for the future of Modelling - Robert Hogg

 

I will be posting an update of Oslo Resources shortly.

Top tip, we will be announcing an event on Governance shortly, keep an eye on Linda’s blog for details.

b.

[Resource] Visual Studio tools, utilities and add-ons

as a part of my collected sets of links here is a set of useful tools and links for Visual Studio

 

Languages

IronPython 2.0 can be downloaded from here

 

Tools

Microsoft Code Analysis Tool .NET (CAT.NET) v1 CTP - 32 bit - here

-CAT.NET is a snap-in to the Visual Studio IDE that helps you identify security flaws within a managed code (C#, Visual Basic .NET, J#),V1 contains rules to detect - Cross Site Scripting - SQL Injection - Process Command Injection - File Canonicalization - Exception Information - LDAP Injection - XPATH Injection - Redirection to User Controlled Site

 

Research Tools

there are quite a few tools which while still research tools , worth mentioning

PeX – here

- PeX is a white-box test generation

Contract tools – here

-  The tools enable runtime and static checking of managed contracts.

Chess- here

- Chess is a tool for finding typical problems in multithreaded applications

Free Book

Yes that's right Microsoft Press are celebrating 25 years and giving away free books, this months is Joseph Davies’s book on IPV6

Get it Here

the offer runs out in a few days so get downloading if you want it.

b.

Running TypeMock based test in Team Build

If you have TypeMock Isolator based MSTests in a solution you will want them to be run as part of any CI build process.

To get this to work with Team Build you have to make sure Isolator is started in the build box at the right time (something that is done automagically behind the scenes by Visual Studio during developer testing). This is not actually that difficult as TypeMock provide some tasks for just this purpose.

Firstly you have to install Isolator on the build box (and of course license it). Then edit your tfsbuild.proj build script to include the overrides for the beforetest and aftertest targets

<!-- Import the Typemock list of tasks --> 
<PropertyGroup>
    <TypeMockLocation>C:\Program Files\Typemock\Isolator\5.1</TypeMockLocation>
</PropertyGroup>
<Import Project ="$(TypeMockLocation)\TypeMock.MSBuild.Tasks"/>

<!-- Before the tests are run start TypeMock -->
<Target Name="BeforeTest">
    <TypeMockStart/>
</Target>

<!-- And stop it when the are finished -->
<Target Name="AfterTest">
    <TypeMockStop/>
</Target>

Once this is done your test should run OK

My problems with Live Messenger inside Visual Studio are fixed.

One of the cool feature of the last October 08 release of TFS Power Tools has been that the members of a Team Project are shown inside Team Explorer.

One of the ideas of this is that you can use Live Messenger from inside Team Explorer to see team members status, but I and many other were seeing the error shown below as Team Explorer refreshed

clip_image002

There had been much talk of it being settings in the registry, UAC being used etc. but none of the fixes detailed worked for me.

However, today it has all started working after I updated to the new version of Live Messenger released in the past few days, Version 2009 (Build 14.0.8050.1202). I suspect the problem in my case was that I was using a beta version of Live Messenger

Update on using StyleCop in TFS Team Build

I posted a while ago about trying to wire in the results from StyleCop into a Team Build, the problem I had was that I could not get the StyleCop violations into the build summary.

Well I still can’t, after much checking and asking around I was reliably informed that the build summary is not editable and there are no immediate plans for it to be in the future versions of TFS.

However, Martin Woodward, another Team System MVP, made the suggestion to add the violation information into the build information object. This would not allow the information to be seen in  the build summary in Visual Studio, but it would allow me to programmatically recover it from the IBuildInformation object inside my build wallboard application – which shows the current state of all our current CI Team Builds, it shows a scrolling list row as below

image

Where the key items are:

  • Big graphic showing Building, Success, Partial Success or Failure
  • The name of the build and the time it finished
  • CE – Compiler errors
  • CW – Compiler warnings
  • FW – FXCop warnings
  • SW – StyleCop violations
  • TP – Tests passed
  • TF – Test failed
  • and the rabbit shows if the build status is reported by a NazBazTag Build Bunny

So to do this I had to write an MSBuild Task, but the code fairly simple as Martin had suggested

//-----------------------------------------------------------------------
// <copyright file="StyleCopResultsMerge.cs" company="Black Marble">
//     Black Marble Copyright 2008
// </copyright>
//-----------------------------------------------------------------------
namespace BlackMarble.MSBuild.CodeQuality
{
    using System;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    using Microsoft.TeamFoundation.Build.Client;
    using Microsoft.TeamFoundation.Client;
    
    /// <summary>
    /// Merges the Stylecop results into the build results for TFS
    /// </summary>
    public class StyleCopResultsMerge : Task
    {
        /// <summary>
        /// The tfs server to report to
        /// </summary>
        private TeamFoundationServer tfs;

        /// <summary>
        /// The build server doing the work
        /// </summary>
        private IBuildServer buildServer;

        /// <summary>
        /// The current build
        /// </summary>
        private IBuildDetail build;
                
        /// <summary>
        /// Gets or sets the Url of the Team Foundation Server.
        /// </summary>
        [Required]
        public string TeamFoundationServerUrl
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the Uri of the Build for which this task is executing.
        /// </summary>
        [Required]
        public string BuildUri
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the number of stylecop violations found.
        /// </summary>
        [Required]
        public int Violations
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the number of files stylecop failed to parser.
        /// </summary>
        [Required]
        public int Failures
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the lazy init property that gives access to the TF Server specified by TeamFoundationServerUrl.
        /// </summary>
        protected TeamFoundationServer Tfs
        {
            get
            {
                if (this.tfs == null)
                {
                    if (String.IsNullOrEmpty(this.TeamFoundationServerUrl))
                    {
                        // Throw some exception.
                    }

                    this.tfs = TeamFoundationServerFactory.GetServer(this.TeamFoundationServerUrl);
                }

                return this.tfs;
            }
        }

        /// <summary>
        /// Gets the lazy init property that gives access to the BuildServer service of the TF Server.
        /// </summary>
        protected IBuildServer BuildServer
        {
            get
            {
                if (this.buildServer == null)
                {
                   this.buildServer = (IBuildServer)this.Tfs.GetService(typeof(IBuildServer));
                }

                return this.buildServer;
            }
        }

        /// <summary>
        /// Gets the lazy init property that gives access to the Build specified by BuildUri.
        /// </summary>
        protected IBuildDetail Build
        {
            get
            {
                if (this.build == null)
                {
                    this.build = (IBuildDetail)this.BuildServer.GetBuild(new Uri(this.BuildUri), null, QueryOptions.None);
                }

                return this.build;
            }
        }

        /// <summary>
        /// ITask implementation - Execute method.
        /// </summary>
        /// <returns>
        /// True if the task succeeded, false otherwise.
        /// </returns>
        public override bool Execute()
        {
            try
            {
                IBuildInformation info = this.Build.Information;

                Log.LogMessage("StyleCopResultsMerge for build {0} with {1} violations ", this.Build.Uri.ToString(), this.Violations.ToString());

                IBuildInformationNode infoNode = info.CreateNode();
                infoNode.Type = "org.stylecop";
                infoNode.Fields.Add("total-violations", this.Violations.ToString());
                info.Save();

                return true;
            }
            catch (Exception ex)
            {
                Log.LogError(ex.Message);
                return false;
            }
        }
    }
}

This can then wired into the build process I detailed in the older post and have repeated below with the new additions. The choice you have to make is if StyleCop violations will cause the build to fail or not – both are detailed below.

<!-- the imports needed -->
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>
<!-- this could be a task file if you wanted -->
<UsingTask AssemblyFile="$(BMTasksPath)BlackMarble.MSBuild.CodeQuality.StyleCopResultsMerge.dll" TaskName="BlackMarble.MSBuild.CodeQuality.StyleCopResultsMerge"/>

<!-- All the other Target go here -->

<Target Name="AfterCompile">

    <!-- Create a build step to say we are starting StyleCop -->
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
        BuildUri="$(BuildUri)"
             Name="StyleCopStep"
              Message="StyleCop step is executing.">
      <Output TaskParameter="Id" PropertyName="StyleCopStep" />
    </BuildStep>

    <!-- Create a collection of files to scan, ** means and sub directories -->
    <CreateItem Include="$(SolutionRoot)\My Project\**\*.cs">
      <Output TaskParameter="Include" ItemName="StyleCopFiles"/>
    </CreateItem>

    <!-- Run the StyleCop MSBuild Extensions task using the setting file in the same directory as sln file and also stored in TFS -->
    <MSBuild.ExtensionPack.CodeQuality.StyleCop
        TaskAction="Scan"
        SourceFiles="@(StyleCopFiles)"
        ShowOutput="true"
        ForceFullAnalysis="true"
        CacheResults="false"
        logFile="$(DropLocation)\$(BuildNumber)\StyleCopLog.txt"
        SettingsFile="$(SolutionRoot)\My Project\Settings.StyleCop"
        ContinueOnError="false">
      <Output TaskParameter="Succeeded" PropertyName="AllPassed"/>
      <Output TaskParameter="ViolationCount" PropertyName="Violations"/>
      <Output TaskParameter="FailedFiles" ItemName="Failures"/>
    </MSBuild.ExtensionPack.CodeQuality.StyleCop>

    <!-- Run the new results merge task -->
    <BlackMarble.MSBuild.CodeQuality.StyleCopResultsMerge
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Violations="$(Violations)"
      Failures ="0"
     />
 
    <!-- Put up a message in the build log to show results irrespective of what we do next -->
    <Message Text="StyleCop Succeeded: $(AllPassed), Violations: $(Violations)"/>

    <!-- FailedFile format is:
        <ItemGroup>
            <FailedFile Include="filename">
                <CheckId>SA Rule Number</CheckId>
                <RuleDescription>Rule Description</RuleDescription>
                <RuleName>Rule Name</RuleName>
                <LineNumber>Line the violation appears on</LineNumber>
                <Message>SA violation message</Message>
            </FailedFile>
        </ItemGroup>-->

    <Warning Text="%(Failures.Identity) - Failed on Line %(Failures.LineNumber). %(Failures.CheckId): %(Failures.Message)"/>

    <!-- The StyleCop task does not throw an error if the analysis failed, 
         so we need to check the return value and if we choose to treat errors as warnngs 
         we need to set the error state -->
    <Error Text="StyleCop analysis warnings occured" Condition="'$(AllPassed)' == 'False'"  />

    <!-- List out the issues, you only need this if we are not forcing the error above -->
    <!--<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
            BuildUri="$(BuildUri)"
            Message="%(Failures.Identity) - Failed on Line %(Failures.LineNumber). %(Failures.CheckId): %(Failures.Message)"/>-->

    <!-- Log the fact that we have finished the StyleCop build step, as we had no error  -->
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
                  BuildUri="$(BuildUri)"
                  Id="$(StyleCopStep)"
                  Status="Succeeded"
                  Message="StyleCop Succeeded: $(AllPassed), Violations: $(Violations)"/>

    <!-- If an error has been raised we call this target 
         You might have thought you could so the same as the error line above and this followng
         OnError line by adding a condition as shown below. However this does not work
         as the OnError condition is not evaluated unless an error as previously occured-->
    <OnError ExecuteTargets="FailTheBuild" />
    <!--<OnError ExecuteTargets="FailTheBuild" Condition="'$(AllPassed)' == 'False'"  />-->

  </Target>

  <Target Name="FailTheBuild">
    <!-- We are failing the build due to stylecop issues -->
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
            BuildUri="$(BuildUri)"
            Id="$(StyleCopStep)"
            Status="Failed"
            Message="StyleCop Failed: $(AllPassed), Violations: $(Violations) [See $(DropLocation)\$(BuildNumber)\StyleCopLog.txt]"/>

    <!-- List out the issues-->
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
            BuildUri="$(BuildUri)"
            Message="%(Failures.Identity) - Failed on Line %(Failures.LineNumber). %(Failures.CheckId): %(Failures.Message)"/>

  </Target>

Finally to get the new in formation out of the build and into the build wallboard

public void UpdateStatus(IBuildDetail detail)
{
    // any other results fields updates
 
    // and now the custom nodes
    IBuildInformation info = detail.Information;
    foreach (IBuildInformationNode infoNode in info.Nodes)
    {
        if (infoNode.Type == "org.stylecop")
        {
            // we have the correct node
            this.SetStyleCopWarnings(infoNode.Fields["total-violations"]);
            break;
        }
    }
}

So not a perfect solution, but but does everything I need at present.