sonarqube - 如何确保正确的字节码可用于我的自定义 Sonar 插件规则,这样我就不会得到!未知!对于每种类型?

标签 sonarqube sonarqube-5.4

我一直在尝试为 Sonarqube ~5.4 编写一个自定义规则插件,虽然我已经实现并运行了一些规则,但依赖于标准库之外的类型的规则依赖于各种杂技字符串匹配.

我正在使用 sonar-packaging-maven-plugin 进行打包:

<plugin>
    <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
    <artifactId>sonar-packaging-maven-plugin</artifactId>
    <version>1.16</version>
    <configuration>
        <pluginClass>${project.groupId}.sonar.BravuraRulesPlugin</pluginClass>
        <pluginKey>SonarPluginBravura</pluginKey>
        <skipDependenciesPackaging>false</skipDependenciesPackaging>
        <basePlugin>java</basePlugin>
    </configuration>
    <executions>

        <execution>
            <phase>package</phase>
            <goals>
                <goal>sonar-plugin</goal>
            </goals>
        </execution>

    </executions>
</plugin>

并且正在使用以下帮助程序扩展(kotlin)运行各种检查:

fun <T : JavaFileScanner> T.verify() {

    val workDir = System.getProperty("user.dir");
    val folder = Paths.get(workDir, "src/test/samples", this.javaClass.simpleName);

    Files.list(folder).forEach { sample ->
        try {
            if (sample.toString().endsWith(".clean.java")) {
                JavaCheckVerifier.verifyNoIssue(sample.toString(), this);

            } else {
                JavaCheckVerifier.verify(sample.toString(), this);
            }

        } catch (error: Exception) {
            throw VerificationFailedException(sample, error);
        }
    }

};

class VerificationFailedException(path: Path, error: Exception)
        : Exception("Failed to verify $path.", error);

我为规则创建一个 IssuableSubscriptionVisitor 子类,并访问 Tree.Kind.METHOD_INVOCATION,查找静态 MAX、MIN、ASC 或 DESC sql 生成器的使用方法被传递一个 AutoLongColumn。这是为了停止将标识符字段用于排序目的。

不幸的是,即使我在 Maven“测试”类路径上有必需的库,当我尝试获取任何类型时,它们只是显示为 !unknown!

override fun visitNode(tree: Tree) {

    if (tree !is MethodInvocationTree) {
        return;
    }

    val methodSelect = tree.methodSelect();
    if (methodSelect !is IdentifierTree || methodSelect.name() !in setOf("MAX", "MIN", "ASC", "DESC")) {
        return;
    }

val firstArg = statement.arguments().first();
    if (firstArg !is MethodInvocationTree) {
        return;
    }

    val firstArgSelect = firstArg.methodSelect();
    if (firstArgSelect !is MemberSelectExpressionTree) {
        return;
    }

    if (firstArgSelect.type is UnknownType) {
        throw TableFlipException("(ノಥ益ಥ)ノ ┻━┻");
    }

    // It never gets here.

}

我确信我错过了拼图中的一些重要部分,如果有人能告诉我哪里出了问题,我将不胜感激。

编辑:我正在使用org.sonarsource.java:sonar-java-plugin:3.14作为分析器,虽然我无法发布所有代码对于分析目标(商业IP等),以下是与关键部分结构相同的内容:

import static com.library.UtilClass.MAX;

...

query.SELECT(biggestId = MAX(address._id())) // Noncompliant
        .FROM(address)
        .WHERE(address.user_id().EQ(userId)
                .AND(address.type_id().EQ(typeId)));
...

address.id() 的类型是一个包装了 long 的 com.library.Identifier。我希望能够访问所有方法调用,检查它们是否匹配 com.library.UtilCLass.MAX,如果匹配,请确保第一个参数不是 com.library.Identifier。如果没有类型信息,我必须对 _id 方法引用进行正则表达式匹配,这很容易丢失一些东西。

最佳答案

事实证明,获取可用类型的方法是使用 maven(或您正在使用的任何工具)将所需的 jar 复制到目录中,然后将其转换为文件列表,然后将其传递给测试验证者。

例如,假设我们正在尝试查找 joda-time 的用法:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>

        <execution>
            <id>copy-libs</id>
            <phase>generate-test-resources</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>

                <artifactItems>

                    <artifactItem>
                        <groupId>joda-time</groupId>
                        <artifactId>joda-time</artifactId>
                        <version>2.9.4</version>
                    </artifactItem>

                </artifactItems>

            </configuration>
        </execution>

    <executions>
</plugin>

此执行会将 joda-time jar 放入 target/dependency 目录中。接下来,您确保枚举该目录中的 jar,并将它们添加到您的测试验证中(我们假设您将验证程序命名为“JodaCheck”):

// Not at all necessary, but it makes the code later on a lot easier to read.
fun <T> Stream<T>.toList(): List<T> = this.collect({
    mutableListOf()

}, { list, item ->
    list.add(item)

}, { list, otherList ->
    list.addAll(otherList)

})

...

val workDir = System.getProperty("user.dir")
val sampleFile = Paths.get(workDir, "src/test/samples/JodaSample.java").toString()
val dependencies = Files.list(Paths.get(workDir, "target/dependency"))
        .map { it.toFile() }.toList()

JavaCheckVerifier.verify(sampleFile, JodaChecker(), dependencies)

完成此操作后,通过测试进行调试将显示 joda-time 类在分析过程中可用。

关于sonarqube - 如何确保正确的字节码可用于我的自定义 Sonar 插件规则,这样我就不会得到!未知!对于每种类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39071433/

相关文章:

sonarqube - 如何保护 SonarQube 5.4 的安全?

SonarQube 服务未启动 : StartSonar. bat

java - 不兼容 :org. codehaus.plexus。 .exception.ComponentLookupException

java - 更改此条件,使其不总是计算为 "false"

build - SonarQube 扫描仪因线路超出范围而失败

postgresql - 使用 Postgres DB 引擎的 Docker 容器上的 SonarQube 管理员密码

java.lang.ClassNotFoundException : org. sonar.java.model.JavaTree "dependency issue creating a sonar plugin"

java - SonarQube - 显示考虑多个项目的代码覆盖率