Setting up FxCop under CruiseControl.NET
After spending up half a day trying to get FxCop v1.36 to play nice with CruiseControl.NET and MSBuild, I thought it was worth spending an extra hour or two documenting it.
There are two ways we can get FxCop running under CCNet: the easy way and (what I think it’s) the right way.
Either way, we start by creating an FxCop project using the FxCop GUI; it makes it easy to add our assemblies and to select the rules we’d like enforced.
The easy way has us using an <Exec/>
task within the MSBuild file:
In this version, we’re telling FxCop command line tool to use a custom dictionary - more on this later, the project file we created earlier, and to output the results to an XML file.
When being run, FxCop tends to load the previous results, which would cause load errors if we renamed classes that previously had errors,
so we’ll <Delete/>
the output file before running the task.
The nicer, more explicit way, has us use the supplemental tasks provided by the MSBuild Community Tasks Project,
in particular the <FxCop/>
task (grab at least version 1.3.0.528, part of the nightly builds - v1.2 doesn’t
properly support this task).
What you won’t find in the MSBuild Community Tasks documentation is the requirement to use the ToolPath
to point to the right version
of FxCop. As of now, the <FxCop/>
task looks explicitly for FxCop v1.32 and for a registry key that no longer exists
when it tries to build the full command line:
The problem with the registry look up is that FxCop v1.36 uses a key called FxCop.Project.9.0
,
all which means that the <FxCop/>
task fails to find the executable. That is why we have to use the
ToolPath
, inherited from its Task
parent, to help it find it.
Alright, now the promised dictionary clarification.
If our namespaces, classes, etc. include non-lexical words, for example Flickr.Configurator
, FxCop will announce
that our code breaks a naming rule - CA1704:IdentifiersShouldBeSpelledCorrectly
- and will tell us to:
Correct the spelling of ‘Flickr’ in assembly ExternalDependencies.dll’.
Correct the spelling of ‘Configurator’ in assembly ExternalDependencies.dll’.
(Yes, Configurator is not an English word either - us developers have a lot of those.)
We’ll fix this problem by adding a custom FxCop dictionary containing the words we want to mark as correct:
We’ll then spell this dictionary using the CustomDictionary
property of the <FxCop/>
task.
We could and should also add the dictionary into the FxCop project file to make sure the GUI doesn’t complain
about those naming rules being broken either. Find the <CustomDictionaries/>
node within the project file,
Default.FxCop
in the examples above, and add a <CustomDictionary/>
node:
CCNet captures all the output of a build into a giant result file using <merge>
tasks.
We’ll follow the instructions on the CCNet website to merge in the generated fxcop.xml
file:
Finally, to be able view the results of the FxCop analysis in CCNet’s web dashboard, we’ll need to include
the XSLT files, which extract and pretty up the entries merged in from fxcop.xml
, into
the dashboard.config
file, typically located within C:\Program Files\CruiseControl.NET\webdashboard\
folder:
That’s it. Next time you build you should see the FxCop details when you click the “FxCop Report” link.
The only one thing to note is that violating FxCop rules, no matter their level or the value of ContinueOnError
,
will not mark the build a broken. If you want FxCop failures to break the build, there is
one further step you need to take.