zoukankan      html  css  js  c++  java
  • sonar自定义规则

    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

  • 相关阅读:
    javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
    windows查看端口占用 windows端口占用 查找端口占用程序 强制结束端口占用 查看某个端口被占用的解决方法 如何查看Windows下端口占用情况
    javaWeb项目中的路径格式 请求url地址 客户端路径 服务端路径 url-pattern 路径 获取资源路径 地址 url
    ServletRequest HttpServletRequest 请求方法 获取请求参数 请求转发 请求包含 请求转发与重定向区别 获取请求头字段
    HttpServletResponse ServletResponse 返回响应 设置响应头设置响应正文体 重定向 常用方法 如何重定向 响应编码 响应乱码
    Servlet主要相关类核心类 容器调用的过程浅析 servlet解读 怎么调用 Servlet是什么 工作机制
    linq查询语句转mongodb
    winddows rabbitmq安装与配置
    Redis For Windows安装及密码
    出现,视图必须派生自 WebViewPage 或 WebViewPage错误解决方法
  • 原文地址:https://www.cnblogs.com/xiang--liu/p/9710101.html
Copyright © 2011-2022 走看看