Skip to content

Conversation

@seungryul99
Copy link
Member

close #175

🔎 PR 내용

코드 품질 관리를 위해 코드 포매터정적 분석 도구를 적용해왔는데,
사용 과정에서 개념적으로 보완이 필요한 부분이 있어 이를 정리했습니다.


1️⃣ 용어 정리

기존에는 코드 포매터와 린터를 동일한 개념으로 이해하고 있었지만, 두 도구는 역할이 완전히 다릅니다.

✔ 코드 포매터(Formatter)

코드 포매터는 코드 스타일을 자동으로 정리해주는 도구입니다.

예를 들면:

  • 들여쓰기
  • 공백
  • 괄호 위치
  • 줄바꿈/정렬

이런 요소들을 자동으로 수정해서, 팀 전체 코드가 일관된 형식을 유지하도록 합니다.

📌 포매터는 정적 분석을 하지 않습니다.
📌 규칙 위반을 검사하지 않고, 코드의 모양만 자동으로 고쳐줍니다.


✔ 린터(Linter)

린터는 코드를 실행하지 않고, 정적 분석을 통해 문제를 찾아주는 도구입니다.

예를 들면:

  • 변수·메서드 네이밍 규칙 위반
  • 사용되지 않는 코드
  • 매직 넘버
  • 복잡도가 높은 메서드
  • 잠재적 버그
  • 보안 취약점 가능성
  • 코드 스멜

등을 검사하여 개발자가 개선할 수 있도록 알려줍니다.

📌 린터는 코드를 고치지 않고, 문제를 “지적”하는 역할을 합니다.


2️⃣ 코드 포매터

코드 포매터를 적용하는 가장 쉬운 방법은 IntelliJ IDE의 기능을 활용하는 것이지만, 이 방식은 모든 팀원이 각자 코드 포매팅 설정을 직접 맞춰야 한다는 문제가 있습니다.

새로운 팀원이 합류하거나 팀 규모가 커질수록 이러한 방식은 관리가 번거로워집니다.
이 문제를 해결하기 위해 spotless를 도입해, IDE 설정 없이 프로젝트 단위에서 자동으로 코드 포매팅이 적용되도록 구성했습니다.

팀원들은 평소처럼 코드를 작성하면 되고, 최종적으로 build 과정에서 자동으로 코드 포매팅이 적용되는 방식입니다.


image

위 파일은 네이버에서 제공하는 코드 포매터 설정 파일입니다. 이는 네이버 코딩 컨벤션 전체를 적용하는 것이 아니라, 순수하게 코드 포매팅 규칙만 가져와 사용하는 과정입니다. 우리는 IDE별로 설정을 따로 맞출 필요 없이, Gradle 차원에서 프로젝트 전체의 코드 포매팅을 일관되게 적용하고 관리하기 위해 spotless를 함께 사용합니다.

spotless는 네이버가 제공하는 포매터 파일 중 Eclipse용 XML 파일만 인식합니다. 파일 이름이 Eclipse 포매터라고 해서 IntelliJ 환경에서 사용하지 못하는 것은 아니며, IntelliJ 기반 프로젝트에서도 문제 없이 그대로 적용할 수 있습니다.


<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200"/>

이는 실제 코드 파일 중 일부입니다. 갑자기 xml이 나와서 당황스러울 수 있지만


<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200"/>

예를 들어서 위와 같은 설정의 경우, 말 그대로 주석 라인이 너무 길어서 200자가 넘어가면 줄바꿈 해라 같은 규칙 입니다.


#before
// 이 주석은 아주 아주 아주 길어서 200자를 넘을 수 있고 포매터는 이 경우 자동으로 적절한 위치에서 개행을 수행하게 된다 ...

# after
// 이 주석은 아주 아주 아주 길어서 200자를 넘을 수 있고 포매터는 이 경우 자동으로 적절한 위치에서
// 개행을 수행하게 된다 ...

이런식으로 코드 포매팅이 적용됩니다. 마음에 안드는 포매팅이 있다면 해당 파일에서 직접 커스텀 할 수 있습니다.


image

위와 같이 프로젝트의 루트에 포매팅 파일을 저장하고

plugins {
    id 'com.diffplug.spotless' version "6.25.0" apply false
    ... 
}

spotless를 위한 플러그인을 추가합니다.

subprojects{
    spotless {
        java {
            eclipse().configFile("${rootProject.projectDir}/convention/spotless/naver-code-format.xml")
            importOrder(
                    'java', 'javax' , 'lombok' , 'org', 'com',
                    'com.moyoy.api',
                    'com.moyoy.batch',
                    'com.moyoy.domain',
                    'com.moyoy.infra',
                    'com.moyoy.common'
            )
        }
    } 
    ...
}

멀티모듈에서 모든 하위 모듈에 spotless를 적용합니다.


tasks.withType(JavaCompile).configureEach {
        dependsOn("spotlessApply")
    }

모든 컴파일 이전에 spotless를 적용했고


project(":Moyoy-Api") {
    tasks.named("build") {
        dependsOn(
                ":Moyoy-Common:check",
                ":Moyoy-Domain:check",
                ":Moyoy-Infra:check"
        )
    }
}

실행 가능한 모듈을 빌드시 의존하고 있는 모든 모듈의 check를 실행 했습니다.


image

check의 경우 test를 포함해서 정적 분석 등의 여러 검증 작업을 수행합니다.


즉, 코드를 수정 -> api 모듈 빌드시, 다른 모듈들의 build 까지 직접 수행되지 않지만, check는 수행되게 함 -> check 시 compile이 수행됨 -> 코드 포맷팅도 같이 수행됨.


