Пора полюбить статические анализаторы! Встречайте Detekt на Kotlin


Если Вы уже знаете о чем пойдет речь и Вас интересут только внедрение в проект, переходите сразу к пункту установки.

Что-же это такое?


image

Анализ программного обеспечения, производимый (в отличие от динамического анализа) без реального выполнения исследуемых программ. Википедия

А своими словами — это удобный инструмент, помогающий в соблюдении правил хорошего кода. Позволяющий очень гибко настраивать фильры по определению плохого кода. Который при каждом запуске сформирует некий отчет, включающий статистические данные об обнаруженных конфликтах, информацию о них, позволяющую определить где произошел конфликт и его тип.

Статические анализаторы облегчают работу ревьюера и в целом экономит время команды на разработку.

Допустим, у нас есть хороший PR, однако автор дал слишком длинные имена переменным, написал код, который можно легко упростить или нарушил одно из множества устанавливаемых правил в конфигурационном файле Detekt, правила не сложные, но code-review такой PR не пройдет.
Автору же придется опять переключаться между проектами, так-же и ревьюерам, уверен, мало удовольствия доставит повторное ревью.
Автоматизируйте, если это быстро и не дорого. (С) Здравый смысл

Какие бывают статические анализаторы?


Для java:


Для Kotlin:


Отвечаю на возникший у Вас в голове вопрос, Spot-bugs на Kotlin не работает.

Внедряем Detekt в проект


Detekt можно установить несколькими способами:

  1. Plugin для AndroidStudio
  2. Gradle

Я считаю настройка через Gradle является более гибкой и рассказываю именно про нее.

На официальном сайте есть несколько способов установки Detekt в проет, в зависимости от версии Gradle, того, является ли он Android проектом. Но, по моему опыту внедрения в android проект, некоторые инструкции не работают. На данный момент проект очень близок к выходу 1.0. Последняя версия на момент написания статьи — release candidate 1.0.0-RC14

Итак.

Заходим на официальный сайт Gradle и видим инструкцию к установке.

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
 }
     dependencies {
         classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.0.0-RC14"
     }
}


Именно этого решения я и советую придерживаться для проекта Android.

Вы наверняка заметили, что я убрал строку apply: plugin, так как я советую отделить Detekt в отдельный файл и уже в нем применить apply.

Этап 1:


Итак, копируем этот код в build.gradle уровня приложения.

Там-же в блоке allprojects мы должны написать строку применения нашего файла содержащего настройки detekt.

allprojects {
    apply from: "$rootDir/detekt.gradle"
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
}

Этап 2:


Затем необходимо создать файл detekt.gradle

apply plugin: "io.gitlab.arturbosch.detekt"

detekt {
    toolVersion = "1.0.0-RC14"                              // Version of the Detekt CLI that will be used. When unspecified the latest detekt version found will be used. Override to stay on the same version.
    input = files("src/main/java")                          // The directories where detekt looks for input files. Defaults to `files("src/main/java", "src/main/kotlin")`.
    parallel = true                                         // Builds the AST in parallel. Rules are always executed in parallel. Can lead to speedups in larger projects. `false` by default.
    filters = ".*build.*,.*/resources/.*,.*/tmp/.*"         // Regular expression of paths that should be excluded separated by `;` or `,`.
    config = files("$rootDir/detekt-config.yml")            // Define the detekt configuration(s) you want to use. Defaults to the default detekt configuration.
    reports {
        xml {
            enabled = true                                  // Enable/Disable XML report (default: true)
            destination = file("build/reports/detekt.xml")  // Path where XML report will be stored (default: `build/reports/detekt/detekt.xml`)
        }
        html {
            enabled = true                                  // Enable/Disable HTML report (default: true)
            destination = file("build/reports/detekt.html") // Path where HTML report will be stored (default: `build/reports/detekt/detekt.html`)
        }
    }
}

Этап 3:


Теперь необходимо создать конфигурационный файл detekt-config.yml

Это стандартный конфигурационный файл с официального сайта.

Этап 4:


Откройте консоль и выполните команду: gradlew detekt

Все!


Теперь у Вас готовы статистические данные по вашему проекту. Они отображаются в консоли, а так-же Вы можете найти их по пути: {u_project}\app\build\reports\detekt

В заключение


Очень удобно использовать Detekt при сборке в Jenkins
Время исполнения задачи в проете с более чем 2000 классов составляет 4-7 секунд*.

Хочу сказать, что использование статического анализатора немного упрощает нашу работу. Ускоряет процесс разработки и экономит деньги бизнеса.

Ссылки:

Detekt github
Set up Detekt
default-detekt-config.yml

Комментарии (3)


  1. rjhdby
    04.03.2019 10:48

    Из статьи непонятно, чем он лучше Ktlint, например (или что там используется в Idea по кнопке «Inspect code»)?
    По удобству использования он явно уступает встроенным средствам — значит у него должны быть весомые достоинства — было бы очень неплохо их описать.


    1. Evleaps Автор
      04.03.2019 17:30
      +1

      Спасибо за комментарий, в idea по умолчанию используется Lint. Очень мощный инструмент, однако он медленнее Detekt. Именно в этом его главный проигрыш. Так же Detekt написан специально для kotlin, а значит можно рассчитывать на более качественный анализ, в теории.

      Цель статьи познакомить с Detekt, возможно, в будущем я напишу статью именно конкурентных отличий статических анализаторов на Kotlin.


  1. igormich88
    04.03.2019 13:30

    Хотелось бы уточнить это в первую очередь статический анализатор или анализатор стилистики кода(переносы, длина имён)?