5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kotlin - コードフォーマットにktlintを導入する

Last updated at Posted at 2022-05-07

ktlintとは

ktlint - GitHub

Kotlinのリンターで、フォーマッターも内蔵している

モチベーション

開発チームでコードスタイルを統一する

便利に感じた点

  • 設定ファイルを作成することなく公式コードスタイルを適応できる
  • Gradleプラグインを公開している
  • CIと統合できる

Hands-on

動作環境

  • windows 10
  • Spring Boot 2.6.7
  • Kotlin

spring initializrでGradleプロジェクトを作成

spring initializrでGradleプロジェクトを作成する
設定済みのリンク

ktlintのGradleプラグインを追加

統合開発環境で開きbuild.gradle.ktsにJLLeitschuh/ktlint-gradleを追加する

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
	id("org.springframework.boot") version "2.6.7"
	id("io.spring.dependency-management") version "1.0.11.RELEASE"
+	id("org.jlleitschuh.gradle.ktlint") version "10.3.0"
	kotlin("jvm") version "1.6.21"
	kotlin("plugin.spring") version "1.6.21"
}

コードスタイルの検証

> gradlew ktlintCheck

or

> gradlew check

検証に失敗しているときコンソールに出力される

C:\Users\Umizoko\Downloads\demo\demo>gradlew ktlintCheck

> Task :ktlintKotlinScriptCheck FAILED
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:4:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:5:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:6:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:7:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:8:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:16:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:20:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:21:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:22:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:23:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:27:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:28:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:29:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:30:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\build.gradle.kts:34:1 Unexpected tab character(s)

> Task :ktlintMainSourceSetCheck FAILED
C:\Users\Umizoko\Downloads\demo\demo\src\main\kotlin\com\example\demo\DemoApplication.kt:10:1 Unexpected tab character(s)

> Task :ktlintTestSourceSetCheck FAILED
C:\Users\Umizoko\Downloads\demo\demo\src\test\kotlin\com\example\demo\DemoApplicationTests.kt:9:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\src\test\kotlin\com\example\demo\DemoApplicationTests.kt:10:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\src\test\kotlin\com\example\demo\DemoApplicationTests.kt:11:1 Unexpected tab character(s)
C:\Users\Umizoko\Downloads\demo\demo\src\test\kotlin\com\example\demo\DemoApplicationTests.kt:12:1 Unexpected blank line(s) before "}"

FAILURE: Build completed with 3 failures.

...

BUILD FAILED in 1s
7 actionable tasks: 3 executed, 4 up-to-date

違反したコードを自動フォーマットする

> gradlew ktlintCheck

BUILD SUCCESSFUL in 5s
7 actionable tasks: 6 executed, 1 up-to-date

GitHub Actionsのワークフローでコードスタイルを検証し、違反がある場合は落とす

Gradle Build Actionを利用してワークフローを設定する

.github/workflows/check_workflow.yaml
name: Run Gradle on PRs
on: pull_request
jobs:
  gradle:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2

      - name: Change Permission
        run: chmod +x ./gradlew

      - name: Execute Gradle check
        run: ./gradlew check

違反したコードでPRを出してワークフローのチェックが落ちるか確認する

> git branch illegal-code-style
> git switch illegal-code-style

コードスタイルを違反したファイルを追加

package com.example.demo.domain.article

class Article private constructor(
    val id: String,
    var title: String,
    val description: String
        ){

    fun changeTitle(title: String) {
        this.title = title
    }
}
> git push --set-upstream origin illegal-code-style

GitHubからmasterブランチに対してPRを作成する

GitHubのワークフローがktlintの違反で落ちていることを確認

Run ./gradlew check
Downloading https://services.gradle.org/distributions/gradle-7.4.1-bin.zip
...........10%...........20%...........30%...........40%...........50%...........60%...........70%...........80%...........90%...........100%

Welcome to Gradle 7.4.1!

...

> Task :ktlintMainSourceSetCheck FAILED
/home/runner/work/learn-ktlint/learn-ktlint/src/main/kotlin/com/example/demo/domain/article/Article.kt:1:1 File must end with a newline (\n)
/home/runner/work/learn-ktlint/learn-ktlint/src/main/kotlin/com/example/demo/domain/article/Article.kt:7:1 Unexpected indentation (8) (should be 0)
/home/runner/work/learn-ktlint/learn-ktlint/src/main/kotlin/com/example/demo/domain/article/Article.kt:7:9 Unexpected indentation (expected 0, actual 8)
/home/runner/work/learn-ktlint/learn-ktlint/src/main/kotlin/com/example/demo/domain/article/Article.kt:7:10 Missing spacing before "{"

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ktlintMainSourceSetCheck'.
> A failure occurred while executing org.jlleitschuh.gradle.ktlint.worker.ConsoleReportWorkAction

   > KtLint found code style violations. Please see the following reports:
> Task :compileKotlin
6 actionable tasks: 6 executed
     - /home/runner/work/learn-ktlint/learn-ktlint/build/reports/ktlint/ktlintMainSourceSetCheck/ktlintMainSourceSetCheck.txt

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1m 15s
Error: Process completed with exit code 1.

自動フォーマットを実行してリモートリポジトリを更新すると、ワークフローがパスする

Run ./gradlew check
To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.4.1/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build 
> Task :loadKtlintReporters
> Task :runKtlintCheckOverKotlinScripts
> Task :ktlintKotlinScriptCheck
> Task :runKtlintCheckOverMainSourceSet
> Task :ktlintMainSourceSetCheck
> Task :runKtlintCheckOverTestSourceSet
> Task :ktlintTestSourceSetCheck
> Task :processResources
> Task :processTestResources NO-SOURCE
> Task :compileKotlin
> Task :compileJava NO-SOURCE
> Task :classes
> Task :compileTestKotlin
> Task :compileTestJava NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test
> Task :check

BUILD SUCCESSFUL in 27s
11 actionable tasks: 11 executed

まとめ

ktlintをwrapperしたプラグインを導入することで、ローカルで自動フォーマットを実行することができ、GitHub ActionsでPRをトリガーにリンターでの検証を行うことで、プロジェクトのコードスタイルを統一することができた。

使用したリポジトリ: https://github.com/Umizoko/learn-ktlint

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?