ReSharper and StyleCop

Configuring ReSharper

Firstly open up Visual Studio. Along the menu bar there should be a “ReSharper” heading. Go to “Options” within it.

Code Style Sharing – make sure you have “Shared across the team, per solution” selected. You’ll need to make sure your whole team have this selected. I think it is by default.

C# – Go through the C# section, and set all the rules to suit preferred style. Typically I would suggest leaving most of them as they are.

Code Cleanup – “Add” a new code cleanup profile, and again go through setting everything as you’d like it to be. I turn on as much as possible, and set it where possible to change explicit types to “var” (because I find it reads more cleanly).

UserSettings.xml

Once done, you need get your settings file. It will be located at:

“%USERPROFILE%\Application Data\JetBrains\ReSharper\v4.x\vs9.0″

Take the UserSettings.xml file and place it in source control. I placed mine at:

/trunk/build/settings/resharper/UserSettings.xml

Here’s my UserSettings.xml file as an example. Within that directory I also created an install.bat with the following inside it:

copy UserSettings.xml “%USERPROFILE%\Application Data\JetBrains\ReSharper\v4.5\vs9.0″
pause

By getting your team to run this, it will ensure you all have the same settings file. I like to enforce this by adding it to the end of go.bat. It’s a simple copy command and won’t increase the build time.

If your solution file is called MyApp.sln, you need to make sure you have a MyApp.4.x.resharper file.

MySolution.4.x.resharper

Where your solution is located, if called MySolution.sln, you should now have a resharper file called MySolution.4.x.resharper. This is your team settings file, and whenever a team member opens the solution, ReSharper will use that config.

UserSettings.xml relates to your settings, namely code cleanup. The only annoying thing of sharing a UserSettings.xml file is that team members can’t customise ReSharper themselves (do they need to?).

Here’s my older Solution.4.1.resharper file (I can’t remember if it’s compatible with v4.5) as an example.

StyleCop

If you open a solution now, you should get ReSharper suggestions regarding poorly styled code. Also the “Code Cleanup” should work quite effectively at cleaning up your code.

However, you’ll probably find ReSharper raising style errors for things you don’t see as errors. Hover over these suggestions and note down the Id. It’ll be something like “SA1004”. Spend a while going through a number of your projects and note down any rules you don’t like.

Now you need to create your Settings.StyleCop file. Right-click on any project in your solution and select “StyleCop Settings”. You can now disable any rules you don’t like (use the search, and type in the Id’s from the above step). This is my Settings.StyleCop file.

Once done go to the projects file system folder, and move the “Settings.StyleCop” file to where your solution file is. Add it to source control. If you reload Visual Studio it should now have:

  • Team .resharper settings
  • Shared UserSettings.xml file
  • StyleCop rules, and ReSharper suggestions

Enforcing Styling

The above steps set up a good framework for well styled code, but don’t enforce it. This is something that can be done using the build and NAnt.

Download StyleCopCommand, and add it to your source control. I place it in:

/trunk/tools/stylecopcommand

Using NAnt you can call StyleCopCommand using:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<project name="StyleCop" xmlns="http://nant.sf.net/release/0.86-beta1/nant.xsd" default="stylecop">
    <property name="stylecop.console" value="${source.directory}\tools\stylecopcmd\StyleCopCmd.exe" />
    <target name="stylecop">
        <exec program="${stylecop.console}">
            <arg line="-sf ${source.directory}\sln\Huddle.All.sln" />
            <arg line="-sc ${source.directory}\src\Settings.StyleCop" />
            <arg line="-of ${report.directory}\stylecop.xml" />
        </exec>
        <property name="violations.file" value="${report.directory}\stylecop.violations.count.xml" />
        <!-- Get the violation count for the previous build -->
        <property name="violations.previous" value="35000" overwrite="true" />
        <if test="${file::exists(violations.file)}">
            <xmlpeek file="${violations.file}" xpath="/Violations" property="violations.previous" failonerror="true"/>
        </if>
        <!-- Overwrite the xml, and get the violation count for the current build -->
        <style style="stylecop.xslt" in="${report.directory}\stylecop.violations.xml" out="${violations.file}.temp" />
        <xmlpeek file="${violations.file}.temp" xpath="/Violations" property="violations.current" failonerror="true" />
        <echo message="Previous style violations = ${violations.previous}" />
        <echo message="Current style violations  = ${violations.current}" />
        <fail if="${(int::parse(violations.current) > int::parse(violations.previous))}" message="More code style violations have been introduced. There are currently ${violations.current} violations. You need to reduce it by ${int::parse(violations.current) - int::parse(violations.previous)} for the build to pass." />
        <copy file="${violations.file}.temp" tofile="${violations.file}" failonerror="true" />
        <delete file="${violations.file}.temp" />
    </fail></target>
</project>

This will generate a “stylecop.xml” report along with a “stylecop.violations.xml”. You can then do a node count on the number of violations. This is tricky with NAnt so I use XSLT to do the node count, then NAnt to read the result.

1
2
3
4
5
6
7
8
9
< ?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <violations>
            <xsl:value -of select="count(//StyleCopViolations/Violation)"/>
        </violations>
    </xsl:template>
</xsl:stylesheet>

I also check the violation count of the previous build, with that of the current build. If it has increased, then I fail the build. It’s strict but we currently have 34,000 6,000 (it dropped around 25,000 in a few months) violations throughout our legacy code, so there’s plenty of code someone can clean up if they break the build.

The only annoying point, is that the violation total is kept on the build server. So there’s no easy (current) way of checking your local code has added any new violations. You only find out upon commiting. It hasn’t caused us too many problems just yet.

Conclusion

It will make some of the developers grumble, but deep down they’ll know it’s a good thing, and will improve the code you work with.

Opening a C# file that is messy and styled badly, immediately makes any developer not want to work with it, feel detached from it, and less ownership of it. It may sound a bit much for code, but it’s what we work with most of the day.

We’re now removing around 500 violations a day. This will probably slow in time, but for now it’s working very well. Maybe in the future we’ll change the build rules to be less strict.

Moving Forward

There are a number of things that can be done to improve all of the above:

  • Creating a StyleCop NAnt task to wrap up a lot of the logic shown above.
  • Defining where the current violation count lives, and allowing your local dev machine to check that count. That way you can be certain you’ve not added any styling violations.
  • The StyleCop report that is generated has all the violations. This isn’t helpful if you’ve added 3 new violations as you have no way of knowing what they were. It would be good to use CruiseControl XSLT templates to compare modifications against files that have style violations. You could then only show the violations that were introduced related to that commit.
  • Related to the above point. Rather than getting StyleCop to check every file, it would be handy to get it to check only the files that were committed. I’m not sure if this is possible, but if it is, then it would reduce build time drastically.

Reshaper

ReSharper is a renowned productivity tool that makes Microsoft Visual Studio a muchbetter IDE. Thousands of .NET developers worldwide wonder how they’ve ever lived without ReSharper’s code inspections, automated refactorings, blazing fastnavigation, and coding assistance.

http://www.jetbrains.com/resharper/