Posts Tagged With SonarQube ReSharper Plugin - Musing, Rants & Jumbled Thoughts

Header Photo Credit: Lorenzo Cafaro (Creative Commons Zero License)

Well, it seems the perceived success of my SonarQube ReSharper plugin was it's own downfall. Less than 30 days after it's official release, that plugin, as it exists today, is now officially deprecated. The SonarSource team has taken it upon themselves to completely rewrite ReSharper integration with the next release of what is currently called the ".net ecosystem" plugins (coming this month) and I am bowing out of developing for SonarQube.

And as I was writing this post, I received an email from SonarSource with this:

I didn't want to touch your repository at the time I started this work, because I would indeed have needed to discuss this with you first, and I was under some time pressure.

You also correctly identified that this implies that your plugin is de facto end of lifed.

I am going to have to ask for the removal of the repository, and to prefix your Jira component name by "(Deprecated)".

This will remove any possible confusion between your plugin and the library.

Seems they are more than happy to run me out of town, but want me to hang my own eviction notice -- perhaps as some sort of extra humiliation?

Unfortunately, it is unlikely I can even use the new plugin, as it will not support reuseReport mode. Additionally, SonarSource's stated (and restated) goal is to eventually drop support for ReSharper and all third-party tools, so this is a temporary solution.

While I am in a "wait and see" mode right now to determine if I will even continue utilizing SonarQube at all once these changes go live with v4.2, I will not be providing additional support or fixes for the current sonar-dotnet-resharper plugin.

This makes me very sad -- and angry. But I guess I should have seen this coming, considering just getting the ReSharper plugin approved was like pulling teeth, and then my NUnit integration plugin was killed. Shame on me for not seeing this coming. Or maybe my Java skills are just that bad.

So, that's all for my involvement with the SonarQube ReSharper integration. I appreciate those who helped while it lasted, and hope those of you who are using it are able to continue with the new version.

If you want the details, just take a look at the last two weeks on the SonarQube dev mailing list. There are too many threads to list here.

Personally, I have two other side projects currently active. I'm helping out with the That Conference organization team and I'm working with a couple of friends to write an Azure Cloud plugin for TeamCity.



I'm happy to announce that v1.1 of my SonarQube plugin for integrating ReSharper analysis into SonarQube has been released. This is the first public release of the plugin and users can now install it from the built-in SonarQube Update Center.

For existing beta and v1.0 users, please read the important upgrade note at later in this post.

If you are interested in installing this plugin, please read the official documentation and installation instructions.

Overview

The basic idea is this: The good folks at JetBrains have released a commandline-based tool (called “InspectCode”) allowing users to run ReSharper code analysis outside of Visual Studio and generate an XML-based file listing the various issues it detected in your codebase. Oh, and it’s free!

I felt this lined up very well with SonarQube, and wrote a SonarQube plugin to (optionally) execute the ReSharper analysis and consume the results, publishing them into SonarQube as Issues, allowing users to take advantage of the management, planning, reporting, etc, features of SonarQube to manage their code quality and technical debt.

The plugin supports reusing existing reports generated by the ReSharper "inspectcode.exe" tool, or, if the user has separately installed the tools, it supports running the analysis as part of the SonarQube runner. This mirrors the process used for the other .NET ecosystem tools such as FxCop and StyleCop. The JetBrains tools are not bundled with the plugin.

Related: See my other post on Setting up SonarQube analysis for C# projects

What You Can Expect To See

Something like this in Visual Studio:

Violation in Visual Studio

Will turn into this in SonarQube:

Violation in SonarQube

Installation

If you are interested in installing this plugin, please read the official documentation and installation instructions.

IMPORTANT NOTE FOR EXISTING v1.0 USERS:

Between v1.0 and v1.1 of the plugin, the format of the rule keys was changed to remove the use of colons (:). The change in rule keys will cause any customization to those rules to be lost after the upgrade and the new rules will need to be activated in the Quality Profiles.

Disclaimers

I am not associated with JetBrains in any way, aside from being a big fan of many of their products. I have, however, received free licenses to JetBrains products (ReSharper and dotPeek) over the years via raffles at the (now defunct) Chicago Alt.Net Users Group, which was sponsored by JetBrains.



