LoginSignup
55
39

More than 5 years have passed since last update.

ktlintを使いこなす 【kotlin】【lint】

Last updated at Posted at 2018-03-15

ktlintとは

ktlintはkotlinの静的コード解析ツールです。
同じようなものに、detektというものもあります。
今回は、ktlintについて書いていきます。

ktlintはkotlinのコードにlintをかけるだけでなく、lintで検出した部分にフォーマットをかけることもできます。

使い方

ktlintの導入方法です。

gradleの場合

configurations {
  ktlint
}

dependencies {
  ktlint "com.github.shyiko:ktlint:$KTLINT_VERSION"
}

check.dependsOn ktlint

lintのtaskを追加

task ktlint(type: JavaExec, group: "kotlin verification") {
  description = 'Check Kotlin code style.'
  args 'src/**/*.kt'
  main = 'com.github.shyiko.ktlint.Main'
  classpath = configurations.ktlint + sourceSets.main.output
}

image.png

./gradlew ktlintでlintを走らせることができます。

formatのtaskを追加

task ktFormat(type: JavaExec, group: "kotlin Formatting") {
  description = 'Fix Kotlin code style deviations.'
  args '-F', 'src/**/*.kt'
  main = 'com.github.shyiko.ktlint.Main'
  classpath = configurations.ktlint + sourceSets.main.output
}

image.png

./gradlew ktFormatを使ってlintで検出された箇所にフォーマットをかけることができます。

CLIの場合

brewを使ってインストールできます。

brew install shyiko/ktlint/ktlint
ktlint "src/**/*.kt"

Output形式

ktlintでは様々なoutput形式を用意しています。
--reporterオプションを使ってOutputの形式を指定することができます。

task ktlint(type: JavaExec, dependsOn: classes) {
  description = 'Check Kotlin code style.'
  args 'src/**/*.kt', '--reporter=plain'
  main = 'com.github.shyiko.ktlint.Main'
  classpath = configurations.ktlint + sourceSets.main.output
}

--reporter=plain

デフォルトのアウトプット形式です。

takusemba/ktlint-sample/app/…/Hoge.kt:44:1: Unexpected blank line(s) before "}"

takusemba/ktlint-sample/app/…/Fuga.kt:108:1: Needless blank line(s)

takusemba/ktlint-sample/app/…/Foo.kt:25:7: Line break before assignment is not allowed

takusemba/ktlint-sample/app/…/Bar.kt:47:1: Unexpected blank line(s) before “}"

--reporter=checkstyle

xml形式でアウトプットすることもできます。

<?xml version="1.0" encoding="utf-8"?>
<checkstyle version=“8.0">
    <file name="takusemba/ktlint-sample/app/…/Hoge.kt">
        <error 
            line="25"  
            column="7" 
            severity="error" 
            message="Line break before assignment is not allowed" 
            source="no-line-break-before-assignment" />
    </file></checkstyle>

--reporter=json

json形式でアウトプットすることもできます。

[
    {
        "file": "ktrule/src/main/java/com/takusemba/Hoge.kt",
        "errors": [
            {
                "line": 3,
                "column": 1,
                "message": "Line break before assignment is not allowed",
                "rule": "no-line-break-before-assignment"
            },
            {
                "line": 5,
                "column": 1,
                "message": "Line break before assignment is not allowed",
                "rule": "no-line-break-before-assignment"
            }
        ]
    }
]

--reporter=your-custom-output

カスタムのアウトプット形式で出力することもできます。
まずは、Repoterインターフェースを実装します。

class CustomReporter(private val out: PrintStream) : Reporter {
  private val errors = ArrayList<LintError>()

  override fun onLintError(
      file: String,
      err: LintError,
      corrected: Boolean) {
    errors.add(err)
  }
  override fun afterAll() {
    out.println("hello custom reporter.")
    out.println("found ${errors.size} errors.")
  }
}

次に、ReporterProviderインターフェースを実装したものに、先程のCustomReporterを指定します。

class CustomReporterProvider : ReporterProvider {

  override val id: String = "custom-ktlint-reporter"

  override fun get(
      out: PrintStream, 
      opt: Map<String, String>
  ): Reporter = CustomReporter(out)

}

最後にMETA-INF/services/com.github.shyiko.ktlint.core.RuleSetProviderにReporterProviderを登録します。

META-INF/services/com.github.shyiko.ktlint.core.RuleSetProvider
com.takusemba.CustomRuleSetProvider

最後に、jarを生成して、-Rオプションで指定します。


task sourcesJar(type: Jar, dependsOn: classes) {
  classifier = 'sources'
  from sourceSets.main.allSource
}

task ktlint(type: JavaExec, group: "kotlin verification") {
  description = 'Check Kotlin code style.'
  args 'src/**/*.kt' , '-R', 'path/to/hoge.jar'
  main = 'com.github.shyiko.ktlint.Main'
  classpath = configurations.ktlint + sourceSets.main.output
}

image.png

ルールの除外

Ktlintであるコードに対して特定のルールまたは、全てのルールを適応外にすることができます。

特定のルール(no-wildcard-imports)を除外

import package.* // ktlint-disable no-wildcard-imports

全てのルールを除外

import package.* // ktlint-disable

では、対象とするコード全てに対して特定のルールを除外するにはどうすればよいのでしょうか。
ktlintには、特定のルールを除外する方法はありません。

しかし、作者いわく、このアプローチは意図的らしいです。
理由はこちらを御覧ください。
https://github.com/shyiko/ktlint/issues/21

しかし、ワークアラウンドは用意されています、

ktlintは最初に.editorconfigのスタイル設定を読み込みに行くため、そこに独自のスタイルを明記しておけば、そのスタイルに従ってlintがかけられます。

.editorconfig
[*.{kt,kts}]
indent_size=2
continuation_indent_size=4
insert_final_newline=unset
max_line_length=off

最後に

今回は基本的はktlintの使い方を紹介しました。
Ktlintを使った独自ルールの追加方法については、こちらの記事を書きましたので、見てみてください。
https://qiita.com/takusemba/items/77e882cada7daf6f35ec

55
39
1

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
55
39