【Android】ktlint を導入してみた
ktlint について
ktlint
とは、Kotlin(kotlinlang.org)とAndroid(Android Kotlin Style Guide)で推奨されているコーディング規約を元に、コードスタイルをチェックしてくれるツールです。
規約について
Package
- パッケージ名は小文字にする。アンダースコアは使わない
- OK:
org.example.project
- NG:
org.example.my_project
- OK:
- 複数の単語を使用することは、推奨されていない。どうしても使いたいときは、単語を「連結させる」か「キャメルケース」にする(キャメルケースは、Androidの規約ではダメってなってた)
- 連結:
org.example.myproject
- キャメルケース:
org.example.myProject
- 連結:
Property
シングルトンの参照をもつプロパティは、オブジェクトと同じ名前にすることができる
// singleton
val PersonComparator: Comparator<Person> = /*...*/
クラス内に同じ概念のプロパティが2つあり、1つを外部に公開したい場合は、プライベートプロパティのプレフィックス(文字の先頭)に、アンダースコアを付ける
class C {
private val _elementList = mutableListOf<Element>()
val elementList: List<Element>
get() = _elementList
}
Factory Function
関数名は基本小文字から始めるキャメルケースを使用するが、クラスのインスタンスを生成に使うファクトリ関数は、返す抽象の型と同じ名前にすることができる
interface Foo { /*...*/ }
class FooImpl : Foo { /*...*/ }
fun Foo(): Foo { return FooImpl() }
Test Method
- バッククオートで囲まれたスペースを含むメソッド名を使うことができる
- メソッド名には、アンダースコアを含めることができる
- Androidの規約では、スペースを含めるのは推奨されていないので、アンダースコアの方を使うのが良さそう
class MyTestCase {
@Test fun `ensure everything works`() { /*...*/ }
@Test fun ensureEverythingWorks_onAndroid() { /*...*/ }
}
Empty Block
改行する
// WRONG!(よくこういう書き方してしまう)
try {
doSomething()
} catch (e: Exception) {}
// Okay
try {
doSomething()
} catch (e: Exception) {
}
ktlint の導入
app/build.gradle
に以下を追加します。
// Add
configurations {
ktlint
}
// Add コードスタイルをチェック
task ktlint(type: JavaExec, group: "verification") {
description = "Check Kotlin code style."
// main = "com.pinterest.ktlint.Main" は非推奨
mainClass.set("com.pinterest.ktlint.Main")
classpath = configurations.ktlint
args "src/**/*.kt", "--color", "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml"
}
// Add
check.dependsOn ktlint
// Add 自動でフォーマットしてくれる
task ktlintFormat(type: JavaExec, group: "formatting") {
description = "Fix Kotlin code style deviations."
// main = "com.pinterest.ktlint.Main" は非推奨
mainClass.set("com.pinterest.ktlint.Main")
classpath = configurations.ktlint
args "-F", "src/**/*.kt"
}
dependencies {
...
// Add
ktlint "com.pinterest:ktlint:0.43.1"
}
ktlint の実行
build.gradle
、または、コマンドでktlint
を実行できます。
build.gradle の「▶︎」で実行
コマンドで実行
$ ./gradlew ktlint
$ ./gradlew ktlintFormat
Android Studio でのコードスタイルの設定
ktlint
の README.md で、ktlint
に引っかからないようにするIntelliJIDEA
の設定方法が紹介されています。
自動で ktlint を実行できるようにする
毎回手動でktlint
を実行するのは手間だったり、忘れたりしそうなので、「コミット時」または「Github Actionを実行したとき」に、解析が行われるようにしてみたいと思います。
コミット時
pre-commit
を使います。
pre-commit
とは、コミット時にスクリプトを実行できる機能です。
以下のコマンドを実行することで、[project name]/.git/hooks/pre-commit
ファイルを作成します。
# ktlintがインストールされているかチェック。インストールされてなければ、brew install ktlint
$ ktlint --version
0.40.0
$ ktlint --install-git-pre-commit-hook
すでにpre-commit
ファイルが存在する場合は、以下をpre-commit
ファイルに追記します。
git diff --name-only --cached --relative | grep '\.kt[s"]\?$' | xargs ktlint --relative .
if [ $? -ne 0 ]; then exit 1; fi
不要になったときは、rm .git/hooks/pre-commit
でファイルを削除するか、pre-commit
のスクリプトを削除すると良さそうです。
Github Actions
[Project name]/.github/workflows/
に.yml
ファイルを作成します。
作成済みの場合は、steps:
にname:
とrun:
を追記します。今回は新規にktlint.yml
を作成したいと思います。
ktlint.yml
name: ktlint
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
ktlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run ktlint
run: ./gradlew ktlint
Discussion