작업환경을 타지 않는 방법의 필요성
코딩 스타일의 일관성은 가독성, 협업에서 중요한 포인트이지만 개인적인 코딩 습관들, 빡빡한 일정들 등으로 인해 지키기 쉽지 않다. IDE에서 저장시에 코드 포맷팅을 해주는 기능들이 있기는 하지만, 작업환경마다 세팅해줘야한다는 단점이 있다. 따라서 어떤 환경에서 작업하더라도 코딩 스타일을 지켜줄 수 있는 방법이 필요했다.
(이 원문을 응용하여 작성된 글입니다.)
GitHook + ktlint
그것은 바로 GitHook을 이용하는 방법이다. git init
을 하면 .git/hook
폴더에는 여러 GitHook 샘플들이 생긴다. 이 경로 안에 내가 Hook을 발생시키기 원하는 시점에 대한 파일을 “확장자 없이” 넣어주면 간단히 Hook 세팅을 할 수 있다. 샘플 파일들은 .sample
확장자가 있기에 실행이 안되는 것이다.
예로들면 Commit전에 할 일을 정의한다면 실행가능한 pre-commit
이라는 파일을 여기에 넣어두면된다. 각각이 어떤 상황인지에 대한 설명은 Cutomizing GIt - Git Hooks를 참조하면 된다.
1 -rwxr-xr-x 1 ASUS 197121 478 11월 15 16:50 applypatch-msg.sample
4 -rwxr-xr-x 1 ASUS 197121 896 11월 15 16:50 commit-msg.sample
8 -rwxr-xr-x 1 ASUS 197121 4726 11월 15 16:50 fsmonitor-watchman.sample
1 -rwxr-xr-x 1 ASUS 197121 189 11월 15 16:50 post-update.sample
1 -rwxr-xr-x 1 ASUS 197121 424 11월 15 16:50 pre-applypatch.sample
4 -rwxr-xr-x 1 ASUS 197121 1643 11월 15 16:50 pre-commit.sample
1 -rwxr-xr-x 1 ASUS 197121 416 11월 15 16:50 pre-merge-commit.sample
4 -rwxr-xr-x 1 ASUS 197121 1492 11월 15 16:50 prepare-commit-msg.sample
4 -rwxr-xr-x 1 ASUS 197121 1374 11월 15 16:50 pre-push.sample
8 -rwxr-xr-x 1 ASUS 197121 4898 11월 15 16:50 pre-rebase.sample
1 -rwxr-xr-x 1 ASUS 197121 544 11월 15 16:50 pre-receive.sample
4 -rwxr-xr-x 1 ASUS 197121 2783 11월 15 16:50 push-to-checkout.sample
4 -rwxr-xr-x 1 ASUS 197121 3650 11월 15 16:50 update.sample
나는 이 중에서 pre-push
를 이용하려한다. Commit은 많을땐 하루에도 몇 번씩 할 때가 있는데, gradle task 수행 속도가 느려서 Commit 마다 Formatting할 경우 생산성이 저하될 가능성이 있기 때문이다.
멀티모듈을 위한 Ktlint 세팅
Ktlint는 Kotlin 표준 코딩 스타일 가이드에 따라 코드 스타일을 검사하고 Formatting도 시켜주는 툴인데, 우리는 Ktlint Gradle Plugin인 https://github.com/jlleitschuh/ktlint-gradle 를사용해 볼 것이다. 모놀리틱 프로젝트에서 세팅하는 방법은 해당 Github 페이지에 존재하므로 참고하면되고, 나는 프로젝트 전체에 적용하는 방법을 소개한다.
// project/build.gradle
// [kts/Kotlin DSL]
plugins {
id("org.jlleitschuh.gradle.ktlint") version "11.1.0"
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jlleitschuh.gradle:ktlint-gradle:11.1.0")
}
}
allprojects {
apply(plugin = "org.jlleitschuh.gradle.ktlint")
}
// [Groovy]
plugins {
id "org.jlleitschuh.gradle.ktlint" version "11.1.0"
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jlleitschuh.gradle.ktlint:11.1.0"
}
}
allprojects {
apply plugin: "org.jlleitschuh.gradle.ktlint"
}
이대로 빌드하고 나면 formatting/ktlintForamt
과 verification/ktlintCheck
Gradle Task가 생겨난 것을 볼 수 있을 것이다. 그러면 성공!
이제 명령행에 다음과 같이 입력하면 Formatting이 이루어진다.
$ ./gradlew ktlintFormat
GitHook 세팅
이를 pre-push
마다 이루어지게 하기 위해서 프로젝트 Root 아래 pre-push
파일을 만들어주고, 내용은 다음과 같이 입력한다. 각 라인에 대한 설명은 주석으로 대체하겠다.
$ touch pre-push
#!/bin/sh
echo "Running git pre-push hook"
./gradlew ktlintFormat --daemon
// $? = ".gradlew ktlintFormat --daemon"에 대한 return 값
STATUS=$?
// 문제없이 끝났다면 exit 0, 아니면 1
// -ne: Not equals
[ $STATUS -ne 0 ] && exit 1
exit 0
이제 안드로이드 프로젝트를 Build하면, 이 pre-push
파일을 .git/hooks
에 복사하여 넣어주는 Task를 만들어 준다. .git
은 Git에 포함되지 않기때문에 어느 환경에서나 돌아가기 위해 해당 작업을 해주는 것이다.
tasks.register<Delete>("deletePreviousGitHook") {
val prePush = "${rootProject.rootDir}/.git/hooks/pre-push"
if (file(prePush).exists()) {
delete(prePush)
}
}
tasks.register<Copy>("installGitHook") {
dependsOn("deletePreviousGitHook")
from("${rootProject.rootDir}/pre-push")
into("${rootProject.rootDir}/.git/hooks")
eachFile {
fileMode = 777
}
tasks.getByPath(":app:preBuild").dependsOn("installGitHook")
}
작성을 끝낸 후 Build를 수행하게 되면 .git/hooks/pre-push
를 확인할 수 있을 것이다. 이제 코드를 아무렇게나 작성한 후 Push하면 Running git pre-push hook
메세지가 출력되며 자동으로 Formatting이 이루어지게 된다.
$ ls .git/hooks -al | grep "pre-push"
-rwxr-xr-x 1 ASUS 197121 131 Feb 4 15:51 pre-push
-rwxr-xr-x 1 ASUS 197121 1374 Aug 15 15:54 pre-push.sample
'프로그래밍 > Android' 카테고리의 다른 글
[안드로이드] 회전목마(Carousel) 애니메이션 구현하기 (0) | 2023.04.27 |
---|---|
[안드로이드] 특정 시간 내 중복 Request를 막는 OkHTTP Interceptor 구현하기 (0) | 2023.03.28 |
[안드로이드] ExoPlayer 깜빡거리거나 검은 화면(Black screen)이 뜰 때 (0) | 2023.01.31 |
[안드로이드] java.lang.IllegalStateException: An instance of OnFlingListener already set 해결 (0) | 2023.01.26 |
[CI/CD] Firebase Test Labs UI Test 자동화하기 (0) | 2022.09.30 |