๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Backend/Spring

[Spring] checkstyle ์ ์šฉํ•˜๊ธฐ

๐Ÿ“’ ์™œ?

โ—ผ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ, ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์„ ๊ตฌ์„ฑํ•˜๊ณ  ์ž˜ ์ง€ํ‚ค๋Š” ๊ฒƒ์ด ํ˜‘์—…์˜ ๊ธฐ๋ณธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

โ—ผ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์‹œ, ํ†ต์ผ๋œ ์ฝ”๋“œ ๊ตฌ์„ฑ์˜ ๊ฐ€๋…์„ฑ๊ณผ ๋กœ์ง ์ดํ•ด์— ๋„์›€์ด ๋  ๊ฒƒ ๊ฐ™์•„์„œ lint ์„ค์ •์„ ์•Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. 

 

๐Ÿ’ฌ sonarlint vs checkstyle

sonarlint๋Š” IDE ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์„ ์ œ๊ณตํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐœ์ธ์ด ์„ค์ • ํŒŒ์ผ์„ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๊ณ , ์ด๋Ÿฌํ•œ ์„ค์ • ํŒŒ์ผ์„ ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋˜ํ•œ, ํ•ด๋‹น ๋ฐฉ์‹์€ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์— ์–ด๊ธ‹๋‚œ ์ƒํƒœ๋กœ pull-request๋ฅผ ๋“ฑ๋กํ•ด๋„ ์ž๋™์œผ๋กœ merge๋ฅผ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค.

๋ฐ˜๋ฉด, checkstyle์€ gradle build๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ๋“ฑ๋กํ•œ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ”„๋กœ์ ํŠธ์— ํŒŒ์ผ์„ ๋“ฑ๋กœ๋กํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜ ๊ณต์œ ๊ฐ€ ์™„๋ฃŒ๋œ๋‹ค. ๋˜ํ•œ, ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์— ์–ด๊ธ‹๋‚ฌ์„ ๊ฒฝ์šฐ pull-request์˜ merge๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

๐Ÿ’ฅ ์‰ฌ์šด ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜ ๊ณต์œ ์™€ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ pull-request์˜ merge๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ์–ด checkstyle์„ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.


๐Ÿ“’ .editorconfig ํŒŒ์ผ ์„ค์ •

โ—ผ editorconfig๋Š” ์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์ž‘์—…์„ ์ง„ํ–‰ํ•  ๋•Œ, ๋™์ผํ•œ ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

โ—ผ ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ์— .editorconfig๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ €์žฅํ•˜๋ฉด ๋˜๊ณ , IntelliJ๋Š” ๋ณ„๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜๊ฐ€ ํ•„์š” ์—†์œผ๋ฉฐ, ์ดํด๋ฆฝ์Šค๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜๊ฐ€ ์ถ”๊ฐ€๋กœ ์š”๊ตฌ๋œ๋‹ค.

๐Ÿ’ฅ ๊ฐœ์ธ IDE์— ์„ค์ •์ด ์ œ๊ฐ๊ฐ์œผ๋กœ ๋˜์–ด ์žˆ์–ด๋„, .editorconfig ํŒŒ์ผ์ด ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น ์„ค์ •์ด ์ ์šฉ๋˜์–ด ์ฝ”๋“œ ์ž‘์„ฑ์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

โœ” ๋‹ค์Œ์€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ํŒŒ์ผ ์„ค์ •์ด๋‹ค.

root = true

[*]
# [encoding-utf8]
charset = utf-8

# [newline-lf]
end_of_line = lf

# [newline-eof]
insert_final_newline = true

[*.bat]
end_of_line = crlf

[*.java]
# [indentation-tab]
indent_style = tab

# [4-spaces-tab]
indent_size = 4
tab_width = 4

# [no-trailing-spaces]
trim_trailing_whitespace = true

[line-length-120]
max_line_length = 120

 

โœ” ๋นŒ๋“œ ์‹œ, editorconfig ์ฒดํฌ

plugins {
    id 'org.ec4j.editorconfig' version '0.0.3'
}

editorconfig {
    excludes = ['build']
}

check.dependsOn editorconfigCheck // checkstyle์ด ์„ค์ • ๋˜์–ด ์žˆ์„ ์‹œ, editorconfigCheck ํ›„ checkstyle ์ง„ํ–‰

