안녕하세요 점냥입니다 :)
처음으로 받은 코드 리뷰 중 기억나는 코멘트는 이거예요. "불필요한 개행이라 지워주세요". 당시 개행은 그저 넘어갈 수 있는 사소한 실수로 여겨 코멘트를 남긴 그분에게 서운함을 느꼈었죠. 하지만 지금은 저도 코드 리뷰를 해드릴 때 가장 먼저 개행, 공백 등의 사소한 부분부터 체크하고 있네요 :)
이처럼 한 프로젝트에 여러 명의 개발자와 협업을 하다 보면 각자 코드 스타일이 달라 부딪치는 때가 많더라고요. 그래서 오늘 소개해드릴 splotless을 사용해서 코드 스타일을 맞춰보면 좋을 것 같아요!
Spotless
Spotless은 선언한 코드 스타일에 맞지 않는 코드를 감지하고 자동으로 수정해주는 포맷터의 역할을 수행해줘요. 지원해주는 언어로는 c, c++, java, kotlin, xml 등 정말 다양한데요. Splotless 자체적으로 모든 언어에 대한 코드 스타일 규칙을 가지고 있지 않고 java면 googleJavaFormat, kotlin이면 ktlint처럼 언어에 맞는 포맷터를 import 하여 사용하는 방식이에요 :)
선언하기
plugins {
id "com.diffplug.spotless" version "6.11.0"
}
subprojects {
apply plugin: 'com.diffplug.spotless'
spotless {
kotlin {
target '**/*.kt'
targetExclude("$buildDir/**/*.kt")
targetExclude('bin/**/*.kt')
ktlint()
trimTrailingWhitespace()
indentWithSpaces()
endWithNewline()
}
}
}
- target: spotless로 검사하고 수정될 파일을 지정하는 명령어예요. 코드에서는 kt 확장자로 끝나는 모든 파일로 지정되어 있어요.
- targetExclude: 검사 대상으로 제외할 파일을 지정하는 명령어예요. 코드에서는 컴파일 타임에 생성되는 코틀린 파일들을 제외해주고 있어요.
- trimTrailingWhitespace: 라인 끝에 있는 공백을 제거해주는 명령어예요
- indentWithSpaces(n: Int) : 들여 쓰기의 공백을 n번의 띄어쓰기로 지정하는 명령어예요. default 값은 2입니다
- endWithNewline: 파일의 끝이 new line으로 끝나는지 검증하는 명령어라고 하네요
실제로 사용해보기
gradlew spotlessCheck
gradlew spotlessApply
프로젝트에 적용이 완료되었다면 위 명령어를 실행하여 spotless를 실행할 수 있어요. 저도 최근 동아리에 개발 중인 Android 앱에 실제로 적용해서 명령어를 실행해본 결과를 보여드릴게요!
C:\Users\user\Desktop\project\mashup_Android>gradlew spotlessCheck
Starting a Gradle Daemon, 3 incompatible Daemons could not be reused, use --status for details
> Task :app:spotlessKotlin FAILED
Step 'ktlint' found problem in 'src\main\java\com\mashup\data\repository\AttendanceRepository.kt':
Error on line: 3, column: 1
rule: no-wildcard-imports
Wildcard import
java.lang.AssertionError: Error on line: 3, column: 1
rule: no-wildcard-imports
spotlessCheck 명령어를 실행을 하니까 마치 Exception이 발생했던 것처럼 StackTrace가 터미널에 표시돼요. no-wildcard-imports 규칙을 위반했다고 나오고 있어요.
*로 해당 패키지의 모든 파일을 import 하는 방식을 사용하지 말라는 규칙이에요. 동일한 패키지에서 5개 이상 import를 하게 되면 자동으로 wildcard-imports로 변경되곤 하는데요. Android IDE 설정에서 자동으로 변경되는 기능을 꺼줄 수 있어요 :)
그런데 spotlessApply를 실행했는 데 splotessCheck 명령어를 실행했을 때처럼 wildcard-imports를 위반했다고 표시되더라고요 -3- 나중에 알아보니 spotlessApply를 실행했을 때 규칙에 어긋난 코드들이 자동으로 수정해주지만 Git Merge 충돌처럼 자동으로 수정되기 애매한 경우 동일하게 에러를 노출되는 것 같아요.
다시 Spotless의 기능을 알아보기 위해 사진처럼 무의미한 공백을 넣었어요.
C:\Users\user\Desktop\project\mashup_Android>gradlew spotlessCheck
> Task :common:spotlessKotlinCheck FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':common:spotlessKotlinCheck'.
> The following files had format violations:
src\main\java\com\mashup\common\widget\TextFieldView.kt
@@ -27,7 +27,7 @@
class·TextFieldView·@JvmOverloads·constructor(
····context:·Context,
····attrs:·AttributeSet?·=·null,
-···········defStyleAttr:·Int·=·0
+····defStyleAttr:·Int·=·0
)·:·ConstraintLayout(context,·attrs,·defStyleAttr)·{
····private·val·viewBinding:·ViewTextLayoutBinding·=
Run 'gradlew.bat :common:spotlessApply' to fix these violations.
어떤 Rule을 위반했는지는 나오지는 않았지만 spotlessApply 명령어를 통해 수정하라고 알려주네요 :) 그럼 수정해볼까요?
C:\Users\user\Desktop\project\mashup_Android>gradlew spotlessApply
...
BUILD SUCCESSFUL in 965ms
정리하며
Spotless를 어떻게 하면 협업 프로세스에 알맞게 녹아들게 할 수 있을 까요? 직접 사용해보지 않았지만 git hook을 이용하여 git commit을 할 때 동시에 spotless 실행하는 경우도 있었고 Pull Request의 템플릿으로 spotless를 실행해보았는지에 대한 체크 박스를 넣기도 하더라고요 :)
'Android > Gradle' 카테고리의 다른 글
[Android] Gradle 버전 카탈로그를 사용해 버전 관리하기 (0) | 2023.06.01 |
---|---|
[Android] 빌드 속도 개선 with Gradle Options (0) | 2022.11.09 |
[Android] RepositoriesMode (0) | 2022.09.03 |