1. 程式人生 > >Sonar Java 規則插件開發 (基於阿裏開發手冊)

Sonar Java 規則插件開發 (基於阿裏開發手冊)

efault debug 靜態 ons status ever target ant cost

引言

最近在做Sonar靜態代碼掃描管理,以此順手接了Sonar的插件開發,基於阿裏開發手冊進行開發,在整體開發過程中,其中還是遇到不少坑位,也以此給大家做相應借鑒
官網Demo演示插件開發地址:
https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101
基於官網的我暫時不多說,基礎框架按照官網的範例進行搭建即可

#開源地址:
https://github.com/tigerge000/sonar-java-custom-rules.git

sonar常用方法說明

範例

需求:【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類 命名以它要測試的類的名稱開始,以 Test 結尾。

實現:
AbstractClassNameCheck

package org.finger.java.rule.checks.namerules;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.*;

/**
* 抽象類命名檢查
* 抽象類命名使用 Abstract 或 Base 開頭
* Created by 古月隨筆 on 2017/3/17.
*/
@Rule(key = "AbstractClassNameCheck")
public class AbstractClassNameCheck extends BaseTreeVisitor implements JavaFileScanner{

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractClassNameCheck.class);

private JavaFileScannerContext context;

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

@Override
public void visitClass(ClassTree tree) {
String className = tree.simpleName().name();

LOGGER.info(className + "<<>>" + tree.symbol().isAbstract());


if(tree.symbol().isAbstract()){
//判斷名稱是否以Abstract 或 Base 開頭

String abName = "Abstract";
String bsName = "Base";
//判斷類名如果小於Abstract 或 Base
if (className.length() < abName.length() || className.length() < bsName.length()) {
context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");
} else {
//判斷是否存在 Abstract 或 Base
if (!className.contains(abName)) {
if (!className.contains(bsName)) {
context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");
} else {
if (className.indexOf(bsName) != 0) {
context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");
}
}
} else {
if (className.indexOf(abName) != 0) {
context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");
}
}
}
}
super.visitClass(tree);
}

}

resources目錄下添加目錄:org.sonar.l10n.java.rules.squid(這命名主要是由於sonar源碼中固定寫死的)
AbstractClassNameCheck.html

<p>AbstractClassNameCheck Check</p>
<h2>Noncompliant Code Example</h2>
<pre>
public abstract class HiClass {// Noncompliant
}

public abstract class MyNameIsAbstract {// Noncompliant
}
</pre>
<h2>Compliant Solution</h2>
<pre>
public abstract class AbstractMysql {
}

public abstract class BaseMysql {
}
</pre>

AbstractClassNameCheck.json

{
"title": "The Name Of Abstract Class should use Abstract or Base first",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"bug",
"pitfall"
],
"defaultSeverity": "CRITICAL"
}

AbstractClassNameCheck_java.json(為什麽有這個文件,主要是由於進行單測的時候,sonar源碼內容寫死是xxxx_java.json命名)

{
"title": "The Name Of Abstract Class should use Abstract or Base first",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"bug",
"pitfall"
],
"defaultSeverity": "CRITICAL"
}

單測:
AbstractClassNameCheckTest

package org.finger.java.rule.checks.namerules;

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

/**
* Created by huqingen on 2017/3/17.
*/
public class AbstractClassNameCheckTest {
@Test
public void test() {
JavaCheckVerifier.verify("src/test/files/HiClass.java", new AbstractClassNameCheck());
}

@Test
public void test1() {
JavaCheckVerifier.verify("src/test/files/MyNameIsAbstract.java", new AbstractClassNameCheck());
}

@Test
public void test2() {
JavaCheckVerifier.verify("src/test/files/BaseMysql.java", new AbstractClassNameCheck());
}
@Test
public void test3() {
JavaCheckVerifier.verify("src/test/files/AbstractMysql.java", new AbstractClassNameCheck());
}
}

開發目錄結構:

技術分享圖片

PS:
1.編寫sonar規則的時候,給個建議,采用Debug方式調試整個tree裏面的內容,針對性的編寫自己想要的規則,sonar在這塊掃描基礎方法做的還是很棒的

Sonar Java 規則插件開發 (基於阿裏開發手冊)