โ—ผ .editorconfig ํŒŒ์ผ๋งŒ ์กด์žฌํ•œ๋‹ค๋ฉด, IDE์˜ ์ฝ”๋“œ ์Šคํƒ€์ผ ์„ค์ •์ด .editorconfig ํŒŒ์ผ์— ๋”ฐ๋ผ์„œ ์ ์šฉ๋œ๋‹ค. gradle build ์‹œ, ๋ณ„๋‹ค๋ฅธ ์ฒดํฌ๋Š” ํ•˜์ง€ ์•Š๋Š”๋‹ค.

โ—ผ ์œ„ ์ฝ”๋“œ๋ฅผ build.gradle์— ์„ธํŒ…ํ•˜๋ฉด, gradle build ์‹œ editorconfig ๊ทœ์น™์„ ๊ฒ€์‚ฌํ•˜๊ณ , checkstyle ๊ทœ์น™์„ ๊ฒ€์‚ฌํ•œ๋‹ค. 


๐Ÿ“’ Spring ํ”„๋กœ์ ํŠธ์— Checkstyle ์ ์šฉํ•˜๊ธฐ

โœ” build.gradle ์„ค์ • ์ถ”๊ฐ€

plugins {
    id 'java'
    id 'checkstyle'
}

checkstyle {
    maxWarnings = 0
    configFile = file("${rootDir}/config/naver-checkstyle-rules.xml")
    configProperties = ["suppressionFile": "${rootDir}/config/naver-checkstyle-suppressions.xml"]
    toolVersion = "8.42"
}

compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'

 

โœ” configFile, configProperties ํŒŒ์ผ ๋‹ค์šด ๋ฐ›์•„ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€

https://github.com/naver/hackday-conventions-java/tree/master/rule-config

 

GitHub - naver/hackday-conventions-java: ์บ ํผ์Šค ํ•ต๋ฐ์ด Java ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜

์บ ํผ์Šค ํ•ต๋ฐ์ด Java ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜. Contribute to naver/hackday-conventions-java development by creating an account on GitHub.

github.com

โ—ผ ์œ„ ๋งํฌ์—์„œ naver-checkstyle-rules.xml ํŒŒ์ผ๊ณผ naver-checkstyle-suppressions.xml ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค. 

โ—ผ ์œ„ ๋งํฌ์—์„œ ๋‹ค์šด ๋ฐ›์€ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์€ ๋„ค์ด๋ฒ„ ์บ ํผ์Šค ํ•ต๋ฐ์ด Java ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์— ๋”ฐ๋ฅธ๋‹ค.

 

โ—ผ ์œ„์™€ ๊ฐ™์ด ๋ฃจํŠธ ํ”„๋กœ์ ํŠธ/config ํด๋” ์•„๋ž˜ ๋‹ค์šด๋กœ๋“œํ•œ xml ํŒŒ์ผ์„ ๋„ฃ๋Š”๋‹ค.

 

โ—ผ ์ธํ…”๋ฆฌ์ œ์ด CheckStyle-IDEA ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•œ๋‹ค.

 

 

โ—ผ Settings -> Checkstyle๋กœ ์ด๋™ํ•˜์—ฌ ์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•œ๋‹ค.

โ—ผ Checkstyle version์€ ์ตœ์‹  ๋ฒ„์ „์ด๋ฉฐ, test ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ํŒŒ์ผ์„ ์ฒดํฌํ•˜๊ณ  ์ฒดํฌ ์Šคํƒ€์ผ ์œ„๋ฐ˜ ์‹œ warning์œผ๋กœ ๋„์–ด ์ค€๋‹ค.

 

โ—ผ ์œ„ ์„ค์ •๊ณผ ์ด์–ด์„œ, Configuration File์˜ + ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ๋’ค, Description ์„ค์ •, ์ด์ „์— ๋ฐ›์•˜๋˜ naver-checkstyle-rules.xml ํŒŒ์ผ์„ ์„ค์ •ํ•œ๋‹ค.

 

โ—ผ Next๋ฅผ ๋ˆ„๋ฅด๋ฉด ์œ„์™€ ๊ฐ™์€ ์ฐฝ์ด ๋œจ๊ณ , ํ”„๋กœํผํ‹ฐ ์„ค์ •์˜ Value ๋ถ€๋ถ„์„ ์ด์ „์— ๋ฐ›์•˜๋˜ naver-checkstyle-suppressions.xml๋กœ ์ž‘์„ฑํ•œ๋‹ค. ํ•ด๋‹น ๋ถ€๋ถ„์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด, naver-checkstyle-rules.xml ํŒŒ์ผ์˜ ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

โ—ผ ๋งŒ๋“ค์–ด์ง„ Configuration์„ Activeํ•˜๊ณ  ์™„๋ฃŒํ•œ๋‹ค.

 

 

