
В моей предыдущей статье о настройке detekt и danger/kotlin я упоминал отличный плагин danger AckeeCZ/danger-kotlin-detekt для парсинга и отчетности результатов работы detekt.
Хотя он отлично справлялся со своей задачей для нас (большое спасибо ребятам), я чувствовал, что нам нужно больше возможностей для настройки того, что и как мы хотим сообщать на основе распарсенных результатов. Я рад представить вам плагин pavelkorolevxyz/danger-detekt-kotlin. Он сильно вдохновлен плагином от Ackee, но я оставил больше места для экспериментов.
Как это выглядит
Зависит от вас. Мы ограничены только внешним видом файлов и строк в danger/kotlin и возможностями markdown хостинга репозитория (например, GitHub). Все остальное настраивается.
Вот так

С инлайн комментариями

Или вот так

Использование
Я предполагаю, что вы уже знакомы с настройкой danger-kotlin. Если нет, вы можете найти больше информации в официальной документации или моей предыдущей статье.
Dangerfile.df.kts - это основной конфигурационный файл любой настройки danger/kotlin. Чтобы использовать этот плагин, вы должны добавить его как зависимость в начале этого файла и вызвать register.
@file:DependsOn("xyz.pavelkorolev.danger.detekt:plugin:x.y.z")
register.plugin(DetektPlugin)
Сам плагин - это fat jar, опубликованный в mavenCentral, так что больше ничего делать не нужно.
Базовое использование
В основном, это то, что плагин от Ackee имел в качестве единственной опции.
Парсинг и отчет одного файла
Это делает то, что говорит. Если у вас есть один отчет detekt и вы не хотите никакой настройки - это, вероятно, ваш выбор.
DetektPlugin.parseAndReport(reportFile)
Парсинг и отчет нескольких файлов
На самом деле параметры всех функций parse - это varargs, так что вы можете передать столько файлов отчетов, сколько хотите.
DetektPlugin.parseAndReport(reportFile1, reportFile2, reportFile3)
или
val files: Array<File> = findReportFilesByYourself()
DetektPlugin.parseAndReport(*files)
Давайте рассмотрим parse и report по отдельности.
Parse
Это что-то новое. Вы также можете парсить файлы без немедленной отчетности.
val report: DetektReport = DetektPlugin.parse(files)
Этот DetektReport содержит все из распарсенных отчетов detekt, так что это может быть полезно, если вы хотите что-то проверить перед фактической отчетностью.
Report
Вы также можете сделать отчет вот так
DetektPlugin.report(report)
Обратите внимание, чтобы danger правильно сообщал о файлах, вы должны настроить detekt на возврат путей относительно рабочей директории.
detekt {
basePath = rootDir.absolutePath
// Другая конфигурация
}
Полный пример
@file:DependsOn("xyz.pavelkorolev.danger.detekt:plugin:x.y.z")
import systems.danger.kotlin.*
import systems.danger.kotlin.models.github.*
import xyz.pavelkorolev.danger.detekt.DetektPlugin
import java.io.File
register.plugin(DetektPlugin)
danger(args) {
warnDetekt()
}
fun warnDetekt() {
val file = File("build/reports/detekt/report.xml")
if (!file.exists()) {
warn(
"🙈 Отчет detekt не найден",
)
return
}
with(DetektPlugin) {
val report = parse(file)
val count = report.count
if (count == 0) {
message("👏👏👏 Отличная работа! Detekt не нашел нарушений!")
return
}
fail(
"🙁 Найдены нарушения Detekt: **${report.count}**.\n" +
"Пожалуйста, исправьте их, чтобы продолжить. У нас политика нулевой терпимости к предупреждениям"
)
report(report)
}
}
Похожий Dangerfile можно найти в основной ветке репозитория pavelkorolevxyz/detekt-danger-sample-android, который я использовал в предыдущей статье для демонстрации полной настройки danger-kotlin + detekt.
Кастомизация
Функции DetektPlugin.report и DetektPlugin.parseAndReport имеют параметр reporter: DetektErrorReporter, который на самом деле является функциональным интерфейсом с функцией report(error: DetektError, fileName: String?).
Реализуя это, вы можете настроить логику отчетности и внешний вид, как хотите.
По умолчанию есть DefaultDetektErrorReporter, который имеет свой собственный способ создания сообщений и учитывает серьезность нарушений.
DefaultDetektErrorReporter использует инлайн комментарии, если для ошибки указаны файл и строка. Если вы хотите использовать только глобальный отчет без инлайн комментариев, используйте DefaultDetektErrorReporter(context, isInlineEnabled = false).
Реализация
Допустим, вы хотите отправить все найденное в таблицу fail с эмодзи в конце. Напишите это так.
class FailReporter(private val context: DangerContext): DetektErrorReporter {
override fun report(error: DetektError, fileName: String?) {
val message = error.message ?: return
context.fail("$message 💥💥💥")
}
}
И используйте это так
DetektPlugin.report(report, reporter = FailReporter(context))
Или вы можете реализовать то же самое как инлайн reporter благодаря его природе функционального интерфейса, вот так.
plugin.report(report) { error, _ ->
error.message?.let(context::fail)
}
Думаю, вы поняли идею.
Идеи
Я попытаюсь дать вам несколько идей о том, как использовать возможности настройки этого плагина.
- Вы можете отправить предупреждение, если вообще нет отчетов detekt. Может быть, что-то пошло не так, и detekt даже не запустился для этой сборки.
- Вы можете проверить количество нарушений перед отчетностью. Если ничего не найдено, скажите автору PR "Хорошая работа". Будьте благодарны за такие моменты, цените работу ваших коллег.
- Вы можете проверить количество нарушений, чтобы НЕ отправлять огромные комментарии в PR. Например, GitHub имеет ограничение на размер комментария. Если нарушений много, Danger не сможет их отправить. Установите разумный лимит и выведите какое-нибудь общее сообщение вместо этого.
- Вы даже можете проверить, есть ли нарушения в чьем-то модуле или директории, чтобы автоматически упомянуть их.
- Добавьте кучу эмодзи. Все их любят. Шучу 😁. Или нет 🤔.
Заключение
Вот и все. Не стесняйтесь связаться со мной в репозитории GitHub или любым другим способом. Я с нетерпением жду, когда вы поделитесь своими идеями или вариантами использования.