views:

132

answers:

4

I have VS 2010 Professional (which, unlike Premium, does not include access to Code Analysis configuration within the IDE), and a C# 4 solution containing many-dozen projects. I want to do static code analysis as part of solution compilation.

The possible ways I have identified with the help of SO and Google are:

  • Edit every .csproj in the solution to include an invocation of the stand-alone FxCop 10 as a Post-build event. Pros: happens on every compile for every project that is rebuilt. Cons: Have to take additional measures to ensure new projects have this specified

  • Create a new project, or identify an existing project, that is always built last, on account of its project dependencies. Give (just) that project a Post-build event that runs FxCop on all the assemblies in the (common) output folder. Pros: only one file to update, and less possibility of future projects going unanalysed. Cons: The vagaries of build dependencies might mean this doesn't actually work

  • Update all developers' VS instances with an add-in or macro that runs FxCop after any build. Don't really like this idea at all.

Are there any other options, that are clearly better than any of the above? Are there any caveats or observations I need to be aware of to make one of the above work?

I also want FxCop to be run as part of a MSBuild 4.0-powered build on a build server. Which of the options will allow me to reuse code analysis rulesets between desktop compilation and bulid server compilation?


I have already read related but non-identical already-existing questions including:

+1  A: 

I've not used FxCop for a while, but if you have lots of projects, I suspect running it once for each project, rather than just once at the end, is going to be painful. You could try (or at least start from) something like this. In a nutshell, you have an uber-project, with targets that depend on building your entire solution, followed by running FxCop (or unit tests, etc.) You invoke the uber-project using a batch file from the Solution Explorer.

It's similar to your second suggestion, but won't have any dependence on the build order, and doesn't require fiddling with new projects. Unfortunately its current incarnation breaks the normal shortcuts for building from within VS, and it'll probably be easy to bypass accidentally, but it might be possible to refine it.

It might also be cleaner and better integrated with VS to use an MSBuild target for running FxCop, rather than a post-build step.

shambulator
+1  A: 

I have used Hudson as a build server that would perform code analysis after building .NET applications. In order to use it for this purpose, you will need to install two plugins:

  • MSBuild plugin to build .NET applications.
  • Violations plugin that reports code analysis results and supports FxCop and StyleCop.

Hudson would need to be configured to execute FxCop and StyleCop, but this isn't very difficult to do using batch files. The benefit is that none of your project files would need to be configured, as the code analysis would be performed externally; that is, not through Visual Studio.

You can configure Hudson to perform the code analysis as a daily task or even on every change to your applications. Then everyone on your development team could view the code analysis results through Hudson to determine whether they've made any violations.

Bernard
+1  A: 

An alternative to FxCop would be to use NDepend and its Code Query language (CQL). CQL is dedicated to write code quality rules that can be verified live in Visual Studio, or that can be verified during build process and reported in a HTML report. Here are a few samples of CQL rules (designed to be highly customizable):

Code refactored recently should be 100% covered by test:

WARN IF Count > 0 IN SELECT METHODS WHERE CodeWasChanged AND PercentageCoverage < 100

I don’t want that my User Interface layer to depend directly on the DataBase layer:

WARN IF Count > 0 IN SELECT METHODS WHERE CyclomaticComplexity > 15 AND PercentageComment < 10

I don’t want that my User Interface layer to depend directly on the DataBase layer:

WARN IF Count > 0 IN SELECT NAMESPACES WHERE IsDirectlyUsing "DataLayer" AND NameIs "UILayer"

Static fields should not be named m_XXX (Custom naming conventions):

WARN IF Count > 0 IN SELECT FIELDS WHERE NameLike "^m_" AND IsStatic

Methods out of MyAssembly and MyAssembly2 should not have more than 30 lines of code:

WARN IF Count > 0 IN SELECT METHODS OUT OF ASSEMBLIES "MyAssembly1", "MyAssembly2" WHERE NbLinesOfCode > 30

Public methods should not be removed to avoid API breaking changes:

WARN IF Count > 0 IN SELECT METHODS WHERE IsPublic AND IsInOlderBuild AND WasRemoved

Types tagged with the attribute MyNamespace.FullCoveredAttribute must be thoroughly covered by tests:

WARN IF Count > 0 IN SELECT TYPES WHERE HasAttribute "MyNamespace.FullCoveredAttribute" AND PercentageCoverage < 100

Patrick Smacchia - NDepend dev
A: 

To integrate FxCop as part of the build scipt (MSBuild) I use the FxCop task from MSBuild.Community.Tasks. Using FxCop I create an FxCop project (FxCopProject.FxCop) that defines the rules to use and the assemblies to examine.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
 <PropertyGroup>
  <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\vendor\MSBuild.Community.Tasks.v1.3.0.504</MSBuildCommunityTasksPath>
  <FxCopDir>vendor\Microsoft Fxcop 10.0</FxCopDir>
 </PropertyGroup>
 <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets"/>

 <Target Name='FxCopReport'>
  <FxCop
   ToolPath='$(FxCopDir)'
   ProjectFile='FxCopProject.FxCop'
   AnalysisReportFileName='FxCopReport.xml'
  />
 </Target>
</Project>
mcdon