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

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

禁用rules

Rules-Quality Profile- Sonar way Java

查看激活的规则,可以禁用,或者更改严重级别(Severity)

自定义rules

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

步骤如下:

  • 创建一个SonarQube插件

  • 增加相关依赖

  • 创建自定义rules

  • 生成插件的jar包

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

  • 重启SonarQube

添加maven依赖

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <sonar-plugin-api.version>5.6</sonar-plugin-api.version>
<sonar-java-plugin.version>4.2</sonar-java-plugin.version>
<sonar-packaging-maven-plugin.version>1.17</sonar-packaging-maven-plugin.version> <sslr-testing-harness.version>1.20</sslr-testing-harness.version>
<junit.version>4.12</junit.version>
<fest-assert.version>1.4</fest-assert.version>
<logback-classic.version>1.1.3</logback-classic.version> </properties>
<dependencies>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
<version>${sonar-plugin-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.java</groupId>
<artifactId>sonar-java-plugin</artifactId>
<version>${sonar-java-plugin.version}</version>
<type>sonar-plugin</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.java</groupId>
<artifactId>java-checks-testkit</artifactId>
<version>${sonar-java-plugin.version}</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>org.codehaus.sonar.sslr</groupId>
<artifactId>sslr-testing-harness</artifactId>
<version>${sslr-testing-harness.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>${fest-assert.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
<scope>test</scope>
</dependency> <!--http://stackoverflow.com/questions/35369058/custom-plugin-for-sonarqube-5-2-produces-noclassdeffounderror-->
<!-- https://mvnrepository.com/artifact/org.codehaus.sonar.sslr-squid-bridge/sslr-squid-bridge -->
<dependency>
<groupId>org.codehaus.sonar.sslr-squid-bridge</groupId>
<artifactId>sslr-squid-bridge</artifactId>
<version>2.6</version>
<!--记得exclude掉sonar-plugin-api,才可以加载其他相关依赖-->
<exclusions>
<exclusion>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-plugin-api</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<version>${sonar-packaging-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<pluginKey>java-custom</pluginKey>
<pluginName>Java Custom Rules</pluginName>
<!-- your plugin class -->
<pluginClass>com.xixicat.sonar.MySonarPlugin</pluginClass>
<sonarLintSupported>true</sonarLintSupported>
<sonarQubeMinVersion>5.6</sonarQubeMinVersion> <!-- allow to depend on API 6.x but run on LTS -->
</configuration>
</plugin>
</plugins>
</build>

这里的依赖要小心配置,记得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<Class> getChecks() {
return ImmutableList.<Class>builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
} public static List<Class<? extends JavaCheck>> getJavaChecks() {
return ImmutableList.<Class<? extends JavaCheck>>builder()
.add(AvoidSmallerLengthVariableNameRule.class)
.build();
} public static List<Class<? extends JavaCheck>> getJavaTestChecks() {
return ImmutableList.<Class<? extends JavaCheck>>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<? extends JavaCheck>[] 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<? extends JavaCheck>[] 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

查看自定义的规则

doc

sonar自定义规则的更多相关文章

  1. Sonar 平台搭建及 Sonar 自定义规则打包部署篇

    引言 基于阿里开发手册的sonar自定义插件工程 开源地址: https://github.com/tigerge000/sonar-java-custom-rules.git由于最近来问童鞋,就算写 ...

  2. 【转】持续集成 Sonar 平台搭建及 Sonar 自定义规则打包部署篇

    引言 基于阿里开发手册的sonar自定义插件工程 开源地址: https://github.com/tigerge000/sonar-java-custom-rules.git由于最近来问童鞋,就算写 ...

  3. SonarQube 自定义规则开发

    SonarQube 自定义规则开发 满足一些特定需求的时候,需要自己开发代码规则. 环境 和前文的演示环境一致. 步骤 开发步骤见 Writing Custom Java Rules 101,这是官方 ...

  4. SonarQube学习(五)- SonarQube之自定义规则使用

    一.前言 古人云:"欲速则不达",最近真的是深有体会.学习也是如此,不是一件着急的事,越是着急越不会. 就拿SonarQube来说吧,去年年末就想学来着,但是想着想着就搁置了,有时 ...

  5. jQquery.validate自定义规则的使用案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Dotfuscator自定义规则中的元素选择

    Dotfuscator是专业的.NET程序代码保护软件.是支持规则自定义的,你可以对重命名.程序控制流.字符串加密等等功能自定义规则.在进行规则自定义过程中,可以通过元素的不同选择,满足自己的程序需要 ...

  7. js将对象数组按照自定义规则排序

    javascript对一个对象数组进行自定义规则排序,对象中有两个字段. 按照对象中一个字段a的值从小到大规则排序, 效果如下: 排序前: [0]:a=9,b=3 [1]:a=33,b=7 [2]:a ...

  8. .NetCore实践爬虫系统(二)自定义规则

    回顾 上篇文章NetCore实践爬虫系统(一)解析网页内容 我们讲了利用HtmlAgilityPack,输入XPath路径,识别网页节点,获取我们需要的内容.评论中也得到了大家的一些支持与建议.下面继 ...

  9. vee-validate 中文配置报错及自定义规则 报错.updateDictionary/.addlocale is not a function

    原因由于vee-validate版本更新的问题导致的. 1. 原因分析: a 新版vee-validate的语言配置方法变化了, Validator.localize('zh_CN', zh_CN) ...

随机推荐

  1. bzoj4398: 福慧双修

    正边权无向图,一条边两个方向权值不一定相同,求经过点1的最小简单环 简单环包含了点1的一条出边和一条入边,且这两条边不同,因此可以枚举这两条边的编号的二进制表示中哪一位不同,用最短路求此时的最优解,时 ...

  2. vue-router总结2

    在上一篇总结了vue-router中的路由切换.重定向和路由传参等知识,因为篇幅的原因,便将剩下的路由模块化.路由嵌套.history模式.路由守卫等放在这里来写了.因为是继续前面的写.所以代码也还是 ...

  3. Java NIO系列教程(五)Buffer

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.交互图如下: 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被 ...

  4. VS2008--VS2013 各种版本官方下载地址

    很多刚入门的学生都不知道从哪里下载Visual studio 编译器 , 我特闲的纯手工整理了下 Visual Studio 2005 Professional 官方90天试用版 英文版:http:/ ...

  5. win server 2008 R2 支持

    安装Microsoft Visual C++ 2010 可再发行组件包 (x64) vcredist_x64.exe 安装Microsoft .NET Framework 4 dotNetFx40_F ...

  6. [UE4]如何编译部署独立专用服务端(Standalone Dedicated Server)

    这是论坛上对UE服务端功能的回答,意思是UE4提供了网游服务端所具备的特性,包括位移修正.物理碰撞检测.这些特性不是UE4才加入,早期UE版本就有了. https://answers.unrealen ...

  7. 关于把Json数据绑定到select2中

    最近做的一个项目中用到select2,想把Json的数据绑定到select2中,select2默认的能够接受的json格式的数据是以{id:"",text:''}这样的键值对来保存 ...

  8. Git配置SSH Key

    最近看到很多人在配置Git时,遇到很问题,网上教程千篇一律.这儿自己单独记录一份. Git配置SSH Key 1.检查本机是否有ssh key设置,切换到.ssh目录 $ cd ~/.ssh 或cd ...

  9. 转]GSM模块信号强度CSQ与RSSI的对应关系

    使用GSM或者3G模块时,都会接触到信号强度CSQ.通过指令AT+CSQ,模块返回当前的信号质量,例如: AT+CSQ +CSQ: 28,0 其中28就是信号强度CSQ,但它不是真实的CSQ,他应该叫 ...

  10. C#存储过程 传入参数 传出参数 结果集

    作者:卞功鑫 转载请保留:http://www.cnblogs.com/BinBinGo/p/6400928.html //1 连接字符串 string connectionString = &quo ...