코틀린 공식 문서에서는 코드를 작성하는 스타일을 컨벤션으로 가이드를 해주고 있다. https://kotlinlang.org/docs/coding-conventions.html
하지만 일일이 컨벤션을 맞춰 작성하는 것은 여간 쉬운일이 아니다. 회사에서 다른 개발자와 공동으로 작업할 때 컨벤션에 맞지 않으면 커밋조차 못하도록 강제할 수 있을까?
스프링 진영에서는 Sonar Lint(소나 린트)를 사용하여 코드 스타일을 점검하는 경우가 많다. 코틀린 진영에서는 더욱 클린한 코드를 위하여 Kotlin Lint(ktlint)를 사용한다.
ktlint의 스타일 예시는 공식 사이트를 확인하면 된다.
ktlint의 공식 사이트에서는 Gradle Plugin을 권장하고 있다. 가장 많이 사용한다고 알려진 Ktlint인 글에서는 org.jlleitschuh.gradle.ktlint를 사용한다.
id("org.jlleitschuh.gradle.ktlint") *version* "10.2.0"
플러그인을 추가하면 우측 gradle 메뉴에 ktlintFormat, ktlintCheck 기능이 생긴다.
ktlint는 플러그인만 추가하면 기능을 사용할 수 있지만 강제를 하는 기능이기 때문에 어느 정도의 커스터마이징이 필요하다. 프로젝트에 .editconfig
를 추가하면 스타일을 설정할 수 있다. 파일을 추가하면 의도하지 않게 상위 디렉토리의 .editorconfig가 참조되는 경우를 막아주기도 한다.
root = true
[*]
charset=utf-8
end_of_line=lf
indent_style=space
indent_size=4
insert_final_newline=true
disabled_rules=no-wildcard-imports,import-ordering,comment-spacing
[*.{kt,kts}]
insert_final_newline=false
프로젝트의 코드가 ktlint에 부합하는지 확인한다.
./gradlew ktlintcheck
자동으로 ktlint 스타일에 맞게 변경하는 기능이다. 하지만 개발자가 예상하지 못한 formatting이 발생할 수 있으므로 사용을 권장하지 않는다.
코틀린 린트 plugin이 있다. unofficial 이므로 선택적으로 사용할 수 있다.
스타일에 맞지 않으면 warning 표시가 된다.
Git Hook pre-commit 설정
pre-commit 스크립트에 ktlint check 내용 포함한다. commit 시 ktlint check에서 잘못된 스타일을 발견하면 커밋이 되지 않는다.
#!/bin/sh
set -e
######## KTLINT-GRADLE HOOK START ########
CHANGED_FILES="$(git --no-pager diff --name-status --no-color --cached | awk '$1 != "D" && $NF ~ /\.kts?$/ { print $NF }')"
if [ -z "$CHANGED_FILES" ]; then
echo "No Kotlin staged files."
exit 0
fi;
echo "Running ktlint over these files:"
echo "$CHANGED_FILstatus"
./gradlew ktlintCheck --daemon
status=$?
echo "$status"
if [ "$status" = 0 ] ; then
echo "> Completed ktlint hook."
exit 0
else
echo "> Error ktlint hook."
echo "============================"
exit 1
fi
echo "Completed ktlint run."
######## KTLINT-GRADLE HOOK END ########
build.gradle.kts에 task 추가
개인 로컬에서는 적용할 수 있지만 pre-commit 스크립트가 있는 .git/hooks 경로가 ignore 되어 있어 디렉토리에 파일 공유가 되지 않는다. pre-commit 스크립트를 미리 만들어 프로젝트에 첨부해 놓고 빌드 과정에서 .git/hooks 경로로 파일 복사한다. 커밋시 ktlinCheck를 먼저 실행하고 실패하면 커밋을 날리지 못하게 설정할 수 있다.
build.gradle.kts
val installLocalGitHook = register<Copy>("installLocalGitHook") {
from("${rootProject.rootDir}/script")
into(File("${rootProject.rootDir}/.git/hooks"))
}
build {
dependsOn(installLocalGitHook)
}
이후에 commit을 할 때는 ktlintCheck가 먼저 실행이 되어
안녕하세요. kotlin + spring boot 로 동일하게 세팅을 하고 있는데, 아래 코드에서 register, build, dependsOn 에 각각 다른 에러가 발생합니다.
register 는 인식을 못해서 import 를 해줘야 하는데, 어느 패키지를 import 해야 하는지 등등..
혹시 build.gradle.kts 의 import 부분을 볼 수 있을까요?