Create Custom plugin which can be deployed to sonarQube server

  • Add language-agnostic features?

Hi Team, I have a very specific requirement and would request some guidance on getting started on this.

Background :
I have a piece of code that scans the project repository for specific test classes and determine whether test method contain some pattern for example if contract test methods make calls using “RxHttpClient” pattern. My code scans the project repository, identifies all such methods. Currently I have this code running as a utility from jenkins, but ask is to integrate this at PR level using SonarQube.

Requirement - How to write a custom plugin or rule where I can integrate my code. In short, currently what my utility is doing (Scanning and identify contract test methods using specific pattern) I want to achieve same using Sonar.

Currently Sonar is running as part of PR, when I contacted plugin team, they asked to write a custom rule/plugin for this requirement and they will deploy it to server. I am new to this so having bit trouble getting started. Any suggestions would be really helpful.

Hi,

Welcome to the community!

Are you raising issues, or just counting to create metrics? If it’s issues, then it’s probably easier to just adapt your tool to output the generic issue format and feed the data in that way.

 
HTH,
Ann

thanks for responding.

I want to raise issues, I am able to create a custom rule using sonar-plugin-api and sonar-java-plugin which I believe serves my purpose, but i am having trouble writing unit tests for it.

I am on Java11 and using latest version of sonar-plugin and sonar java. Details below.

Java version - 11

  compile 'org.sonarsource.api.plugin:sonar-plugin-api:10.2.0.1908'
    compile 'org.sonarsource.sonarqube:sonar-batch:5.4'
    compile 'org.sonarsource.java:sonar-java-plugin:7.27.1.33504'
testCompile 'org.sonarsource.java:java-checks-testkit:7.17.0.31219'

I am unable to use

import org.sonar.java.checks.verifier.JavaCheckVerifier;

Error - Cannot resolve symbol ‘JavaCheckVerifier’

test code sample -

@Test
    public void testBasicCompliantPerformance() {
        CopyrightCheck rule = spy(new CopyrightCheck());
        JavaCheckVerifier.verify("src/test/resources/rulesTestFiles/java/CopyrightCheck_Compliant_Basic.java",
                rule);
    }

Is the new version doesn’t support this ?

Hi,

Are you sure JavaCheckVerifier is public?

 
Ann

I am not sure, but my code works on sonarqube version 7. After upgrading to version 10, started facing issues

Hi,

A lot has changed since SonarQube 7. You need to take a fresh look at your plugin code.

 
Ann

Sure will do. Can you point me to any example project if you have, where I can look for unit tests ? If there is any sample project for custom plugin development

Hi,

I’d start in the docs.

 
Ann

I mean sample project to build custom plugin with latest sonar version? I want to migrate to new version but facing lot of issues when upgraded to new version. Any reference project would help :slight_smile:

I could achieve to some extent what I want to do. Also able to write test with latest version.

I would need some help in proceeding further. If someone can help with below query would be really helpful.

I am visiting each method of a class under scan using ‘visitMethod’ . I need to get entire content of the method as string? So that for my custom plugin, I can check if any method contains certain string which we consider as violation. Basically want to check if certain String is present inside the method

Hi,

Can you post your code? Also, what language is this for?

 
Ann

@Override
    public void visitMethod(MethodTree tree) {
        super.visitMethod(tree);
             boolean usedRxHttpClient = false;

            // Traverse the method's block
            for (StatementTree statement : tree.block().body()) {
                if (statement.is(Tree.Kind.VARIABLE)) {
                    VariableTree variable = (VariableTree) statement;
                    System.out.println("Variable type is : " + variable.type());
                    // Check if the variable type is RxHttpClient
                    if ("RxHttpClient".equals(variable.type().toString())) {
                        usedRxHttpClient = true;
                        break;
                    }
                }
            }

            // Report an issue if RxHttpClient is used in the method
            if (usedRxHttpClient) {
                context.reportIssue(this, tree.simpleName(), "Method uses RxHttpClient");
            }
        }

Language - Java

Above is my code which checks Usage of RxHttpClient. Here I am checking for each variable declaration type within method. I am able to identify for some extent. This code is not working when RxHttpClient is declared within try catch block. Also I want to check for strings other than RxHttpClient.

Is there a way, instead of checking for variable type, can I just get entire method as string or traverse each statement and get the line as String so I can do String.contains() operation.

Hello @sumit_ghorpade,

I recommend you to go over the CUSTOM_RULES_101 guidelines, where you should get everything you need to write, test and add a custom rule to the Sonar Java Plugin. You can also find examples here.

You are asking for help in writing your custom rule logic, unfortunately, this is something that you need to figure out yourself. It can help you to look at how we implement our rules, you can find them here. Have a look at this to understand how to get type information from the semantic.

Wish you the best of luck in implementing your rule.

Cheers,
Angelo

1 Like

Hi @angelo.buono . thanks for responding. I am able to figure out my logic and it worked. I also need to create a custom rule which analysis the Kotlin files. However I am unable to find much documentation around that. Would you be able to point me to some documentation or example project for Kotlin?

I’m glad that you succeded in implementing your custom rule for the Java Plugin.

Unfortunately, there is no support for custom rules in the Kotlin Plugin. You can check Adding coding rules for the list of Sonar Plugins that support custom rules.

@angelo.buono - is there a way to add a rule which is language independent? My requirement is pretty simple. Describing my requirement below.

Scan all kotlin files in a specific folder (say ‘integrationTest’) and check if the kotlin files contain specific string? thats it.

is there a way to achieve this? Just scan .kt files in specific folder and check the presence of a string.

Any suggestions on this would be really helpful

Hi @sumit_ghorpade,

we specify and implement rules language by language. We have different teams specialized in different languages. It is possible to have the same rule defined in different languages, but their specification may be different and their implementation is independent.

I don’t recall any rule allowing the detection of a String within the file.

Feel free to look into the list of Kotlin Rules and search by yourself. In case you can’t find any suitable rule for your specific need you may:

  1. Open a new post in which you propose an idea for a new rule, that is backed by a valid rationale.

  2. Find a different tool more suitable for your task. In your case, a simple script may be enough, for example, grep -Rnw '/path/to/folder/' -e 'pattern'.

Generally, our rules are based on best practices that guarantee maintainable, reliable, and secure code.

Cheers,
Angelo

Hi @angelo.buono , thanks a lot for responding. I want to gate at PR level so going with Sonar option to block PR merge in case a file meets specific requirement.

Regarding custom rule for sonar, I found a link (2 years old), is this not officially supported? Is this a feasible solution to create custom rule for kotlin?

Hi @sumit_ghorpade, sonar-detekt is an unofficial fork of the official sonar-kotlin.

If you are using SonarQube, you can install your own plugins or 3rd party plugins, like sonar-detekt. Follow the guide Install a plugin.

Please look at the SonarQube Documentation for any other questions; you will find most of the answers there.

Cheers,
Angelo

1 Like