>_ DevTrendsit

Lingua

Home

Linguaggi

Sezioni

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Sicurezza
Kotlin

diKTat Trasforma la Code Review Kotlin in una Routine Automatizzata

Ti è mai capitato di avere un terzo dei commenti nella tua pull request dedicato a dispute sulla formattazione? Qualcuno ha lasciato un booleano negativo come isNoError, qualcuno ha mischiato l'ordine dei metodi in una classe, e qualcuno ha confrontato numeri in virgola mobile usando l'operatore ==. Tecnicamente il codice compila e i test passano, ma leggere una codebase del genere sei mesi dopo diventa fisicamente doloroso.

Di solito per Kotlin, i team usano la combinazione ktlint e detekt. Il primo controlla indentazione e spaziatura, il secondo cerca code smells evidenti. Ma c'è un'area grigia tra loro per quanto riguarda lo stile architetturale e le convenzioni, dove i team o scrivono le proprie regole o perdono tempo con commenti manuali. Il repository diKTat del team SaveOurTool risolve esattamente questo problema.

Cos'è diKTat

Il progetto è un set rigoroso di regole per le convenzioni di codice Kotlin. Tecnicamente, diKTat è costruito sopra ktlint e analizza l'AST dei file. Il repository contiene una linea guida estesa organizzata in sezioni: naming, commenti KDoc, struttura delle classi, funzioni, lavoro con tipi e variabili.

Lo strumento include oltre cento controlli, molti dei quali non si trovano in altri analizzatori statici. La principale comodità è che diKTat non può solo lamentarsi sulla console, ma anche correggere automaticamente le violazioni al volo.

Controlli Non Evidenti Che Salvano Il Tuo Codice

La maggior parte dei linter si concentra sulla formattazione. diKTat scava più a fondo e cattura stranezze semantiche.

Pulizia di Naming e Logica

diKTat ha un divieto integrato sui nomi di variabili a doppia negazione. Se dichiari un flag val isNotValid = false, il linter richiederà di rinominarlo in un equivalente positivo. Costrutti come !isNotValid ti fanno impazzire quando leggi, quindi questa regola salva i nervi di tutti.

Controlla anche le chiamate di funzione con negazione. Invece di !list.isEmpty(), lo strumento suggerirà insistentemente di scrivere list.isNotEmpty().

Ordine dei Membri della Classe

Un problema comune nei file Kotlin grandi è il disastro di campi, funzioni e oggetti. diKTat controlla rigorosamente la struttura:

  • Costanti a tempo di compilazione
  • Proprietà regolari
  • Proprietà late-init
  • Blocchi init (e lo strumento vieta di creare più blocchi init senza necessità esplicita)
  • Costruttori
  • Metodi public, internal, protected e private
  • Companion object

Se qualcuno mette un helper private prima dell'API pubblica, il build CI fallirà.

Sicurezza dei Tipi e del Calcolo

Lo strumento vieta il confronto diretto di tipi Float e Double tramite ==. A causa delle particolarità della rappresentazione binaria dei numeri in virgola mobile, questi confronti portano spesso a bug difficili da catturare. diKTat ti costringerà a usare il controllo con delta tramite abs(a - b) > EPS o a passare a BigDecimal.

Un altro bel controllo traccia i cast ridondanti. Se Kotlin ha già eseguito uno Smart Cast dentro una condizione, chiamare as Type sarà marcato come rumore inutile.

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

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

Come Eseguire e Configurare

diKTat può essere eseguito tramite terminale, integrato in build Gradle o Maven, o collegato attraverso l'aggregatore Spotless.

Aggiungere a Gradle

Per progetti che usano Gradle con Kotlin DSL, il plugin si collega in un paio di righe:

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")
        }
    }
}

I controlli vengono eseguiti con il comando ./gradlew diktatCheck, e la auto-correzione di tutto ciò che l'analizzatore può raggiungere viene fatta tramite ./gradlew diktatFix.

Configurazione Fine delle Regole

La configurazione risiede in un file YAML standard diktat-analysis.yml. Ogni regola è abilitata o disabilitata separatamente, e molte hanno parametri specifici:

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]

Se hai bisogno di sopprimere un controllo specifico localmente, l'annotazione standard @Suppress("FUNCTION_NAME_INCORRECT_CASE") o un generale @Suppress("diktat") funziona direttamente nel codice.

Adozione Graduale Tramite Baseline

Abilitare un linter rigoroso su un progetto vecchio con 50.000 righe di codice senza preparazione è impossibile. Gli sviluppatori annegherebbero in migliaia di avvisi.

Per questo, diKTat ha una modalità baseline. Alla prima esecuzione, l'utility genera un file XML con tutti i problemi attuali nel progetto:

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

Il file baseline viene committato nel repository. Dopo di che, il linter smette di lamentarsi del codice vecchio e blocca il build solo se qualcuno introduce nuove violazioni in un commit fresco.

Integrazione con GitHub Actions

img.png

Lo strumento può emettere report in formato SARIF. Combinato con GitHub Actions, gli errori e gli avvisi di stile vengono evidenziati direttamente nell'interfaccia della pull request con riferimenti esatti alla riga. Non c'è bisogno di configurare bot di terze parti per i commenti.

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

Vale la Pena Provare

diKTat è molto intransigente. La sua linea guida richiede ordinamento esplicito degli import, limita la lunghezza delle funzioni a trenta righe, controlla la presenza della documentazione KDoc per i metodi pubblici e vieta var non necessari.

Per un progetto personale con due persone, queste restrizioni sembreranno eccessive. Ma se un team distribuito lavora su un servizio o stai sviluppando una libreria open-source, diKTat rimuove il mal di testa della sincronizzazione dello stile e libera tempo nella code review per discutere architettura invece di spazi bianchi. Il modo più semplice per iniziare è aggiungere il plugin Gradle in modalità single-module check e generare un baseline.

Progetti correlati