Visual Studio 2010 Professional and Hudson / Jenkins CI and FxCop

 

Visual Studio 2010 Premium and Ultimate do have the code analysis feature build in. What this feature does is static code analysis of your source code (or IL to be specific). Unfortunately the Professional edition lacks the build in integration (no Analysis tab in the project properties). Here is a way to easily integrate Visual Studio 2010 Professional with FxCop. FxCop is a standalone Code Analysis version that comes together with “Microsoft Windows SDK for Windows 7 and .NET Framework 4 Version 7.1”. Actually if you download and install the SDK you will get the FxCop installer in %ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\FXCop. You will have to install it from there (yeah installer in a installer ;).

Here is how to built it into Visual Studio 2010 and into continuous integration process. First of all, I like to have all the assets in my repository. So I went and copied all the FxCop files into the tools/FxCop directory into the repository. I didn’t wanted to use the FxCop project files (they add unnecessary friction with editing the file – sometimes on runtime). I decided to go the command line way all the way. The easiest solution is to define all the rules you want to obey in the ruleset file. Ruleset file is a XML file that looks like this:

   1: <?xml version="1.0" encoding="utf-8"?>

   2: <RuleSet Name="Codefusion Rules" Description="This is the Codefusion rule set." ToolsVersion="10.0">

   3:   <Localization ResourceAssembly="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.dll" ResourceBaseName="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.Localized">

   4:     <Name Resource="ExtendedDesignGuidelineRules_Name" />

   5:     <Description Resource="ExtendedDesignGuidelineRules_Description" />

   6:   </Localization>

   7:   <IncludeAll Action="Error" />

   8:   <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">

   9:     <Rule Id="CA1000" Action="Warining" />

  10:   </Rules>

  11: </RuleSet>

The example above states that all the rules (IncludeAll) are threated as errors with one exception being a Warning (<Rule Id=…). You can define the rules as you wish. Fortunately Visual Studio 2010 Professional has the build in editor for the ruleset files. Using this editor you can easily choose the rules to obey (or not).

image

When you are done with the ruleset place it somewhere in your repository and define post build event like this one:

image

The text for the post build event is:

if $(ConfigurationName) == Release $(SolutionDir)Codefusion.Common\Tools\FxCop\FxCopCmd.exe /file:$(SolutionDir)S000.Basic\bin\$(ConfigurationName)\Codefusion.S000.Basic.dll /ruleset:=$(SolutionDir)Codefusion.Common\FxCopRules\CodefusionRules.ruleset /rulesetdirectory:$(SolutionDir)Codefusion.Common\Tools\FxCop\Rules /console

This way if you compile the project in Release mode you will get all the rules defined in ruleset file checked. You will see the violations in the Error List area. You can still jump to the line where violation occurs by double-clicking the line with report.

You can always suppress the messages for the rules you chosen to obey if in this particular case they don’t make sense. You can do it globally in the GlobalSuppressions.cs file. Like that:

   1: [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Codefusion")]

Or directly in the code like that:

   1: [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]

   2: public static string MakeMD5Hash(this string value)

   3: {

   4:     if (value == null)

   5:     {

   6:         throw new ArgumentNullException("value");

   7:     }

   8:     else if (value == string.Empty)

   9:     {

  10:         throw new ArgumentException(Resources.BasicStrings.ErrorMsgValueCannotBeEmpty + ".", "value");

  11:     }

  12:  

  13: ...

To make the suppressions work (suppressions are inline or global exceptions from the ruleset) you will have to define the compiler directive like that:

image

It will define a constant in the project file:

<DefineConstants>CODE_ANALYSIS</DefineConstants>

If you are using the continuous integration technique you can put the command similar to the one in post build event into the build project. In MSBuild it will look like this:

   1: <Target Name="Analysis" >

   2:   <Exec Command="$(MSBuildProjectDirectory)\Codefusion.Common\Tools\FxCop\FxCopCmd.exe /file:S000.Basic\bin\$(Configuration)\Codefusion.S000.Basic.dll /ruleset:=Codefusion.Common\FxCopRules\CodefusionRules.ruleset /rulesetdirectory:Codefusion.Common\Tools\FxCop\Rules /out:FxCopReport.xml /forceoutput" ContinueOnError="false" />

   3: </Target>

This way you will get get the XML file with the violations report that your CI server can interpret and thanks to the ContinueOnError=”false” attribute you will get the broken build if any of the violations will be found.

In Hudson/Jenkins you can use the Violations plug-in (you will have to install it) to show the violations in the build report. To do so you need to to configure the project like this:

image

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *