1. [문제 분석] 코드 포맷팅을 강제해 confilct를 최소화할 방법 없을까? 
(1) 문제 인지
총대마켓 팀은 intellij-java-wooteco-style.xml 을 이용해 코드 포맷팅을 진행하고 있었습니다.
intellij-java-wooteco-style.xml을 이용하는 Intellij의 코드 스타일 설정은 아래와 같은 방식으로 등록합니다. 아마 대다수의 우테코 크루들이 아래와 같은 방식으로 코드 포맷팅을 진행하고 있으리라 생각합니다.
인텔리제이 코드 스타일 설정 예시 (with. 인텔리제이 코드 포맷터)
1.
2.
Settings > Editor > Code Style > Java > 톱니바퀴 > Import Scheme > Intellij IDEA code style XML > 다운로드 해둔 WootecoStyle 파일 선택해 적용 > OK
3.
(선택) Settings > Tools > Actions on Save > Reformat code, Optimize imports 체크
이때 IntelliJ가 아닌 VScode로 파일을 건들어 코드 스타일이 적용되지 않는 경우가 생겼습니다. 또 누군가는 Actions on Save를 사용하지 않아 코드 스타일이 적용되지 않은 채로 커밋이 올라오는 경우도 더러 생겼습니다.
IntelliJ의 Actions on Save 기능에만 의존해 전체 코드의 스타일을 유지하는 건 어려울 수 있겠단 생각이 들었습니다. 협업에서 전체 코드의 스타일을 유지하는 건 중요합니다. 코드 스타일이 맞지 않아 발생하는 conflict를 계속해 해결해야 하는 병목이 생길 수 있기 때문입니다.
(2) 해결책 탐색
코드 포맷팅을 체크하기 위한 방법으론 아래와 같은 방법들이 있습니다.
1.
intellij code formatter > xml
2.
checkstyle > xml
3.
stopless > intellij
4.
editorconfig
2. [배경 지식 학습] editorconfig-gradle-plugin 에 대해 알아보자 
이 파트의 내용은 editorconfig-gradle-plugin 의 README 내용을 번역하여 정리한 내용입니다.
•
정의) .editorconfig 파일에 정의된 형식 규칙을 준수하는지 여부를 확인하고, 위반 사항을 수정하기 위한 Gradle 플러그인
•
기본 사용)
◦
전제조건) Java 8+ 과 Gradle 4.1+ 에 사용 가능
1.
플러그인 추가
•
https://plugins.gradle.org/plugin/org.ec4j.editorconfig 에서 최신버전 확인 가능
plugins {
...
// Check the latest version at https://plugins.gradle.org/plugin/org.ec4j.editorconfig
id 'org.ec4j.editorconfig' version '...'
}
JSON
복사
2.
소스 파일이 .editorconfig 규칙을 준수하는지 확인 (.editorconfig 파일 있어야 함)
./gradlew editorconfigCheck // 소스 파일이 .editorconfig 규칙을 준수하는지 확인
./gradlew editorconfigFormat // 위반 사항 자동으로 수정
Groovy
복사
3.
또는 editorconfigCheck task를 프로젝트의 다른 task에 바인딩
•
ex. Java 플러그인이 있다면 check 작업에 바인딩하는 것이 자연스러움
plugins {
id 'java'
id 'org.ec4j.editorconfig' version '...'
}
check.dependsOn editorconfigCheck
Groovy
복사
•
추가 설정)
◦
.editorconfig 확장 객체 이용해 설정
editorconfig {
# 기본적으로 모든 파일이 포함됩니다. 경로 또는 패턴은 프로젝트 루트 디렉터리를 기준으로 해야 합니다.
includes = ['src/**', 'build.gradle']
# 기본 제외 항목 외에도 몇몇 파일을 제외합니다.경로 또는 패턴은 프로젝트 루트 디렉터리를 기준으로 해야 합니다.
excludes = ['derby.log', 'LICENSE']
}
Groovy
복사
•
동작 과정)
◦
editorconfig-gradle-plugin은 org.ec4j.maven:ec4j-lint-api와 org.ec4j.maven:ec4j-linters 라이브러를 사용함
◦
두 라이브러리는 Linter 인터페이스를 중심으로 설계됨
◦
Linter는 특정 파일 형식(YAML 또는 XML 등)에 대해 .editorconfig 속성이 만족되는지 여부를 감지하고, 필요한 경우 자동으로 적용 가능한 수정을 제안하는 프로세서임
3. [문제 해결] 빌드 과정에서 코드 포맷팅 체크하기 (with editorconfig)
이 파트의 내용은 독자가 바로 적용해볼 수 있는 솔루션을 제공하는 걸 목표로 합니다.
(1) .editorconfig 파일에서 자바 파일에 대한 형식 규칙을 정의
•
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.java]
indent_style = space
indent_size = 4
Groovy
복사
•
◦
변환 방식) intellij-java-wooteco-style.xml을 적용한 후 추출함
1.
Settings > Editor > Code Style > 톱니바퀴 > Import Schema > IntelliJ IDEA code style XML > 다운로드해둔 WootecoStyle 파일 선택해 적용 > OK
2.
Settings > Editor > Code Style > 톱니바퀴 > Export > EditorConfig
▪
위 방식과 같이 인텔리제이의 export 기능을 이용해 어떤 코드 스타일이든 쉽게 EditorConfig 파일로 변환 가능함
▪
주의할 점으론 생성된 EditorConfig 파일 내용 중 빈 값이 들어간 게 종종 있는데, 이는 실행 시 오류를 일으키기에 수동으로 해당 라인을 지워줘야 함
•
ex. Property 'ij_visual_guides' has no value at 14:20 (318)
◦
변환 결과) 혹시 intellij-java-wooteco-style.xml을 editorconfig로 변환한 것을 사용하고 싶다면, 도라가 미리 변환해둔 아래 파일을 그대로 써도 됨:) (다운받은 후 파일 이름을 .editorconfig 로 변경해 프로젝트 루트 경로에 두기)
(2) .editorconfig 규칙 검사가 check 작업에 의존하도록 설정
// build.gradle
plugins {
id 'java'
id 'org.ec4j.editorconfig' version '...'
}
editorconfig {
includes = ['src/**/*.java', 'build.gradle'] // 자바 파일과 build.gradle 파일을 포함
excludes = ['build/**', 'out/**'] // 빌드 및 출력 디렉터리 제외
}
check.dependsOn editorconfigCheck
Groovy
복사
(3) (선택) CI 스크립트 추가
CI 스크립트가 필요한 이유 (with. 예시)
[전제]
•
PR이 머지될 때 CI/CD 스크립트가 실행되게 설정되어 있는 프로젝트
•
위의 2번 과정을 적용해 build 시 editorconfigCheck task 가 실행되도록 설정한 프로젝트
[문제 상황]
1.
수동으로 build 해보지 않았다면, 해당 PR 속 코드가 포맷되어 있지 않단 걸 눈치 채지 못한 채 PR을 머지할 수 있음
2.
이 경우 PR 머지 시 도는 CI/CD 과정에서 코드 포맷이 맞지 않아 뜨는 build 실패를 마주하게 될 텐데, 이를 해결하기 위해 오직 코드 포맷만을 위한 PR을 새로 만들어야 한단 불편함 존재함
[해결책]
•
PR에 커밋이 들어오는 시점에 별도의 CI 스크립트가 동작한다면 위의 문제를 해결할 수 있음
•
기존 CI/CD 스크립트
JSON
복사
•
기존 CI/CD 스크립트에 기반해 추가한 CI 스크립트
JSON
복사