Update 2014-02-06: The SonarQube .NET ReSharper plugin has been released. See my release announcement.

For those of you following along with the SonarQube ReSharper plugin, here's an update on where things currently stand.

JetBrains released version 8.1 of the ReSharper commandline tools back in early December, so I consider version 1.0 of the plugin to have been "released" around that time... and there are a handful of folks out there using it! However, I was unsuccessful in getting the necessary votes on the SonarQube developers mailing list to get the plugin published to the official Update Center, which would make it uber simple for others to install and use the plugin. I must say, I was quite disappointed that I only managed one "+1" vote of the required three. (For the uninitiated, the rules for getting a plugin officially released require three "+1", or "yes" votes and no "-1" or "no" votes from the existing developers group.) As discussed on the dev mailing list, there's not much incentive for the developers on the list, who are, by definition, Java developers, to try, test and therefore vote on plugins for .NET (or other languages), thus making the bar very high for new developers to make the cut. Generally, the call for a vote stays open for under a week -- in my case, it was open for more than a month before I threw in the towel.

Since then, however, someone else reported an issue with the rule keys used by the plugin (which map directly to the ReSharper rule keys) that cause the Issues Report plugin to fail.

Additionally, several users have asked for the ability to provide a ReSharper dotSettings file while running analysis directly in the plugin.

And I've had a few people contact me to say they'd like to submit pull requests for features they'd like to see as well.

So, I'm planning to work on version 1.1 over the next month or so to fix the rule key issue and add a few of the user-requested features (especially if pull requests are submitted). And at that point, re-try to get the plugin officially hosted in the Update Center. I am putting a somewhat hard limit on a month to get this wrapped up, as my "volunteer" time will be shifting to support That Conference 2014, likely up until the actual conference, Aug 11-13th.



I was recently asked in an email if I knew of any tools that would translate the XML results file from the JetBrains ReSharper command line tool inspectcode into a human readable format, such as HTML. For your viewing pleasure, here was my response:

There aren't any tools out there yet to convert the XML to HTML, but the XML format is fairly simple, so I suspect it wouldn't take much to write your own.

The file is broken into two sections <IssueTypes> and <Issues>

Under <IssueTypes>, there's a collection of <IssueType> elements, which list all of the violation types that were discovered in your code. Each one has the following possible attributes:

  • Id
    • This is the unique identifier for the rule
  • Category
    • This is a general grouping for the rule types
  • SubCategory (optional)
    • some of the groupings are further split
  • Description
    • This is a general description of what the rule is checking
  • Severity
    • One of these values: ERROR, WARNING, SUGGESTION, HINT, DO_NOT_SHOW
  • WikiUrl (optional)
    • A link to a jetbrains webpage that has additional details about the rule

In the <Issues> section are the specific instances of rule violations found in your code. Under <Issues>, you will find a collection of <Project> elements, each with a Name attribute which will match your Visual Studio project name. Under each <Project> attribute will be a collection of <Issue> elements, each with the following attributes:

  • TypeId
    • A reference to the rule in the collection, where the TypeId here is a match for the Id in the element
  • File
    • The file path that contains the violation. This path is relative to the Visual Studio Solution's folder
  • Line
    • The line number in the file where the issue occurred
  • Message
    • A message about why this line of code violated the rule. The message is case-specific and often include the variable name or other context information specific to this line of code.
  • Offset
    • I'm 100% sure what this actually represents, but from what I can tell, it's the character range (offset from start of file) of the specific text in the file that violates the rule. In Visual Studio, this would be the text that is highlighted/underlined, etc. So a value of "1684-1722" would be the 1684th character in the file through the 1722nd character.

Hope that helps



Update 2014-02-06: The SonarQube .NET ReSharper plugin has been released. See my release announcement. Since my last post announcing my SonarQube plugin, it has been accepted into the SonarQube Community plugins, including hosting of documentation, issue tracking, and builds on the SonarSource servers, and moving the code into the SonarCommunity GitHub repository, with a path for eventual inclusion in the SonarQube Update Center for easy distribution to users.

Before I open the gates and push a formal release to the public, I'd like to get some beta testers to use the plugin and work out any rough edges. If you're using SonarQube for your .Net-based projects, I'd love to have you as an early adopter and get your feedback.