3️⃣ 린터

이제 들여쓰기, 띄어쓰기 등등에서 자동 포매팅은 완료 했으나, 네이밍 컨벤션은 잘 지켰나? 같은 규칙은 적용되지 않았습니다.

image

이 부분에서 네이버에서 제공하는 rule 파일을 적용해서 checkstyle을 이용한 정적 분석을 수행할까 고민했습니다.

이게 무슨 말인가 싶다면 눈으로 결과부터 보는게 빠를 거 같습니다.


image

checkstyle을 이용할 경우 빌드시 위와 같이 컨벤션 규칙 위반이 발생하면 에러가 발생합니다.

image

IntelliJ의 도움을 받아 위와 같이 몇번째 줄에 어떤 문제가 있는지 알 수 있습니다.


image

하지만, checkstyle을 사용할 경우, 우리는 해당 문서를 보면서 내가 어떤 부분에서 어떤 컨벤션을 지키고 있지 않은지 하나하나 검사하면서 코드를 모두 뜯어 고쳐야 합니다. 만약 프로젝트 초창기 부터 이를 적용했다면 굉장히 좋은 시도라고 생각합니다.

이렇게 프로젝트가 진행된 시점에 이를 사용하기 위해서는 몇일 날 잡고 모든 코드를 컨벤션에 맞게 뜯어 고쳐야 하는 비용이 발생합니다. (진작 했어야 했는데...)

따라서 지금 당장은 사용할 수 없을 것 같네요. 하지만, 다음에 프로젝트를 진행한다면, 이런 린터는 필수로 사용해야 할 것 같습니다.


4️⃣ 정적 코드 분석

이런 기본적인 포매터와 린터 외에도 소나큐브라는 정적 코드 분석 도구를 이용해서 코드 품질 관리를 할 수 있습니다.


image

소나 큐브를 이용할 경우, 위와 같이 우리가 PR을 생성하는 시점에 코드에 대한 분석이 시작 됩니다. 소나 큐브의 경우 별도의 테스트 커버리지 측정 기능도 제공하고, 코드 스멜 정도를 알려주며


image

자체적으로 제공하는 보고서와


image

내 코드의 어떤 부분에 어떤 문제가 존재하고, 보안 취약점 체크등등 정말 상세하게 여러가지 기능을 제공해 줍니다.


5️⃣ 결론 & 아쉬운 점

결론은 우리 프로젝트에는 코드 포매터 까지만 적용이 되고 린터는 적용하지 않은 상태 입니다. 또한 소나큐브도 사용은 하고 있지만, 아직 유의미 하게 활용까지 하고 있지는 않습니다.

아무래도 프로젝트를 처음부터 다시 리팩토링 해보거나 시간을 내서 린터 룰에 맞게 모든 코드를 수정하지 않는 이상 당장 개선할 수 있는 부분은 없을거 같네요..

@seungryul99 seungryul99 self-assigned this Dec 5, 2025
@seungryul99 seungryul99 added the ⚙ Setting 개발 환경 세팅 label Dec 5, 2025
@seungryul99 seungryul99 linked an issue Dec 5, 2025 that may be closed by this pull request
@seungryul99 seungryul99 added :shipit: 승률 This doesn't seem right and removed size/XL labels Dec 5, 2025
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 5, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
13.3% Coverage on New Code (required ≥ 80%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@seungryul99 seungryul99 changed the title chore: 불필요 공백 제거 setting: 포매터 린터 재설정 Dec 5, 2025
@seungryul99 seungryul99 changed the title setting: 포매터 린터 재설정 setting: 포매터 린터 관련 재설정 ★★★ Dec 5, 2025
Copy link
Member

@zzaekkii zzaekkii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

린트랑 포맷터 구분을 잘 정리해주셨군요.
그동안 Rust에서는 cargo fmt / clippy로 워낙 분리가 잘 돼 있어서 익숙했는데,
Java에서의 흐름도 정리된 걸 읽으니까 감이 잡히네요.

사실 Rust에선 clippy와 cargo fix로 바로 수정이 가능했었던지라,
Java에서는 프로젝트 전체에 린트 결과를 자동으로 적용하기 어렵다는 사실도 처음 알았네요.

=> 정리하자면 기존에 적용하던 포매터는 그대로 이용하고,
린터의 경우엔 네이버의 checkstyle rules를 활용할 순 있지만 당장 전체를 수정하기엔 비용이 크다는 거군요.

🙋‍♂️ 이건 제 생각인데, 당장 기존 코드 전체에 린트를 반영하진 않더라도
새로 추가할 PR부터는 린트 기준을 맞춰보는 식으로 천천히 적용해보는 건 어떨까요?

예를 들어, 기존 코드와 신규 코드에 checkstyle 위반이 발생해도 에러로 빌드 실패가 아니라
warning으로만 표시해서 빌드가 실패하지는 않게 해서 내용만 확인해 코드에 반영하는 거죠.

@seungryul99 이 방식은 어떻게 생각하나요?

@seungryul99
Copy link
Member Author

seungryul99 commented Dec 6, 2025

음.. suspression 파일을 이용해서 가능은 할거 같은데 개발 할때마다 린터에서 제외할 파일과 아닌파일들을 직접 관리해 줘야해서 굳이? 싶네요. 너무 헷갈리지 않을까..

@seungryul99 seungryul99 merged commit 0e7231f into develop Dec 7, 2025
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚙ Setting 개발 환경 세팅 :shipit: 승률 This doesn't seem right size/XL

Projects

Development

Successfully merging this pull request may close these issues.

Setting: 린트 재설정

3 participants