Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

iconfalse
titleTable of Contents
Table of Contents
maxLevel2

There are three two ways to extend coding rules:

  1. Writing custom rules in Java via a SonarQube plugin
  2. Adding XPath rules directly in through the Sonar SonarQube web interface.
  3. Extending an existing Sonar plugin. For example Checkstyle and PMD plugins accept definition of custom checks.
  4. Embedding and executing a code analyzer. For example the Checkstyle plugin configures and executes the library Checkstyle.

...

Note that the Java API, if available, will be more fully-featured than what's available for XPath, and is generally preferable.

Note

Before implementing a new coding rule,

...

you should consider whether it is specific to your own context or might benefit others. If it might benefit others, you can propose them on the developer list. If the SonarQube team find your proposed rules interesting, they may be implemented directly in the related language plugin. It means less maintenance for you, and benefit to others.

Writing Custom Rules in Java

The following languages can be extended with new rules written in Java: COBOL and Java.

Java

To get started a sample plugin can be browsed or downloaded/plugins/java-custom-rules.

To go further, you can have a look at the following classes implementing coding rules:

Notes:

COBOL

See how to extend COBOL rules.

Anchor
extendingRulesXPath
extendingRulesXPath

Adding New Rules Using XPath Expressions

Sonar SonarQube provides a quick and easy way to add new coding rules directly via the web interface for certain languages (C, /C++, CobolC#, COBOL, Flex, Java, JavaScript, PL/I, PL/SQL, Python and PythonVB.NET).

The rules have to must be written in XPath to  (version 1.0) to navigate the language's Abstract Syntax Tree (AST). For each language, an SSLR Toolkit is provided to help you navigate the AST. This Each language's SSLR Toolkit is a standalone application that displays the AST for a provided piece of code source . So that you quickly get the nodes feed into it, allowing you to read the node names and attributes to from your code sample and write your XPath expression from your code sample. The proper SSLR Toolkit can be downloaded from the language plugin page. So, finally, knowing the XPath language is the only prerequisite. A , and there are a lot of tutorials on XPath can be found online (see http://www.w3schools.com/xpath/ for example).

Detailed tutorial

Let's take  

For an SSLR preview, consider the following JavaScript source code sample:

Code Block
titleHelloWorld.js
linenumberstrue
languagejavascript
function HelloWorld(hour) {
  if (hour) {
    this.hour = hour;
  } else {
    var date = new Date();
    this.hour = date.getHours();
  }
  this.displayGreeting = function() {
    if (this.hour >= 22 || this.hour <= 5)
      document.write("Good night, World!");
    else
      document.write("Hello, World!");
  }  
}

While parsing the source code, Sonar builds SonarQube builds an Abstract Syntax Tree (AST) .An SSLR Toolkit is provided by each language supporting XPath to get a representation of this ASTfor it, and the SSLR Toolkit provided for each language will show you SonarQube's AST for a given piece of code. Here's the AST for our JavaScript sample:

The XPath language provides a way to write coding rules by navigating this AST.To create a new rule, and the SSLR Toolkit for the language will give you the ability to test your new rules against your sample code.

Once your new rule is written, you can add it SonarQube:

  1. Login as an Quality profile administrator
  2. Go to Configuration > Quality Profile
  3. Select one of the quality profiles whose for the language you want wish to add a new the rule to
  4. Look for the XPath rule template:
    Image RemovedImage Added
  5. Copy this the template to create a new rule:
  6. Write your Paste in the XPath rule (it should comply to XPath 1.0) you wrote and tested using the SSLR toolkit:


    Here are two examples of JavaScript XPath rules:

    Do not use document.write

    Code Block
    languagenone
    //callExpression/memberExpression[count(*) = 3 and primaryExpression[@tokenValue = "document"] and identifierName[@tokenValue = "write"]]


    Always use curly braces for if/else statements:

    Code Block
    languagenone
    //ifStatement/statement[not(block)] 

     

     

  7. Once written, activate those rules and run a Sonar Once your rule is added to SonarQube, activate it in a profile and run an analysis.
     
  8. Violations Issues on those XPath rules are now logged:

Extending Sonar Plugins

The following languages can be extended with new rules:

Executing a Code Analyzer

A code analyzer plugin executes the following steps:

  1. Register definitions of coding rules, when the server is started.
  2. Optionally define some templates of quality profiles, when the server is started.
  3. Analyze source code and inject results in database 

1. Registering coding rules

This step relates to the extension point org.sonar.api.rules.RuleRepository. A RuleRepository defines a set of coding rules. It usually loads data from a XML file:

...

public class CheckstyleRuleRepository extends RuleRepository { 
  // this sonar component is injected in constructor
  private XMLRuleParser xmlRuleParser; 

  public CheckstyleRuleRepository(XMLRuleParser xmlRuleParser) {   
    super("checkstyle", Java.KEY);
    setName("Checkstyle");   
    this.xmlRuleParser = xmlRuleParser; 
  } 

  @Override public List<Rule> createRules() {
    // the InputStream is closed in xmlRuleParser
    return xmlRuleParser.parse(getClass().getResourceAsStream("/org/sonar/plugins/checkstyle/rules.xml"))); 
  }
}

The XML file is available in the plugin classloader and looks like :

...

 <rules> 
  <!-- the format used before sonar 2.3 is still supported : attributes key and priority on the node <rule> -->
  <rule>
    <!-- unique key within this repository -->
    <key>com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck</key>
    <name>Header</name>
    <!-- default priority when the rule is activated (optional, default value is MAJOR). Values are INFO, MINOR,
         MAJOR, CRITICAL, BLOCKER -->
    <priority>MAJOR</priority>

    <!-- this key is used later by the sensor to configure the code analyzer --> 
    <configKey>Checker/Header</configKey>
   
    <!-- available ISO categories : Reliability, Portability, Maintainability, Efficiency, Usability -->
    <category name="Usability"/>

    <!--
    This node is optional: default value is SINGLE.
    MULTIPLE: the rule can be activated many times with different parameters and priority.
    SINGLE: the rule can be activated once
    --> 
    <cardinality>SINGLE</cardinality>

    <description><![CDATA[Checks that ...]]></description>
    <param>
      <key>header</key>
      <description><![CDATA[the required header specified inline. Individual header lines must be separated by the string "\n" (even on platforms with a different line separator)]]></description>
    </param>
    <param>
      <key>ignore</key>
      <description>...</description>
      <defaultValue>false</defaultValue>
    </param>
  </rule>
</rules>

2. Defining quality profiles

This step relates to the extension point org.sonar.api.profiles.ProfileDefinition. Profiles provided by plugins are registered at server startup  and can't be edited by users:Image Removed

3. Analyzing source code

This step relates to the extension point org.sonar.api.batch.Sensor.