2016-08-22 7 views
2

Я пытаюсь написать плагин пользовательских правил для 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> 

И бегаю различные проверки с помощью расширения следующего вспомогательного (Котлин):

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', когда я пытаюсь получить любой из этих типов, они просто отображаются как !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. 

} 

Я уверен, что не хватает какой-то жизненно важную часть головоломки, и я был бы признателен, если кто-то может сказать мне, где я буду неправильно.

EDIT: Я использую 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, которые подвержены потенциально отсутствующим вещам.

+0

Не могли бы вы поделиться анализируемым кодом? Там может быть что-то скрытое. – benzonico

+1

вы также можете уточнить, какую версию анализатора сонара java вы используете. – benzonico

+0

Я добавил обновление к вопросу. – tzrlk

ответ

2

Итак, выясняется, что способ получения доступных типов - использовать maven (или любой другой инструмент, который вы используете), чтобы скопировать необходимые банки в каталог, затем перевести лот в список файлов и передать это к верификатору теста.

Например, позволяет делать вид, что мы пытаемся найти обычаи Joda времени:

<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 время банки в каталог target/dependency. Далее, вы убедитесь, что перечислить банки в этом каталоге, и добавить их к тестовой проверке (мы предполагаем, что вы назвали ваш верификатор «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) 

После того, как вы сделали это, отладку через тесты покажут, что во время анализа доступны классы йода-времени.

+0

Следует отметить следующее: для этого есть веская причина: вы можете не захотеть добавить зависимость от своего проекта (даже в тестах из-за возможных конфликтов версий класса), потому что типы, которые вы хотите тестировать, могут не быть частью вашего (например, тестирование JPA и т. д.), – benzonico