Kotlin > ktlintを設定する


## plugin


ktlintプラグインを使っている場合には、バージョンを合わせること

![スクリーンショット 2021-08-08 20.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/ded685a4-41ce-9504-ffa9-dde836457109.png "スクリーンショット 2021-08-08 20.11.18.png")



## gradleの設定

今回はプラグインに合わせて、0.42.0を入れます。

※[公式ページ](https://github.com/pinterest/ktlint#with-a-plugin---recommended)ではプラグインでの使用をお勧めされてますが、
今回はktlintのバージョンを明示的に指定したかったので↓の方法をとっています。


### build.gradleの場合

[pinterest/ktlint: An anti\-bikeshedding Kotlin linter with built\-in formatter](https://github.com/pinterest/ktlint#without-a-plugin)


build.gradle

```groovy:build.gradle
// kotlin-gradle-plugin must be applied for configuration below to work
// (see https://kotlinlang.org/docs/reference/using-gradle.html)

apply plugin: 'java'

repositories {
    mavenCentral()
}

configurations {
    ktlint
}

dependencies {
    ktlint("com.pinterest:ktlint:0.42.0") {
        attributes {
            attribute(Bundling.BUNDLING_ATTRIBUTE, getObjects().named(Bundling, Bundling.EXTERNAL))
        }
    }
    // additional 3rd party ruleset(s) can be specified here
    // just add them to the classpath (e.g. ktlint 'groupId:artifactId:version') and 
    // ktlint will pick them up
}

task ktlint(type: JavaExec, group: "verification") {
    description = "Check Kotlin code style."
    classpath = configurations.ktlint
    main = "com.pinterest.ktlint.Main"
    args "src/**/*.kt"
    // to generate report in checkstyle format prepend following args:
    // "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml"
    // to add a baseline to check against prepend following args:
    // "--baseline=ktlint-baseline.xml"
    // see https://github.com/pinterest/ktlint#usage for more
}
check.dependsOn ktlint

task ktlintFormat(type: JavaExec, group: "formatting") {
    description = "Fix Kotlin code style deviations."
    classpath = configurations.ktlint
    main = "com.pinterest.ktlint.Main"
    args "-F", "src/**/*.kt"
}
```


### build.gradle.ktsの場合


build.gradle.kts


[公式ページのREADME](https://github.com/pinterest/ktlint#without-a-plugin-for-gradle-kotlin-dsl-buildgradlekts)を編集しています。変更点は以下です。

- group = "ktlint"を追加していることです。
- worningが出るので、`@Suppress("UNUSED_VARIABLE")` を追加
- mainがdeprecatedになっているので、mainClass.setに変更
[JavaExec setMain is deprecated · Issue \#1184 · pinterest/ktlint](https://github.com/pinterest/ktlint/issues/1184)



```kotlin:build.gradle.kts
val ktlint by configurations.creating

dependencies {
    ktlint("com.pinterest:ktlint:0.42.0") {
        attributes {
            attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
        }
    }
    // ktlint(project(":custom-ktlint-ruleset")) // in case of custom ruleset
}

val outputDir = "${project.buildDir}/reports/ktlint/"
val inputFiles = project.fileTree(mapOf("dir" to "src", "include" to "**/*.kt"))

@Suppress("UNUSED_VARIABLE")
val ktlintCheck by tasks.creating(JavaExec::class) {
    inputs.files(inputFiles)
    outputs.dir(outputDir)

    group = "ktlint"
    description = "Check Kotlin code style."
    classpath = ktlint
    mainClass.set("com.pinterest.ktlint.Main")
    args = listOf("src/**/*.kt")
}

@Suppress("UNUSED_VARIABLE")
val ktlintFormat by tasks.creating(JavaExec::class) {
    inputs.files(inputFiles)
    outputs.dir(outputDir)

    group = "ktlint"
    description = "Fix Kotlin code style deviations."
    classpath = ktlint
    mainClass.set("com.pinterest.ktlint.Main")
    args = listOf("-F", "src/**/*.kt")
}

```

build.gradle.ktsの場合の例です。
Gradleにktlintグループが作成されて、ktlintが実行できるようになっています。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/d9f33023-2937-82c9-cf71-323ec495fc1e.png width=500 />



## Actions


.github/workflows/ktlintchecker.yml

Actionにもktlintチェックを仕込みます。

```yaml
name: reviewdog
on: [pull_request]
jobs:
  ktlint:
    name: Check Code Quality
    runs-on: ubuntu-latest

    steps:
      - name: Clone repo
        uses: actions/checkout@master
        with:
          fetch-depth: 1
      - name: ktlint
        uses: ScaCap/action-ktlint@master
        with:
          github_token: ${{ secrets.github_token }}
          reporter: github-pr-review # Change reporter

```



## Commit前にKtlintチェックする


### command line版のktlintを入れる

```
brew install ktlint
ktlint --version
```


旧バージョンを入れる場合

[brewは最新版しか保持しない方針](https://docs.brew.sh/FAQ#how-can-i-keep-old-versions-of-a-formula-when-upgrading)のようなので、


旧バージョンを入れるには以下の方法を行う。今回はプラグインに合わせて、0.42.0を入れる
参考:[Homebrewで過去のバージョンを使いたい【tap版】 \- Carpe Diem](https://christina04.hatenablog.com/entry/install-old-version-with-homebrew)

```
brew uninstall ktlint
brew tap-new jun06t/taps
brew extract ktlint jun06t/taps --version 0.42.0
brew install jun06t/taps/ktlint@0.42.0
brew link ktlint@0.42.0
```



### pre-commitを導入

```
brew install pre-commit
pre-commit --versionß
```


以下のように表示されたら `xcode-select --install`を行う

```
Error: python@3.9: the bottle needs the Apple Command Line Tools to be installed.
  You can install them, if desired, with:
    xcode-select --install
```

xcode

```
xcode-select --install
```


## pre-commit-hookの作成

プロジェクトRootで以下を実行する

```
ktlint --install-git-pre-commit-hook
```


`.git/hooks/` 配下に `pre-commit`が作成される


```:pre-commit
#!/bin/sh
# https://github.com/shyiko/ktlint pre-commit hook
git diff --name-only --cached --relative | grep '\.kt[s"]\?$' | xargs ktlint --relative .
if [ $? -ne 0 ]; then exit 1; fi
```


これでCommitのたびにktlintが走ります。



以上