728x90
프로젝트에 Kotlin의 컨벤션을 지키기 위해 Ktlint를 사용해보기.
서론
- 최근 노마드 커뮤니티 사이드프로젝트를 진행하면서 학습 및 새로운 경험을 하기 위해 백엔드 언어를 Kotlin으로 채택하여, 개발을 시작하게 되었습니다.
- 현재는 1인 개발이지만, 초기에 컨벤션을 잘 지켜두기 위해 Ktlint를 적용한 이야기를 해보려고 합니다.
ktlint란?
An anti-bikeshedding Kotlin linter with built-in formatter.
포맷터가 내장된, 바이크셰이팅 방지용 코틀린 린터입니다.
- cf) Anti-bikeshedding이란?
- 사소함의 법칙이라고 불리우는, 영향력이 미미하거나 중요성이 없는 항목에 불균형적인 시간을 소비하는것을 말합니다.
- 즉, 작은 문제에 집착하면서 시간을 소비한다는 의미입니다.
- Ktlint의 한줄 설명이 해당 라이브러리에 역할을 모두 보여준다고 할수 있습니다.
사용법
- 사용법은 2가지가 있지만, 프로젝트에 내장에서 사용하는 Gradle 방식에 대해서만 설명하도록 하겠습니다.
- 일단 Plugin에 아래와 같이 추가하면 됩니다.
plugins {
id("org.jlleitschuh.gradle.ktlint") version $currentVersion
id("org.jlleitschuh.gradle.ktlint-idea") version $currentVersion
}
- cf) 버전은 아래에서 확인하면 됩니다.
- 기본적으로 사용되는 기능들은 모두 ktlint에 있으며, JetBrain 사의 IntelliJ에서 지원하지 않는 몇가지 부가적인 기능과 린트에 대해서 도와주는 역할을 하는것이 ktlint-idea입니다.
- 자동으로 Lint를 적용하거나, Lint에 어긋나는 것들에 대한 경고를 받고 싶다면 해당 플러그인을 설치하면 편안하게 사용가능합니다.
.editorconfig 설정
- 린트의 설정을 오버라이딩을 하기 위해선
.editorconfig
해당 파일을 만들어서 관리하면 됩니다. - 없다면 아래와 설정과 같이, standard가 적용됩니다.
- https://pinterest.github.io/ktlint/latest/rules/standard/
Gradle Task
- 해당 Ktlint 플러그인을 설치하면 아래와 같이 여러가지들의 Command들이 나오게 됩니다.
- Main tasks
loadKtlintReporters
- preloads KtLintReporter
srunKtlintCheckOverKotlinScripts
- runs actual lint check over project Kotlin script filesktlintKotlinScriptCheck
- generates reports and prints issues into Gradle console based on lint check found errors. This task execution depends onloadKtlintReporters
andrunKtlintCheckOverKotlinScripts
tasks execution outputsrunKtlintFormatOverKotlinScripts
- tries to format according to the code style project Kotlin script filesktlintKotlinScriptFormat
- generate reports and prints issues into Gradle console based on found non-formattable errors. This task execution depends onloadKtlintReporters
andrunKtlintFormatOverKotlinScripts
tasks execution outputsktlintCheck
- checks allSourceSet
s and project Kotlin script filesktlintFormat
- tries to format according to the code style allSourceSet
s Kotlin files and project Kotlin script files
- Then for each
SourceSet
plugin adds following tasks:runKtlintCheckOver[source set name]SourceSet
- runs actual lint check on every Kotlin file in givenSourceSet
ktlint[source set name]SourceSetCheck
- generates reports and prints issues into Gradle console based on lint check found errors. This task execution depends onloadKtlintReporters
andrunKtlintCheckOver[source set name]SourceSet
tasks execution outputsrunKtlintFormatOver[source set name]SourceSet
- tries to format according to the code style every Kotlin file in givenSourceSet
ktlint[source set name]SourceSetCheck
- generates reports and prints issues into Gradle console based on found non-formattable errors. This task execution depends onloadKtlintReporters
andrunKtlintFormatOver[source set name]SourceSet
tasks execution outputs
- Additional helper tasks
Following additional tasks are added:
ktlintApplyToIdea
- The task generates IntelliJ IDEA (or Android Studio) Kotlin style files in the project.idea/
folder. Note that this task will overwrite the existing style file.ktlintApplyToIdeaGlobally
- The task generates IntelliJ IDEA (or Android Studio) Kotlin style files in the user home IDEA (or Android Studio) settings folder. Note that this task will overwrite the existing style file.addKtlintCheckGitPreCommitHook
- adds Gitpre-commit
hook, that runs ktlint check over staged files.addKtlintFormatGitPreCommitHook
- adds Gitpre-commit
hook, that runs ktlint format over staged files and adds fixed files back to commit.
실제 사용할거 같은 Task 살펴보기
- ktlintCheck
- 실제 린트에 반하게 된 코드가 없는지 체크해서 경고해줍니다.
- 실제 린트에 반하게 된 코드가 없는지 체크해서 경고해줍니다.
- ktlintFormat
- 실제 린트에 반하게 된 코드를 자동으로 수정이 가능한 부분은 자동으로 수정해주며, 자동수정이 불가능한 영역에 대해서 알림을 줌
- addKtlintCheckGitPreCommitHook
- Pre commit Hook(커밋 하기 전에 특정한 행동을 하는 것)으로 Klint check를 추가하는 것
- addKtlintFormatGitPreCommitHook
- Pre commit Hook(커밋 하기 전에 특정한 행복을 하는 것)으로 Klint Formmat을 추가하는 것
- ktlintApplyToIdea
- 기존 IntelliJ의 스타일 컨벤션 파일을 Lint 설정에 맞게 변경
몇가지 rule을 확인해보자.
- final-newline
- 각 파일 끝에 줄바꿈을 일관되게 사용하도록 보장합니다.
- default는 true입니다.
- intert_final_newline을 통해
.editorconfig
에서 변경 가능합니다.
- package-name
[a-z][a-zA-Z\d]*(\.[a-z][a-zA-Z\d]*)*
해당 정규표현식과 패키지 이름이 맞는지 체크합니다.
- max-line-length
- 한 라인의 최대 글자수를 지정합니다.
- no-wildcard-imports
- 와일드 카드로 import를 할수 없다는 의미입니다. 이경우 IntelliJ와 충돌날수가 있는데, 둘중에 하나의 설정을 변경해야 합니다.
- Ktlint의 설정을 변경하기 위해선
ij_kotlin_packages_to_use_import_on_demand = unset
를.editorconfig
에 추가해주시면 됩니다.
- no-unit-return
- Unit 유형의 함수의 반환을 생략하는 위한 규칙
- chain-wrapping
- 체이닝 메서드 방식을 사용할때, 아래와 같이 사용해야 합니다.
// O listOf(1,2,3) .filter { it > 2} // X listOf(1,2,3). filter { it > 2}
cf) 더 자세한 것은 ktlint의 공식 홈페이지에서 참고하시면 됩니다.
몇가지 .editconfig
설정을 살펴보자
- insert_final_newline
- 최종 개행을 사용할것인지
- ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than
- 한줄에 맞는 경우에 최소 수의 매개변수가 포함되어 있을지에 대한 설정입니다.
- indent_size & indent_style
- 들여쓰기의 총 갯수와 스타일을 지정합니다.
- default는 4개와 space입니다.
- ij_kotlin_allow_trailing_comma / ij_kotlin_allow_trailing_comma_on_call_site
- 위 코드에 있는 trailing comma를 허용할지 여부
class Person( val firstName: String, val lastName: String, val age: Int, // trailing comma )
마지막으로 github Action으로 CI에 check를 녹여보자.
- https://github.com/ScaCap/action-ktlint
- 위 github action으로 ci에 아래와 같이 작성해주면 됩니다
name: nomad-be-ci
on: push
jobs:
ktlint:
name: Check Code linting
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@main
with:
fetch-depth: 1
- name: ktlint
uses: ScaCap/action-ktlint@master
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
fail_on_error: true
level: warning
- 몇가지 옵션을 살펴보면 아래와 같습니다.
- github_token
- github 저장소에 PR에 리포트를 해야 하기 때문에 필요합니다.
${{ secrets.github_token }}
이런식으로 작성하면 기본으로 들어가게 됩니다.
- github 저장소에 PR에 리포트를 해야 하기 때문에 필요합니다.
- level
- 리뷰 리포트에 대한 로그를 선택할수 있으며 default는 error입니다.
- reporter
github-pr-check
,github-pr-review
,github-check
3가지 기능이 있으며 아래와 같습니다.- github-pr-check
- github-pr-review
- fail_on_error
- error 레벨 이상의 진단이 발견되면 비정상 종료 코드(exit code != 0)를 반환합니다.
- 디폴트는 false입니다.
- ktlint_version
- 디폴트는 latest입니다.
- 설정 옵션에 대한 추가적인것들은 github에서 확인할수 있습니다.
마지막 팁 save lint
- intelliJ의 플러그인 설치한 이후에
Run ktlint --format on save
를 켜두면 해당 파일을 저장할때 lint 포맷이 되기 때문에 훨씬 편합니다.
결론
- 코드 컨벤션은 맨처음 소개했듯이, 사소한 문제이지만, 개발자들에겐 굉장히 중요한 개념이라고 생각합니다.
- 그러다 보니, 시간을 많이 사용하게 됩니다.
- 간단한 플러그인과 설정으로 시간을 단축시킨다면, 리뷰부터 시작해서 코딩을 할때 신경쓸게 없기 때문에 훨씬 더 생산성이 나올거라고 생각합니다.
- 꼭 사용하셔서 시간을 단축시키세요~
728x90
728x90
'Backend > Kotlin' 카테고리의 다른 글
kotlin 1.9.0 언어 업데이트 (0) | 2023.09.09 |
---|---|
Kotlin의 val vs var (0) | 2022.02.05 |