Как я могу гарантировать, что правильный байт-код доступен для моего пользовательского правила плагина сонара, так что я не получаю! Unknown! для каждого типа?
Я пытался написать собственный плагин правил для 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 'test' classpath, когда я пытаюсь получить любой из типов, они просто показывают как !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()
является com.library.Identifier
это оборачивается долго. Я хотел бы иметь возможность посетить все вызовы методов, проверить, соответствуют ли они com.library.UtilCLass.MAX
и, если это так, убедитесь, что первый параметр не com.library.Identifier
, Без информации о типе, я должен сделать регулярное выражение на _id
ссылки на методы, которые подвержены потенциально отсутствующим вещам.
1 ответ
Итак, получается, что способ получить доступные типы - использовать 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>
Это выполнение поместит флягу времени йода в 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 доступны во время анализа.