官網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 結尾;。實現:
AbstractClassNameCheck:
package org.sonar.samples.java.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.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.ClassTree;
/**
* 抽象類命名檢查
* 抽象類命名使用 Abstract 或 Base 開頭
*
* @author cxq
*/
@Rule(key = "AbstractClassNameCheck_java.html")
public class AbstractClassNameCheck extends BaseTreeVisitor implements JavaFileScanner {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractClassNameCheck.class);
private JavaFileScannerContext context;
@Override
public void scanFile(JavaFileScannerContext javaFileScannerContext) {
this.context = javaFileScannerContext;
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目錄下添加目錄:
AbstractClassNameCheck_java.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_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.sonar.samples.java.checks;
import org.junit.Test;
import org.sonar.java.checks.verifier.JavaCheckVerifier;
import org.sonar.samples.java.checks.namerules.AbstractClassNameCheck;
public class AbstractClassNameCheckTest {
@Test
public void test() {
JavaCheckVerifier.verify("src/test/files/AbstractClassNameCheck.java", new AbstractClassNameCheck());
}
}
結構:
此時,我們已完成第一個自定義規則的實現,並將其註冊到自定義插件中。最後剩下的步驟是使用SonarQube平臺直接測試它並嘗試分析項目!
首先使用maven構建項目
目錄:\sonar-custom-rules-examples-master\java-custom-rules> 執行:mvn clean install
打包成功後:
[INFO] Building jar: ***\java-custom-rules\target\java-custom-rules-1.0-SNAPSHOT.jar
講jar包放入
$SONAR_HOME/extensions/plugins
重啓sonarQube
./sonar.sh restart
啓動後SonarQube以管理員身份登錄並導航到“ 代碼規則” 選項卡。
從那裏,在語言部分下,選擇“ Java ”,然後選擇存儲庫部分下的 “ MyCompany Custom Repository ” 。 您的規則現在應該是可見的(包含所有其他示例規則)。
選擇規則並在默認質量配置文件中激活它。
如何配置:
質量配置》java新建配置》my-java
激活更多規則
活動
已經打開成功。測試一次我們自己定義的規則
新建兩個測試類:
sonar-scanner 這裏如果不清楚,請自己學習 scanner檢測代碼,我這裏就直接運行了。
發現新的bug
我們自定義的規則已經實現