sonar自定义规则

Sonar并不是简单地把不同的代码检查工具结果(例如 FindBugs,PMD 等)直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。

sonarqubue默认的对java的检测规则不一定适合我们,可以自己去自定义rules。

禁用rules

Rules-Quality Profile- Sonar way Java
查看激活的规则,可以禁用,或者更改严重级别(Severity)
sonar自定义规则_第1张图片

自定义rules

sonar提供XPath或Java方式的扩展,有的语言支持XPath,有的只能支持Java,比如Java语言只支持Java方式的扩展。具体详见Support of Custom Rules by Language

步骤如下:

  • 创建一个SonarQube插件

  • 增加相关依赖

  • 创建自定义rules

  • 生成插件的jar包

  • 将该jar包放在SONARQUBE_HOME/extensions/plugins目录下

  • 重启SonarQube

添加maven依赖


        UTF-8
        UTF-8
        1.8

        5.6
        4.2
        1.17

        1.20
        4.12
        1.4
        1.1.3

    
    
        
            org.sonarsource.sonarqube
            sonar-plugin-api
            ${sonar-plugin-api.version}
            provided
        
        
            org.sonarsource.java
            sonar-java-plugin
            ${sonar-java-plugin.version}
            sonar-plugin
            provided
        
        
            org.sonarsource.java
            java-checks-testkit
            ${sonar-java-plugin.version}
            provided
        

        
            org.codehaus.sonar.sslr
            sslr-testing-harness
            ${sslr-testing-harness.version}
            test
        
        
            junit
            junit
            ${junit.version}
            test
        
        
            org.easytesting
            fest-assert
            ${fest-assert.version}
            test
        
        
            ch.qos.logback
            logback-classic
            ${logback-classic.version}
            test
        

        
        
        
            org.codehaus.sonar.sslr-squid-bridge
            sslr-squid-bridge
            2.6
            
            
                
                    org.codehaus.sonar
                    sonar-plugin-api
                
            
        
        
        
            com.google.code.gson
            gson
            2.6.2
        
        
            com.google.guava
            guava
            19.0
        
        
            commons-codec
            commons-codec
            1.10
        
        
            commons-io
            commons-io
            2.4
        
        
            commons-lang
            commons-lang
            2.6
        


    
    
        
            
                org.sonarsource.sonar-packaging-maven-plugin
                sonar-packaging-maven-plugin
                ${sonar-packaging-maven-plugin.version}
                true
                
                    java-custom
                    Java Custom Rules
                    
                    com.xixicat.sonar.MySonarPlugin
                    true
                    5.6 
                
            
        
    

这里的依赖要小心配置,记得exclude掉sonar-plugin-api,才可以加载其他相关依赖,然后显示依赖用到的jar,否则容易报class not found

编写plugin

创建plugin入口

public class MySonarPlugin implements Plugin {
    public void define(Context context) {
// server extensions -> objects are instantiated during server startup
        context.addExtension(MyJavaRulesDefinition.class);

        // batch extensions -> objects are instantiated during code analysis
        context.addExtension(MyJavaFileCheckRegistrar.class);
    }
}

这个类实现了org.sonar.api.Plugin接口,主要添加两类扩展:

  • server extensions
    在sonarqube server启动时实例化,实现org.sonar.api.server.rule.RulesDefinition接口

public class MyJavaRulesDefinition implements RulesDefinition {

    public static final String REPOSITORY_KEY = "myRepo";

    public void define(Context context) {
        NewRepository repository = context.createRepository(REPOSITORY_KEY, Java.KEY);
        repository.setName("my sonar repo");
        AnnotationBasedRulesDefinition.load(repository, "java", RulesList.getChecks());
        repository.done();
    }
}

public class RulesList {

    private RulesList() {
    }

    public static List getChecks() {
        return ImmutableList.builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
    }

    public static List> getJavaChecks() {
        return ImmutableList.>builder()
                .add(AvoidSmallerLengthVariableNameRule.class)
                .build();
    }

    public static List> getJavaTestChecks() {
        return ImmutableList.>builder()
                .build();
    }
}
  • batch extensions
    在分析代码的时候实例化,实现org.sonar.plugins.java.api.CheckRegistrar接口

public class MyJavaFileCheckRegistrar implements CheckRegistrar {
    public void register(RegistrarContext registrarContext) {
        // Call to registerClassesForRepository to associate the classes with the correct repository key
        registrarContext.registerClassesForRepository(MyJavaRulesDefinition.REPOSITORY_KEY,
                Arrays.asList(checkClasses()), Arrays.asList(testCheckClasses()));
    }

    /**
     * Lists all the checks provided by the plugin
     */
    public static Class[] checkClasses() {
        return new Class[] { // List of rules to be included here
                AvoidSmallerLengthVariableNameRule.class
        };
    }

    /**
     * Lists all the test checks provided by the plugin
     */
    public static Class[] testCheckClasses() {
        return new Class[] {};
    }
}

创建规则

import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.VariableTree;
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;

@Rule(key = "AvoidSmallerLengthLocalVariableName",
        name = "Avoid usage of the smaller length in local variable name",
        description = "This rule detects usage of smaller length local variable name. Variable name should not be smaller than 4 characters.",
        tags = {"coding-guideline"},
        priority = Priority.MINOR)
@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
//SQALE全称是Software Quality Assessment based on Lifecycle Expectations,是一套评估代码质量的方法。
@SqaleConstantRemediation("10min") //纠正所需时间
public class AvoidSmallerLengthVariableNameRule extends BaseTreeVisitor implements JavaFileScanner {

    private static final String DEFAULT_VALUE = "SmallerLengthLocalVariable";

    private JavaFileScannerContext context;

    /**
     * Avoid usage of the smaller length in local variable name in Quality profiles.
     * The key
     */
    @RuleProperty(
            defaultValue = DEFAULT_VALUE,
            description = "Avoid usage of the smaller length in local variable name")
    protected String name;

    public void scanFile(JavaFileScannerContext context) {
        this.context = context;
        scan(context.getTree());
    }


    @Override
    public void visitVariable(VariableTree tree) {
        String variableName = tree.simpleName().name();
        System.out.println("Scanning the variable : " + variableName);
        if(variableName.length() < 4) {
            context.reportIssue(this,tree, "Variable length is less than 4 characters");
        }
        super.visitVariable(tree);
    }
}

打包plugin

mvn clean package sonar-packaging:sonar-plugin

拷贝到plugins

cp target/sonar-rule-demo-0.0.1-SNAPSHOT.jar ~/sonar/extensions/plugins

run

docker run --rm  \
 -e JAVA_OPTS='-Xmx1g' \
  -v /Users/xixicat/sonar/data:/opt/sonarqube/data \
  -v /Users/xixicat/sonar/extensions:/opt/sonarqube/extensions \
  -p 9000:9000 -p 9092:9092 \
  -e SONARQUBE_JDBC_USERNAME=sonar \
  -e SONARQUBE_JDBC_PASSWORD=sonar \
  sonarqube:lts-alpine

查看自定义的规则

sonar自定义规则_第2张图片

doc

  • Build Plugin

  • Support of Custom Rules by Language

  • Adding Coding Rules using Java

  • java-custom-rules

  • Custom-Java-Plugin-For-SONAR

  • Analyzing with SonarQube Scanner

  • How to create custom rules in Sonarqube for java and implement the same?

你可能感兴趣的:(sonar)