>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML GameDev Blockchain Systemy wbudowane Bezpieczeństwo
Kotlin

diKTat zamienia przegląd kodu Kotlin w zautomatyzowaną rutinę

Czy zdarzyło Ci się kiedyś, że jedna trzecia komentarzy do Twojego pull requesta dotyczyła sporów o formatowanie? Ktoś zostawił ujemne boolean jak isNoError, ktoś pomieszał kolejność metod w klasie, a ktoś porównywał liczby zmiennoprzecinkowe używając operatora ==. Technicznie kod się kompiluje i testy przechodzą, ale czytanie takiej bazy kodu sześć miesięcy później staje się fizycznie bolesne.

Zazwyczaj w przypadku Kotlina zespoły stawiają na połączenie ktlint i detekt. Pierwszy pilnuje wcięć i odstępów, drugi wypatruje oczywistych code smells. Ale jest szara strefa między nimi, jeśli chodzi o styl architektoniczny i konwencje, gdzie zespoły albo piszą własne reguły, albo marnują czas na ręczne komentarze. Repozytorium diKTat od zespołu SaveOurTool rozwiązuje dokładnie ten problem.

Czym jest diKTat

Projekt to rygorystyczny zestaw reguł konwencji kodu dla Kotlina. Technicznie diKTat jest zbudowany na bazie ktlint i analizuje AST plików. Repozytorium zawiera obszerne wytyczne podzielone na sekcje: nazewnictwo, komentarze KDoc, struktura klas, funkcje, praca z typami i zmiennymi.

Narzędzie zawiera ponad sto sprawdzeń, z których wiele nie występuje w innych statycznych analizatorach w ogóle. Główną wygodą jest to, że diKTat może nie tylko narzekać do konsoli, ale także automatycznie naprawiać znalezione naruszenia w locie.

Nieoczywiste sprawdzenia, które ratują Twój kod

Większość linterów koncentruje się na formatowaniu. DiKTat kopie głębiej i wyłapuje semantyczne dziwności.

Czystość nazewnictwa i logiki

DiKTat ma wbudowany zakaz podwójnie negatywnych nazw zmiennych. Jeśli zadeklarujesz flagę val isNotValid = false, linter zażąda zmiany jej nazwy na pozytywny odpowiednik. Konstrukcje jak !isNotValid psują mózg podczas czytania, więc ta reguła oszczędza nerwy wszystkim.

Sprawdza również wywołania funkcji z negacją. Zamiast !list.isEmpty(), narzędzie będzie uporczywie sugerować pisanie list.isNotEmpty().

Kolejność członków klasy

Typowym problemem w dużych plikach Kotlina jest bałagan pól, funkcji i obiektów. DiKTat ściśle kontroluje strukturę:

  • Stałe czasu kompilacji
  • Zwykłe właściwości
  • Właściwości z late-init
  • Bloki init (a narzędzie zabrania tworzenia wielu bloków init bez wyraźnej konieczności)
  • Konstruktory
  • Metody publiczne, wewnętrzne, chronione i prywatne
  • Companion object

Jeśli ktoś umieści prywatnego helpera przed publicznym API, build CI nie przejdzie.

Bezpieczeństwo typów i obliczeń

Narzędzie zabrania bezpośredniego porównywania typów Float i Double przez ==. Ze względu na specyfikę binarnej reprezentacji liczb zmiennoprzecinkowych, takie porównania często prowadzą do trudnych do wykrycia błędów. DiKTat zmusi Cię do używania sprawdzania delta przez abs(a - b) > EPS lub przejścia na BigDecimal.

Inne przydatne sprawdzenie śledzi zbędne rzutowania. Jeśli Kotlin już wykonał Smart Cast wewnątrz warunku, wywołanie as Type zostanie oznaczone jako niepotrzebny szum.

// Было
if (x is String) {
    print((x as String).length)
}

// Стало после автофикса
if (x is String) {
    print(x.length)
}

Jak uruchamiać i konfigurować

DiKTat można uruchamiać przez terminal, zintegrować z buildami Gradle lub Maven, lub podłączyć przez agregator Spotless.

Dodawanie do Gradle

Dla projektów używających Gradle z Kotlin DSL, plugin podłącza się w kilku linijkach:

plugins {
    id("com.saveourtool.diktat") version "2.0.0"
}

diktat {
    inputs {
        include("src/**/*.kt")
        exclude("src/test/kotlin/excluded/**")
    }
    reporters {
        plain()
        html {
            output = file("build/reports/diktat.html")
        }
    }
}

Sprawdzenia uruchamiamy poleceniem ./gradlew diktatCheck, a automatyczną naprawę wszystkiego, co analizator może osiągnąć, wykonujemy przez ./gradlew diktatFix.

Drobna konfiguracja reguł

Konfiguracja znajduje się w standardowym pliku YAML diktat-analysis.yml. Każda reguła jest włączana lub wyłączana osobno, a wiele z nich ma specyficzne parametry:

name: HEADER_MISSING_OR_WRONG_COPYRIGHT
  enabled: true
  configuration:
    isCopyrightMandatory: true
    copyrightText: Copyright (c) MyTeam, 2024. All rights reserved.

name: HEADER_NOT_BEFORE_PACKAGE
  enabled: true
  ignoreAnnotated: [Generated, Controller]

Jeśli musisz pominąć konkretne sprawdzenie lokalnie, standardowa adnotacja @Suppress("FUNCTION_NAME_INCORRECT_CASE") lub ogólna @Suppress("diktat") działa bezpośrednio w kodzie.

Stopniowe wdrażanie przez Baseline

Włączenie rygorystycznego lintera na starym projekcie z 50 000 liniami kodu bez przygotowania jest niemożliwe. Developerzy utoną w tysiącach ostrzeżeń.

Do tego diKTat ma tryb baseline. Przy pierwszym uruchomieniu narzędzie generuje plik XML ze wszystkimi bieżącymi problemami w projekcie:

./diktat --baseline=diktat-baseline.xml "src/**/*.kt"

Plik baseline jest commitowany do repozytorium. Po tym linter przestaje narzekać na stary kod i blokuje build tylko wtedy, gdy ktoś wprowadzi nowe naruszenia w świeżym commicie.

Integracja z GitHub Actions

img.png

Narzędzie może wyprowadzać raporty w formacie SARIF. W połączeniu z GitHub Actions błędy i ostrzeżenia stylistyczne są podświetlane bezpośrednio w interfejsie pull requesta z dokładnymi referencjami do linii. Nie trzeba konfigurować zewnętrznych botów do komentarzy.

name: Upload SARIF report
  uses: github/codeql-action/upload-sarif@v1
  if: always()
  with:
    sarif_file: build/reports/diktat/diktat.sarif

Czy warto wypróbować

DiKTat jest bardzo nieprzejednany. Jego wytyczne wymagają jawnego porządku importów, limitują długość funkcji do trzydziestu linii, kontrolują obecność dokumentacji KDoc dla metod publicznych i zabraniają niepotrzebnych var.

W przypadku projektu hobbystycznego z dwoma osobami takie ograniczenia będą wydawać się przesadą. Ale jeśli rozproszony zespół pracuje nad serwisem lub rozwijasz bibliotekę open-source, diKTat usuwa ból synchronizacji stylu i uwalnia czas na code review do dyskusji o architekturze zamiast o białych znakach. Najłatwiejszy sposób na start to dodanie pluginu Gradle w trybie sprawdzania jednego modułu i wygenerowanie baseline.

Powiązane projekty