Overview



The basic idea is this: The good folks at JetBrains have released a commandline-based tool (called "InspectCode") allowing users to run ReSharper code analysis outside of Visual Studio and generate an XML-based file listing the various issues it detected in your codebase. Oh, and it's free!

I felt this lined up very well with SonarQube, and wrote a SonarQube plugin to (optionally) execute the ReSharper analysis and consume the results, publishing them into SonarQube as Issues, allowing users to take advantage of the management, planning, reporting, etc, features of SonarQube to manage their code quality and technical debt.

What You Can Expect To See

Something like this in Visual Studio: Violation in Visual Studio

Will turn into this in SonarQube: Violation in SonarQube

How To Get Started



For this beta, I'm assuming you're already a SonarQube user and have successfully configured analysis for your .Net solutions. If that's not the case, take a look at my post on setting up SonarQube analysis for C# projects.

The official documentation for installing this plugin can be found on the SonarQube Wiki page for this plugin, which I'm still building out, and will change over time to reflect the current state of things. For now, here's the process:

Download resharper EAP and run a local analysis First, make sure the InspectCode tool is working for you. Download the ReSharper Command Line Tools (they come as a .zip file) and extract them into the folder of your choosing. For the purpose of this posting, I'm assuming you used C:\jetbrains-commandline-tools\.

Open a command prompt and run inspectcode.exe /help. You should see a usage statements printed to the console.

Now change into the folder with your VS Solution file and run the command c:\jetbrains-commandline-tools\inspectcode.exe /output=resharper-results.xml YourSolutionFile.sln

Warning: This may take a very long time to run, possibly a couple hours for very large projects. I would suggest starting with a small project and maybe grabbing some lunch.

One this completes, you should have a resharper-results.xml file in your solution folder, which will look a little like this:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by InspectCode 8.0.0.0 -->
<Report ToolsVersion="8.0">
    <Information>
        <Solution>Example.sln</Solution>
        <InspectionScope>
            <Element>Solution</Element>
        </InspectionScope>
    </Information>
    <IssueTypes>
        <IssueType Id="CSharpWarnings::CS0162" Category="Compiler Warnings" Description="CS0162:Code is unreachable" Severity="WARNING" />
        <IssueType Id="CanBeReplacedWithTryCastAndCheckForNull" Category="Potential Code Quality Issues" Description="Type check and direct cast can be replaced with try cast and check for null" Severity="SUGGESTION" />
        <IssueType Id="ClassNeverInstantiated.Global" Category="Potential Code Quality Issues" Description="Class is never instantiated: Non-private accessibility" Severity="SUGGESTION" />
        <!-- ... -->
    </IssueTypes>
    <Issues>
        <Project Name="Example.Application">
            <Issue TypeId="RedundantUsingDirective" File="Example.Application\\Program.cs" Offset="910-943" Line="22" Message="Using directive is not required by the code and can be safely removed" />
            <Issue TypeId="RedundantUsingDirective" File="Example.Application\\Program.cs" Offset="945-963" Line="23" Message="Using directive is not required by the code and can be safely removed" />
            <!-- ... -->
        </Project>
        <Project Name="Example.Core">
            <Issue TypeId="RedundantUsingDirective" File="Example.Core\\IMoney.cs" Offset="895-908" Line="21" Message="Using directive is not required by the code and can be safely removed" />
            <Issue TypeId="RedundantUsingDirective" File="Example.Core\\IMoney.cs" Offset="910-943" Line="22" Message="Using directive is not required by the code and can be safely removed" />
            <!-- ... -->
        </Project>
    </Issues>
</Report>