โ—ผ ์ธํ…”๋ฆฌ์ œ์ด ํ•˜๋‹จ์„ ๋ณด๋ฉด CheckStyle ํƒญ์ด ์žˆ๊ณ , ํ•ด๋‹น ๋ถ€๋ถ„์„ ํด๋ฆญํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ๋‚˜์˜จ๋‹ค.

โ—ผ Rules๋ฅผ ์ด์ „์— ์„ค์ •ํ–ˆ๋˜ ํŒŒ์ผ๋กœ ๋งž์ถฐ์ฃผ๊ณ , ์™ผ์ชฝ์— Start ์•„์ด์ฝ˜์„ ํด๋ฆญํ•˜๋ฉด CheckStyle์ด ์ง„ํ–‰๋œ๋‹ค.

 

๐Ÿ’ฌ ์œ„์˜ ์ธํ…”๋ฆฌ์ œ์ด ์„ค์ •์€ ์•ˆํ•ด๋„ ํ„ฐ๋ฏธ๋„์—์„œ ./gradlew clean build ์‹œ CheckStyle์ด ์ง„ํ–‰๋˜๊ณ  ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด build๊ฐ€ ์‹คํŒจ๋œ๋‹ค.

 

โœ” ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ํŒŒ์ผ Save ์‹œ, ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ์ฝ”๋“œ ๋ณ€๊ฒฝํ•˜๊ธฐ

โ—ผ Editor -> Code Style -> Java์—์„œ IntelliJ IDEA code style XML์„ ํด๋ฆญํ•œ๋‹ค.

 

โ—ผ ์œ„ ๊นƒํ—ˆ๋ธŒ ๋งํฌ์—์„œ naver-intellij-formatter.xml ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•œ ๋’ค ์„ค์ •ํ•œ๋‹ค.

 

โ—ผ Save Actions ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•œ๋‹ค.

 

โ—ผ Settings -> Other Settings -> Save Actions์—์„œ ์œ„์™€ ๊ฐ™์ด ์ฒดํฌํ•œ๋‹ค.

โ—ผ ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ฉด, ์ฝ”๋“œ ์ž‘์„ฑ ํ›„ Save ์‹œ ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค.

 

โœ” ํ”„๋กœ์ ํŠธ์—์„œ ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ํ•œ ๋ฒˆ์— ์ฝ”๋“œ ๋ณ€๊ฒฝ์‹œํ‚ค๊ธฐ

โ—ผ ๋ฃจํŠธ ํ”„๋กœ์ ํŠธ ์šฐํด๋ฆญ ํ›„, Reformat Code๋ฅผ ์„ ํƒํ•œ๋‹ค.

 

โ—ผ Optimize imports๋ฅผ ์„ ํƒํ•˜๊ณ  Run์„ ๋ˆ„๋ฅด๋ฉด ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ํ”„๋กœ์ ํŠธ ๋‚ด, ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค.


๐Ÿ“’ .gitattributes ํŒŒ์ผ ์„ค์ •

* text=auto

*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.bat text merge=union eol=crlf

โ—ผ .gitattributes ์„ค์ •์„ ํ†ตํ•ด git ์ €์žฅ ์‹œ, ํ…์ŠคํŠธ ๋ฐ ์ง€์ • ํŒŒ์ผ์˜ ํ˜•์‹์„ ์•Œ๋งž๊ฒŒ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝํ•˜์ž.

๐Ÿ’ฌ LF์™€ CRLF ์ฐจ์ด์ 

โ—ผ LF(Line Feed)๋Š” ์ค„ ๋ฐ”๊ฟˆ์— ์žˆ์–ด, ์ปค์„œ์˜ ์œ„์น˜ ์ด๋™์€ ์ œ์™ธํ•˜๊ณ , ์ค„ ๋ฐ”๊ฟˆ๋งŒ ๋˜๋Š” ๋ฌธ์ž์ด๋‹ค.

โ—ผ CRLF(Carriage Return Line Feed)๋Š” ์ปค์„œ์˜ ์œ„์น˜ ์ด๋™๊ณผ ์ค„ ๋ฐ”๊ฟˆ์ด ํ•ฉ์ณ์ ธ์„œ ์‹œํ–‰๋˜๋Š” ๋ฌธ์ž์ด๋‹ค.

๐Ÿ’ฅ CRLF๋Š” Windows์—์„œ LF๋Š” Unix ๊ณ„์—ด์—์„œ ๊ธฐ๋ณธ ๊ฐœํ–‰ ๋ฌธ์ž๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 

โœจ Reference

https://creampuffy.tistory.com/128