If that all works, then you're ready to start using the plugin.

  • Download the sonar-dotnet-resharper-plugin from the build server and place it in your SONARQUBE_SERVER_HOME/extensions/plugins folder.
  • Restart your SonarQube service
  • Login to the SonarQube server with an admin account and head over to the Quality Profiles page and select the profile used by your .Net project (this may be the "Sonar way" profile, or one you've created on your own).
  • In the search fields, set the Repository to ReSharper and the Activation to Any and click "Search". You should be presented with a list of approx 650 rules supported by ReSharper's tool. In the upper right corner of the results list is a Bulk Change option. Choose Activate all. This will (immediately) activate all of the ReSharper rules for this profile.
SonarQube Quality Profile Bulk Change
  • Modify your sonar-project.properties file to include the following:
    # ReSharper settings
    sonar.resharper.mode=reuseReport  #leave blank (run ReSharper during sonar analysis), 'skip' to deactive, or 'reuseReport' (recommended) and provide a previously generated results file
    sonar.resharper.report.path=$(SolutionDir)/resharper-results.xml
    #sonar.resharper.installDirectory=c:/jetbrains-commandline-tools  #only needed if running during sonar analysis
    #sonar.resharper.timeoutMinutes=10 #optional, and only if running during sonar analysis
  • Execute sonar-runner and get yourself a cup of coffee. For really big projects this could take half and hour or more.
  • Bask in the glory of your new ReSharper-based Issues in the SonarQube web UI.

A Note About Rule Severity



ReSharper users a four-tier severity (plus a "Do Not Show" option), while SonarQube uses a five-tier system. I have mapped the ReSharper values like this:

ReSharper SonarQube
Error Blocker
Warning Critical
- Major
Suggestion Minor
Hint Info
Do Not Show Info

While some of the ReSharper rules are marked as Do Not Show by default, the plugin maps them to Info so that you can modify their visibility via the Quality Profile. If you want them to not show, disable the rules in the Quality Profile. You can, of course, change any of these levels for any rule using the Quality Profile, and I fully expect most people will want to downgrade a lot of the Critical rules to Major and a lot of Info to be turned off.

Reuse Report vs Run During Analysis



The ReSharper analysis can be very time consuming for large solutions with many projects, sometime taking multiple hours to run if the cache has to be rebuilt, so I would suggest users favor the reuseReport mode when possible. This reduces the number of times the analysis is executed, since running it during the sonar-runner will analyze each project separately, adding significant analysis time, even with heavy caching in the ReSharper tool.

To use the reuseReport option you'll need to use the inspectcode.exe utility to analyze your solution before executing sonar-runner. There are several command line options for the tool, but at minimum, you’ll need this:

inspectcode.exe -o=resharper-results.xml YourSolutionName.sln

Where -o=resharper-results.xml will write the results into the file name you provide. Note: by default (without the -o argument), inspectcode will write the file to the temp directory. You’ll need this file to provide to the plugin.

Analysis times

The amount of time required to run the inspectcode analyzer and import the results into SonarQube can vary based on several factors. Here is some representative data to give you some guidance on how long it will take, based on two actual projects I'm analyzing.

Small Project Larger Project
Lines of Code 27,515 593,979
VS Projects in Solution 10 39
Standalone InspectCode 4min 1hr 24min
Sonar-Runner (ReuseReport) 2min 35min
Sonar-Runner (embedded InspectCode) 11min 2hr 58min

All cases had an existing ReSharper cache. Excludes unsupported project types, such as WiX (installer) projects. Includes only the .NET ReSharper plugin and the base C# plugins (ie: does not include FxCop, Gallio/Unit Tests, etc). Timings are based on running within a TeamCity CI build on a decently powerful server. Obviously, your times will vary and these represent only a guidepost for how much variation can happen between runs.

Known Issues / Limitations



The ReSharper command line tools are fairly new and still have a few kinks to work out. I would suggest always using the newest possible version, including new EAP builds of 8.1 while it is still in development.

Inconsistent results from inspectcode

From one run to the next, you may get a different list of rule violations from ReSharper, even without code changes. This means you will have violations come and go in SonarQube without the underlying issue actually being addressed. In my tests, for a large project like the Windows Azure .net library, I saw a 4% difference (~430 rules delta on ~12,000 total)

See RSRP-390005 - inspectcode provides inconsistent results

Data quality issues in available rules

With the 8.1 EAP builds, JetBrains has added a commandline switch to inspectcode to dump the list of possible issuetypes that could be reported. There are a couple of data issues in that output, which I have worked around in the plugin:

See RSRP-390380 - inspectcode /dumpIssuesTypes includes duplicate entries for "StructuralSearch" and RSRP-390375 - IssueType "InvocationIsSkipped" has undocumented "INFO" severity

"Sonar.UnknownIssueType" Violation

SonarQube requires that the rule database be populated up front, at server start. ReSharper provides a list of possible violation types for their tool via the /dumpIssuesTypes argument, and I've populated the SonarQube rule repository using these values. However, as new versions come out, or you add your own ReSharper plugins to generate new IssueTypes, it’s possible that you will have violations in your code that the plugin did not know about when the server started, so cannot import into SonarQube appropriately. When the plugin comes across one of these, it will write a log statement (to the runner’s log) and generate a "Sonar.UnknownIssueType" violation with instructions on how to add the rule information to the 'ReSharper custom rules' property in the Settings UI. After adding that setting and restarting SonarQube, future analysis runs will support those IssueTypes.

unknown violation setting

Other File Types

While the ReSharper tools support the full .Net stack, including .xaml and other file types, The sonar-dotnet API does not currently support more than one language (C# or VB.net) for a given project. For .xaml and other files, the plugin attempts to report the violation against the file, but they may end up attached to the project instead. In either case, the source code for the .xaml or other unsupported file type will not be imported into SonarQube.

Future plans and release timeline



There are a handful of things I want to see before I release version 1.0, which will go out in the Update Center for general public consumption:

  • ReSharper 8.1 released. I feel like the 8.0 release of the command line tools just isn't viable for use with SonarQube, primarily due to the inconsistent results from one run to the next. This also ensures any breaking changes they make before 8.1 ships are caught and addressed in the plugin. JetBrains has not publicly stated when they thing 8.1 will be released.
  • A handful of early adopters are using the plugin and providing feedback (and are happy with it).
  • I've addressed any high-value tickets in JIRA. I'm using the NETRESHARPER-1.0 release to track things targeted for the public release.

Other features I'm hoping to include, but are not guaranteed:

  • additional configuration settings to modify the inspectcode arguments when running directly. For example: ability to set the cache folder path, disable solution-wide analysis, use of a R# settings file, etc.
  • utilize and document ReSharper plugins in the inspectcode analysis. This is a core feature we're looking to utilize at work to make the dev-time experience match the CI server analysis for company coding standards enforcement. This may "just work", but is dependent on JetBrains releasing the 8.1 SDK nuget packages, which will be "later this autumn".

Disclaimers



I am not associated with JetBrains in any way, aside from being a big fan of many of their products. I have, however, received free licenses to JetBrains products (ReSharper and dotPeek) over the years via raffles over the years at the Chicago Alt.Net Users Group, which is sponsored by JetBrains.



Update 2014-02-06: The SonarQube .NET ReSharper plugin has been released. See my release announcement.

Update - I've moved my plugin into the "SonarQube Forge" and hosting the source, etc, under the SonarCommunity plugins. The information on this page is now stale. See my post SonarQube .Net ReSharper Beta Release for updated information.


I've created a fork of the SonarQube .Net ecosystem plugin's GitHub repository with the purpose of adding a new plugin to support the free JetBrains ReSharper command line code inspection tool. I have full intention of submitting this back to the main SonarQube dotnot plugin repository once it's stabilized, under SONARDOTNT-348.

The fork can be found at https://github.com/johnmwright/sonar-dotnet(no longer hosted here), if you want to try it yourself. I provide no warranty, no guarantee and limited support (I'm just one guy, doing this in 30-minute chucks on my train ride to/from work). I'm using the LGPL v3 license for this code, same as the .Net ecosystem plugins, so the code is open for anyone -- thus the use of GitHub. You are free to modify it yourself, in accordance with the license, and I will accept pull request, should you wish to provide them.

Currently, this plugin only support reusing an existing report, although I will be adding support to run the analysis directly in the next month or so.

Installation Instructions:

Install .NET plugins 2.2-SNAPSHOT

This plugin requires you use the "2.2-SNAPSHOT" builds of the C#/.NET plugins for SonarQube. While you can build these from within my fork, since I'm not actively integrating upstream changes, I suggest you don't use these and pull from the official sources. I will provide some support for the ReSharper plugin, but for the rest of the .NET Ecosystem plugins you should go through the upstream maintainers.

Install ReSharper Command Line Tools and Analyze

To use the new sonar-dotnet-resharper-plugin, you'll need to download the ReSharper command line tools from JetBrains and use the inspectcode.exe utility to analyse your solution. There are several command line options for the tool, but at minimum, you'll need this:

    inspectcode.exe -o=resharper-results.xml YourSolutionName.sln

Where -o=resharper-results.xml will write the results into the file name you provide. Note: by default (without the -o argument), inspectcode will write the file to the temp directory. You'll need this file to provide to my SonarQube plugin.

You can also optionally provide the name of a single project in the solution to limit the analysis to just that project.

Install My Plugin

Install the sonar-dotnet-resharper-plugin into your SonarQube server's \extensions\plugins folder and restart the SonarQube server. In the server's log file, you should see lines like this:

    2013.09.12 22:22:08 INFO  org.sonar.INFO  Register rules [resharper-cs/cs]...
    2013.09.12 22:22:09 INFO  org.sonar.INFO  Register rules [resharper-cs/cs] done: 718 ms
    2013.09.12 22:22:09 INFO  org.sonar.INFO  Register rules [resharper-vbnet/vbnet]...
    2013.09.12 22:22:09 INFO  org.sonar.INFO  Register rules [resharper-vbnet/vbnet] done: 313 ms

Now, add the following to your sonar-project.properties file(s):

    #ReSharper
    sonar.resharper.mode=reuseReport
    sonar.resharper.reports.path=resharper-results.xml

Where the value of sonar.resharper.reports.path is the path to the ReSharper results file relative to each project file. This has the current limitation (same as the FxCop and other sonar-dotnet plugins) of requiring the same relative path be used for all projects. As such, if your filesystem layout has project files at different depths relative to the results file, you will have to copy the results file to each project's folder so that the relative path works.

Right now, for sonar.resharper.mode it only supports reuseReport. In the (near) future I will add the ability to directly run project-level ReSharper analysis instead of reusing a report, which will work much better for people that have differing depth project files.

Modify Your Project's Quality Profile

If you install the sonar-dotnet-resharper-plugin on a clean system where you have not modified the "Sonar way" Quality Profile, then all of the new ReSharper-based rules will be included and enabled immediately. However, if you have modified that profile or have your own custom profile(s), you will need to enable the ReSharper rules for that profile. To do this, go into the SonarQube web UI, click the "Quality Profiles" link in the header bar, and choose the profile you wish to include ReSharper results.

In the filter boxes, choose "ReSharper" in the Repository field and "Any" from the Activation field and submit. I expect you'll see a list of approx 240 rules, all disabled. In the upper right corner of the results list is a "Bulk Change" option. Choose "Activate all". This will (immediately) activate all of the ReSharper rules for this profile.

A Note About Rule Severity

ReSharper users a four-tier severity, while SonarQube uses a five-tier system. I have mapped the ReSharper values like this:

ReSharper SonarQube
Error Blocker
Warning Critical
Major
Suggestion Minor
Hint Info

Note that there is no mapping to the SonarQube 'Major' category, but this is the fall-back/default value SonarUses for a rule, so if you see any (or all) of the ReSharper rules in this tier, please let me know -- there was likely an error importing the rules into your SonarQube installation.

You can, of course, change these levels for any rule using the Quality Profile, and I fully expect most people will want to downgrade a lot of the 'Critical' rules to 'Major'.

Run the sonar-runner!

Now run sonar-runner on your SonarQube project. You should now see your new ReSharper violations in the SonarQube web reports.

Current limitations

SonarQube requires that the rule database be populated up front, at server start. However, ReSharper does not (yet) publish a list of possible violation types for their tool, so the rules in the plugin are only those which I've come across so far in my own C# projects. This means that it's possible, likely even, that you will have violations in your code that the plugin does not know about, so cannot import into SonarQube appropriately. When the plugin comes across one of these, it will write a log statement (to the runner's log). In a future release, it log more information on how to 1) submit that rule back to me for inclusion in a future plugin build and 2) add it to a local supplement file for inclusion in your local rules. For now, if you hit this, you can email me with the block of your ReSharper results block and I'll update the plugin. Also, I have an open request with JetBrains to provide a mechanism to get the full list of violations up front so that this issue will be less likely going forward.

The sonar-dotnet API does not currently work for .xaml files, so any violations in .xaml files are not reported in SonarQube.