Skip to content

Latest commit

ย 

History

History
364 lines (256 loc) ยท 17.4 KB

README_KR.md

File metadata and controls

364 lines (256 loc) ยท 17.4 KB

SwiftLint

SwiftLint๋Š” ์Šค์œ„ํ”„ํŠธ ์Šคํƒ€์ผ ๋ฐ ์ปจ๋ฒค์…˜์„ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋กœ, Kodeco ์Šค์œ„ํ”„ํŠธ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ์— ๋Œ€๋žต์ ์ธ ๊ธฐ๋ฐ˜์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

SwiftLint๋Š” ์ข€ ๋” ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์œ„ํ•ด Clang๊ณผ SourceKit์— ์—ฐ๊ฒฐํ•˜์—ฌ ์†Œ์Šค ํŒŒ์ผ์˜ AST ํ‘œํ˜„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Build Status codecov.io

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” Contributor Covenant Code of Conduct๋ฅผ ์ถฉ์‹คํžˆ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ์— ์ฐธ์—ฌํ•จ์œผ๋กœ์จ ์ด๋Ÿฌํ•œ ์ˆ˜์น™์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์—†๋Š” ํ•ญ๋ชฉ์ด ์žˆ๋‹ค๋ฉด [email protected]๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”.

์„ค์น˜ ๋ฐฉ๋ฒ•

Homebrew๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

brew install swiftlint

CocoaPods๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

Podfile์— ์•„๋ž˜ ๋ผ์ธ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

pod 'SwiftLint'

์ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๋ฒˆ pod install ์‹คํ–‰ ์‹œ SwiftLint ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ Pods/์— ์žˆ๋Š” ๋””ํŽœ๋˜์‹œ๋“ค์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ , Script Build Phases์—์„œ ${PODS_ROOT}/SwiftLint/swiftlint ๋ช…๋ น์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

CocoaPods๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ตœ์‹  ๋ฒ„์ „ ์™ธ์—๋„ SwiftLint์˜ ํŠน์ • ๋ฒ„์ „์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. (Homebrew๋Š” ์ตœ์‹  ๋ฒ„์ „๋งŒ ์„ค์น˜ ๊ฐ€๋Šฅ)

์ด๋ ‡๊ฒŒ ํ–ˆ์„ ๋•Œ SwiftLint ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ ๊ทธ์— ์ข…์†๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋“ค๊ณผ ์Šค์œ„ํ”„ํŠธ ๋ฐ”์ด๋„ˆ๋ฆฌ๊นŒ์ง€ Pods/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ถ”๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์—, git ๋“ฑ์˜ SCM์— ์ด๋Ÿฐ ๋””๋ ‰ํ„ฐ๋ฆฌ๋“ค์„ ์ฒดํฌ์ธํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Mint๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

$ mint install realm/SwiftLint

๋นŒ๋“œ๋œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

์ตœ์‹  ๊นƒํ—ˆ๋ธŒ ๋ฆด๋ฆฌ์ฆˆ์—์„œ SwiftLint.pkg๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์„œ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†Œ์Šค๋ฅผ ์ง์ ‘ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒฝ์šฐ:

๋ณธ ํ”„๋กœ์ ํŠธ๋ฅผ ํด๋ก ํ•ด์„œ ๋นŒ๋“œํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. make install ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (Xcode 12.5 ์ดํ›„ ๋ฒ„์ „)

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

ํ”„๋ ˆ์  ํ…Œ์ด์…˜

ํ”„๋กœ์ ํŠธ์— SwiftLint๋ฅผ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ถŒ์žฅ ์‚ฌ์šฉ ๋ฐฉ์‹์˜ ์ „๋ฐ˜์ ์ธ ๊ฐœ์š”๋ฅผ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ์˜์ƒ์„ ๋ณด๊ฑฐ๋‚˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฝ์–ด๋ณด๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.

Presentation

Xcode

SwiftLint๋ฅผ Xcode ํ”„๋กœ์ ํŠธ์— ํ†ตํ•ฉํ•˜์—ฌ IDE ์ƒ์— ๊ฒฝ๊ณ ๋‚˜ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ํŒŒ์ผ ๋‚ด๋น„๊ฒŒ์ดํ„ฐ์—์„œ ํƒ€๊ฒŸ ์•ฑ์„ ์„ ํƒ ํ›„ "Build Phases" ํƒญ์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. + ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ํ›„ "Run Script Phase"๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„ ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

if which swiftlint >/dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

๋งŒ์•ฝ, ์• ํ”Œ ์‹ค๋ฆฌ์ฝ˜ ํ™˜๊ฒฝ์—์„œ Homebrew๋ฅผ ํ†ตํ•ด SwiftLint๋ฅผ ์„ค์น˜ํ–ˆ๋‹ค๋ฉด, ์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ ๋ฅผ ๊ฒช์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint

๊ทธ ์ด์œ ๋Š”, ์• ํ”Œ ์‹ค๋ฆฌ์ฝ˜ ๊ธฐ๋ฐ˜ ๋งฅ์—์„œ Homebrew๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ”์ด๋„ˆ๋ฆฌ๋“ค์„ /opt/homebrew/bin์— ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. SwiftLint๊ฐ€ ์–ด๋”” ์žˆ๋Š”์ง€ ์ฐพ๋Š” ๊ฒƒ์„ Xcode์— ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด, build phase์—์„œ /opt/homebrew/bin๋ฅผ PATH ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ๋™์‹œ์— ์ถ”๊ฐ€ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if [[ "$(uname -m)" == arm64 ]]; then
    export PATH="/opt/homebrew/bin:$PATH"
fi

if which swiftlint > /dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

ํ˜น์€ ์•„๋ž˜์™€ ๊ฐ™์ด /usr/local/bin์— ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ณณ์œผ๋กœ ํฌ์ธํŒ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. :

ln -s /opt/homebrew/bin/swiftlint /usr/local/bin/swiftlint

๋‹น์‹ ์€ SwiftLint phase๋ฅผ 'Compile Sources' ๋‹จ๊ณ„ ์ง์ „์œผ๋กœ ์˜ฎ๊ฒจ ์ปดํŒŒ์ผ ์ „์— ์—๋Ÿฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ณ  ์‹ถ์–ด ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, SwiftLint๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๊ตฌ๋ฌธ ๋ถ„์„ ๋‹จ๊ณ„๋ฅผ ์™„๋ฒฝํžˆ ์ˆ˜ํ–‰ํ•˜๋Š” ์œ ํšจํ•œ Swift ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, 'Compile Sources' ์ „์— SwiftLint๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ผ๋ถ€ ๋ถ€์ •ํ™•ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋‹น์‹ ์€ ์œ„๋ฐ˜ ์‚ฌํ•ญ(violations)์„ ๋™์‹œ์— ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์„ ์›ํ•œ๋‹ค๋ฉด, ์Šคํฌ๋ฆฝํŠธ์— swiftlint ๋Œ€์‹  swiftlint --fix && swiftlint์„ ์ ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ”„๋กœ์ ํŠธ์˜ ์ˆ˜์ • ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์œ„๋ฐ˜ ์‚ฌํ•ญ๋“ค์ด ์ˆ˜์ •๋˜๊ณ  ๋‚˜๋จธ์ง€ ์œ„๋ฐ˜ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

CocoaPods๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ๋Š” ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

"${PODS_ROOT}/SwiftLint/swiftlint"

Xcode ์ €์žฅ์‹œ ์‹คํ–‰๋˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ

Xcode์—์„œ ์ €์žฅ์‹œ swiftlint autocorrect๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด Alcatraz์—์„œ SwiftLintXcode ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

โš  ๏ธ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ Xcode 8์—์„œ SIP๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ด๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

AppCode

AppCode์—์„œ SwiftLint๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๊ณ  ํ”Œ๋Ÿฌ๊ทธ์ธ ํ™˜๊ฒฝ์„ค์ •์—์„œ SwiftLint๊ฐ€ ์„ค์น˜๋œ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค. autocorrect ์•ก์…˜์€ โŒฅโŽ ๋‹จ์ถ•ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Atom

Atom์—์„œ SwiftLint๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด APM์—์„œ linter-swiftlint ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

fastlane

fastlane ๊ณผ์ •์—์„œ SwiftLint๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ณต์‹์ ์ธ fastlane ์•ก์…˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

swiftlint(
  mode: :lint,                            # SwiftLint ๋ชจ๋“œ: :lint (๋””ํดํŠธ) ์•„๋‹ˆ๋ฉด :autocorrect
 ย executable: "Pods/SwiftLint/swiftlint", # SwiftLint ๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฒฝ๋กœ (์„ ํƒ ๊ฐ€๋Šฅ). CocoaPods๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ๋Š” ์ด ์˜ต์…˜์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค
 ย output_file: "swiftlint.result.json",   # ๊ฒฐ๊ณผ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ (์„ ํƒ ๊ฐ€๋Šฅ)
 ย reporter: "json",                       # ๋ณด๊ณ  ์œ ํ˜• (์„ ํƒ ๊ฐ€๋Šฅ)
 ย config_file: ".swiftlint-ci.yml", ย  ย    # ์„ค์ • ํŒŒ์ผ์˜ ๊ฒฝ๋กœ (์„ ํƒ ๊ฐ€๋Šฅ)
  ignore_exit_status: true                # SwiftLint ์ข…๋ฃŒํ•  ๋•Œ 0์ด ์•„๋‹Œ ๋ฐ˜ํ™˜ํ•œ ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ๋ฌด์‹œํ•ด์„œ fastlane ๊ณ„์† ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค
)

์ปค๋งจ๋“œ ๋ผ์ธ

$ swiftlint help
Available commands:

   autocorrect  Automatically correct warnings and errors
   help         Display general or command-specific help
   lint         Print lint warnings and errors for the Swift files in the current directory (default command)
   rules        Display the list of rules and their identifiers
   version      Display the current version of SwiftLint

์Šค์œ„ํ”„ํŠธ ํŒŒ์ผ์ด ์žˆ๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ swiftlint๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ์žฌ๊ท€์ ์œผ๋กœ ํƒ์ƒ‰๋ฉ๋‹ˆ๋‹ค.

lint๋‚˜ autocorrect๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์—ฌ๋Ÿฌ ํŒŒ์ผ(์˜ˆ๋ฅผ ๋“ค๋ฉด, ExtraBuildPhase ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์˜ํ•ด Xcode๊ฐ€ ๋ณ€๊ฒฝํ•œ ํŒŒ์ผ๋“ค ํ˜น์€ git ls-files -m ๋ช…๋ น์œผ๋กœ ์ธํ•ด ์ž‘์—… ํŠธ๋ฆฌ์—์„œ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ๋“ค)์„ ์ง€์ •ํ•˜๋ ค๋ฉด --use-script-input-files ์˜ต์…˜์„ ๋„˜๊ธฐ๊ณ  ๋‹ค์Œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์„ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. SCRIPT_INPUT_FILE_COUNT and SCRIPT_INPUT_FILE_0, SCRIPT_INPUT_FILE_1...SCRIPT_INPUT_FILE_{SCRIPT_INPUT_FILE_COUNT - 1}

์ด๋Š” Xcode์˜ ์ปค์Šคํ…€ ์Šคํฌ๋ฆฝํŠธ ๋‹จ๊ณ„์— ์ž…๋ ฅ ํŒŒ์ผ๋กœ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์Šค์œ„ํ”„ํŠธ ์—ฌ๋Ÿฌ ๋ฒ„์ „์— ๋Œ€ํ•œ ๋Œ€์‘

SwiftLint๋Š” SourceKit์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์Šค์œ„ํ”„ํŠธ ์–ธ์–ด๊ฐ€ ๋ณ€ํ™”ํ•˜๋”๋ผ๋„ ์ด์ƒ ์—†์ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” ์ „์ฒด ์Šค์œ„ํ”„ํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ SwiftLint๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์œ ์ง€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SwiftLint๋Š” ๋ฐ์Šคํฌํƒ‘์— ์ด๋ฏธ ์„ค์น˜๋˜์–ด ์žˆ๋Š” ๊ณต์‹ ์Šค์œ„ํ”„ํŠธ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ†ต์‹ ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

SwiftLint๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” ํ•ญ์ƒ ์Šค์œ„ํ”„ํŠธ ํŒŒ์ผ์„ ์ปดํŒŒ์ผํ•˜๋Š” ๋™์ผํ•œ ํˆด์ฒด์ธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„ค์น˜๋œ ํˆด์ฒด์ธ์ด๋‚˜ Xcode๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ ํ˜น์€ ์Šค์œ„ํ”„ํŠธ ๊ตฌ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ(Xcode 8์—์„œ ์Šค์œ„ํ”„ํŠธ 2.3 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ)์—๋Š” SwiftLint์˜ ๊ธฐ๋ณธ ์Šค์œ„ํ”„ํŠธ ํˆด์ฒด์ธ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

SwiftLint๊ฐ€ ์–ด๋Š ์Šค์œ„ํ”„ํŠธ ํˆด์ฒด์ธ์„ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์ˆœ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • $XCODE_DEFAULT_TOOLCHAIN_OVERRIDE
  • $TOOLCHAIN_DIR or $TOOLCHAINS
  • xcrun -find swift
  • /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • ~/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • ~/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain

sourcekitd.framework์€ ์œ„์—์„œ ์„ ํƒ๋œ ๊ฒฝ๋กœ์˜ usr/lib/ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

TOOLCHAINS ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ์Šค์œ„ํ”„ํŠธ ํˆด์ฒด์ธ ๋ฒ„์ „์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ๋ฆฌ๋ฒ„์Šค DNS ํ˜•์‹์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

$ TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 swiftlint autocorrect

๋ฆฌ๋ˆ…์Šค์—์„œ๋Š” SourceKit์ด /usr/lib/libsourcekitdInProc.so ํ˜น์€ LINUX_SOURCEKIT_LIB_PATH ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ๊ฒฝ๋กœ์— ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฃฐ

SwiftLint์—๋Š” 200๊ฐœ๊ฐ€ ๋„˜๋Š” ๋ฃฐ๋“ค์ด ์žˆ๊ณ , ์Šค์œ„ํ”„ํŠธ ์ปค๋ฎค๋‹ˆํ‹ฐ(๋ฐ”๋กœ ์—ฌ๋Ÿฌ๋ถ„๋“ค!)๋Š” ์ด๋ฅผ ์ง€์†์ ์œผ๋กœ ๋ฐœ์ „์‹œ์ผœ ๊ฐ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋Š” ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ตฌํ˜„๋œ ๋ฃฐ ์ „์ฒด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด Source/SwiftLintBuiltInRules/Rules๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”.

opt_in_rules๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. (์ฆ‰, ์„ค์ • ํŒŒ์ผ์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด๋‹น ๋ฃฐ์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

๋‹ค์Œ์€ ๋ฃฐ์„ ์˜ตํŠธ ์ธ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.

  • ์ž˜๋ชป ํŒ๋‹จ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋งŽ์€ ๋ฃฐ (์˜ˆ: empty_count)
  • ์†๋„๊ฐ€ ๋งค์šฐ ๋Š๋ฆฐ ๋ฃฐ
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ํ•ฉ์˜ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํŠน์ •ํ•œ ์ƒํ™ฉ์—๋งŒ ์œ ์šฉํ•œ ๋ฃฐ (์˜ˆ: force_unwrapping, missing_docs)

์ฝ”๋“œ์—์„œ ๋ฃฐ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ธฐ

์†Œ์Šค ํŒŒ์ผ์—์„œ ์•„๋ž˜ ํ˜•์‹์˜ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฃฐ์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// swiftlint:disable <๋ฃฐ1> [<๋ฃฐ2> <๋ฃฐ3>...]

๋น„ํ™œ์„ฑํ™”๋œ ๋ฃฐ์€ ํ•ด๋‹น ํŒŒ์ผ์˜ ๋งˆ์ง€๋ง‰๊นŒ์ง€ ์ ์šฉ๋˜๊ฑฐ๋‚˜, ํ™œ์„ฑํ™” ์ฃผ์„์ด ๋‚˜ํƒ€๋‚  ๋•Œ๊นŒ์ง€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

// swiftlint:enable <๋ฃฐ1> [<๋ฃฐ2> <๋ฃฐ3>...]

์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// swiftlint:disable colon
let noWarning :String = "" // ๋ณ€์ˆ˜๋ช… ๋ฐ”๋กœ ๋’ค์— ์ฝœ๋ก ์ด ์œ„์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฒฝ๊ณ ๊ฐ€ ๋œจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค!
// swiftlint:enable colon
let hasWarning :String = "" // ๋ณ€์ˆ˜๋ช… ๋ฐ”๋กœ ๋’ค์— ์ฝœ๋ก ์ด ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

disable๊ณผ enable ๋ช…๋ น ๋’ค์— :previous, :this, :next๋ฅผ ๋ถ™์ด๋ฉด ๊ฐ๊ฐ ๋ช…๋ น์ด ์œ„์น˜ํ•œ ์ด์ „ ๋ผ์ธ, ํ˜„์žฌ ๋ผ์ธ, ๋‹ค์Œ ๋ผ์ธ๋งŒ ๋ฃฐ์ด ์ ์šฉ๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// swiftlint:disable:next force_cast
let noWarning = NSNumber() as! Int
let hasWarning = NSNumber() as! Int
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast
let noWarning3 = NSNumber() as! Int
// swiftlint:disable:previous force_cast

swiftlint rules๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ชจ๋“  ๋ฃฐ ๋ชฉ๋ก๊ณผ ๋ฃฐ๋ณ„ ์‹๋ณ„์ž๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์„ค์ •

SwiftLint๊ฐ€ ์‹คํ–‰๋  ๋””๋ ‰ํ„ฐ๋ฆฌ์— .swiftlint.yml ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์„œ SwiftLint๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ์„ค์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ฃฐ ์ ์šฉ์—ฌ๋ถ€ ์„ค์ •:

  • disabled_rules: ๊ธฐ๋ณธ ํ™œ์„ฑํ™”๋œ ๋ฃฐ ์ค‘์— ๋น„ํ™œ์„ฑํ™”ํ•  ๋ฃฐ๋“ค์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • opt_in_rules: ๊ธฐ๋ณธ ๋ฃฐ์ด ์•„๋‹Œ ๋ฃฐ๋“ค์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • only_rules: ์ง€์ •ํ•œ ๋ฃฐ๋“ค๋งŒ ํ™œ์„ฑํ™”๋˜๋„๋ก ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. disabled_rules ๋ฐ opt_in_rules๊ณผ๋Š” ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
disabled_rules: # ์‹คํ–‰์—์„œ ์ œ์™ธํ•  ๋ฃฐ ์‹๋ณ„์ž๋“ค
  - colon
  - comma
  - control_statement
opt_in_rules: # ์ผ๋ถ€ ๋ฃฐ์€ ์˜ตํŠธ ์ธ ํ˜•ํƒœ๋กœ ์ œ๊ณต
  - empty_count
  - missing_docs
  # ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋ฃฐ์€ swiftlint rules ๋ช…๋ น์œผ๋กœ ํ™•์ธ ๊ฐ€๋Šฅ
included: # ๋ฆฐํŠธ ๊ณผ์ •์— ํฌํ•จํ•  ํŒŒ์ผ ๊ฒฝ๋กœ. ์ด ํ•ญ๋ชฉ์ด ์กด์žฌํ•˜๋ฉด `--path`๋Š” ๋ฌด์‹œ๋จ
  - Sources
excluded: # ๋ฆฐํŠธ ๊ณผ์ •์—์„œ ๋ฌด์‹œํ•  ํŒŒ์ผ ๊ฒฝ๋กœ. `included`๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„ ๋†’์Œ
  - Carthage
  - Pods
  - Sources/ExcludedFolder
  - Sources/ExcludedFile.swift

# ์„ค์ • ๊ฐ€๋Šฅํ•œ ๋ฃฐ์€ ์ด ์„ค์ • ํŒŒ์ผ์—์„œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅ
# ๊ฒฝ๊ณ ๋‚˜ ์—๋Ÿฌ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฃฐ์€ ์œ„๋ฐ˜ ์ˆ˜์ค€์„ ์„ค์ • ๊ฐ€๋Šฅ
force_cast: warning # ์•”์‹œ์ ์œผ๋กœ ์ง€์ •
force_try:
  severity: warning # ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •
# ๊ฒฝ๊ณ  ๋ฐ ์—๋Ÿฌ ๋‘˜ ๋‹ค ์กด์žฌํ•˜๋Š” ๋ฃฐ์˜ ๊ฒฝ์šฐ ๊ฐ’์„ ํ•˜๋‚˜๋งŒ ์ง€์ •ํ•˜๋ฉด ์•”์‹œ์ ์œผ๋กœ ๊ฒฝ๊ณ  ์ˆ˜์ค€์— ์„ค์ •๋จ
line_length: 110
# ๊ฐ’์„ ๋‚˜์—ดํ•ด์„œ ์•”์‹œ์ ์œผ๋กœ ์–‘์ชฝ ๋‹ค ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ
type_body_length:
  - 300 # ๊ฒฝ๊ณ 
  - 400 # ์—๋Ÿฌ
# ๋‘˜ ๋‹ค ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Œ
file_length:
  warning: 500
  error: 1200
# ๋„ค์ด๋ฐ ๋ฃฐ์€ ๊ฒฝ๊ณ /์—๋Ÿฌ์— min_length์™€ max_length๋ฅผ ๊ฐ๊ฐ ์„ค์ • ๊ฐ€๋Šฅ
# ์ œ์™ธํ•  ์ด๋ฆ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ
type_name:
  min_length: 4 # ๊ฒฝ๊ณ ์—๋งŒ ์ ์šฉ๋จ
  max_length: # ๊ฒฝ๊ณ ์™€ ์—๋Ÿฌ ๋‘˜ ๋‹ค ์ ์šฉ
    warning: 40
    error: 50
  excluded: iPhone # ์ œ์™ธํ•  ๋ฌธ์ž์—ด ๊ฐ’ ์‚ฌ์šฉ
identifier_name:
  min_length: # min_length์—์„œ
    error: 4 # ์—๋Ÿฌ๋งŒ ์ ์šฉ
  excluded: # ์ œ์™ธํ•  ๋ฌธ์ž์—ด ๋ชฉ๋ก ์‚ฌ์šฉ
    - id
    - URL
    - GlobalAPIKey
reporter: "xcode" # ๋ณด๊ณ  ์œ ํ˜• (xcode, json, csv, codeclimate, checkstyle, junit, html, emoji, sonarqube, markdown, github-actions-logging)

์ปค์Šคํ…€ ๋ฃฐ ์ •์˜

์•„๋ž˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ • ํŒŒ์ผ์— ์ƒˆ๋กœ์šด ์ •๊ทœ ํ‘œํ˜„์‹ ๊ธฐ๋ฐ˜์˜ ๋ฃฐ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

custom_rules:
  pirates_beat_ninjas: # ๋ฃฐ ์‹๋ณ„์ž
    included: ".*.swift" # ๋ฆฐํŠธ ์‹คํ–‰ ์‹œ ํฌํ•จํ•  ๊ฒฝ๋กœ๋ฅผ ์ •์˜ํ•˜๋Š” ์ •๊ทœํ‘œํ˜„์‹. ์„ ํƒ ๊ฐ€๋Šฅ.
    name: "Pirates Beat Ninjas" # ๋ฃฐ ์ด๋ฆ„. ์„ ํƒ ๊ฐ€๋Šฅ.
    regex: "([nN]inja)" # ํŒจํ„ด ๋งค์นญ
    match_kinds: # ๋งค์นญํ•  SyntaxKinds. ์„ ํƒ ๊ฐ€๋Šฅ.
      - comment
      - identifier
    message: "Pirates are better than ninjas." # ์œ„๋ฐ˜ ๋ฉ”์‹œ์ง€. ์„ ํƒ ๊ฐ€๋Šฅ.
    severity: error # ์œ„๋ฐ˜ ์ˆ˜์ค€. ์„ ํƒ ๊ฐ€๋Šฅ.
  no_hiding_in_strings:
    regex: "([nN]inja)"
    match_kinds: string

๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํ•˜๋‚˜ ์ด์ƒ์˜ match_kinds๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งค์นญ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชฉ๋ก์— ๋“ค์–ด์žˆ์ง€ ์•Š์€ ๊ตฌ๋ฌธ ์œ ํ˜•์ด ํฌํ•จ๋œ ๊ฒฐ๊ณผ๋Š” ๋งค์นญ์—์„œ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ตฌ๋ฌธ ์œ ํ˜•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • argument
  • attribute.builtin
  • attribute.id
  • buildconfig.id
  • buildconfig.keyword
  • comment
  • comment.mark
  • comment.url
  • doccomment
  • doccomment.field
  • identifier
  • keyword
  • number
  • objectliteral
  • parameter
  • placeholder
  • string
  • string_interpolation_anchor
  • typeidentifier

์ค‘์ฒฉ ๊ตฌ์„ฑ

SwiftLint๋Š” ์„ค์ • ํŒŒ์ผ์„ ์ค‘์ฒฉ๋˜๊ฒŒ ๊ตฌ์„ฑํ•ด์„œ ๋ฆฐํŠธ ๊ณผ์ •์„ ๋”์šฑ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ์—์„œ ํ•„์š”ํ•œ ๊ณณ์ด๋ฉด ์–ด๋””๋“ ์ง€ .swiftlint.yml ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ ํŒŒ์ผ์€ ์ž์‹ ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด์— ์žˆ๋Š” ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๊ณ„์ธต๊ตฌ์กฐ ์ƒ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด์„œ ๋ฆฐํŠธ๋ฉ๋‹ˆ๋‹ค. ๋ณ„๋„๋กœ ์„ค์ • ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฃจํŠธ์— ์žˆ๋Š” ์„ค์ • ํŒŒ์ผ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์ค‘์ฒฉ ๊ตฌ์„ฑ์—์„œ excluded ๋ฐ included๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

์ž๋™ ์ˆ˜์ •

SwiftLint๋Š” ์ผ๋ถ€ ์œ„๋ฐ˜ ์‚ฌํ•ญ๋“ค์„ ์ž๋™์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””์Šคํฌ ์ƒ์˜ ํŒŒ์ผ๋“ค์€ ์ˆ˜์ •๋œ ๋ฒ„์ „์œผ๋กœ ๋ฎ์–ด ์“ฐ์—ฌ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

swiftlint autocorrect๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ํŒŒ์ผ๋“ค์„ ๋ฐฑ์—…ํ•ด์ฃผ์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์‹ค๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ‘œ์ค€ ๋ฆฐํŠธ ๊ฒ€์‚ฌ๋Š” ์ž๋™ ์ˆ˜์ • ์ค‘์—๋Š” ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์œ„๋ฐ˜ ์‚ฌํ•ญ๋“ค์€ ํŒŒ์ผ์ด ์ž๋™ ์ˆ˜์ •๋œ ํ›„์— ๋”์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ผ์ด์„ ์Šค

MIT ๋ผ์ด์„ ์Šค.

About

SwiftLint๋Š” Realm Inc.์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ ธ์„œ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Realm์˜ ์ด๋ฆ„๊ณผ ๋กœ๊ณ ๋Š” Realm Inc.์˜ ํŠธ๋ ˆ์ด๋“œ ๋งˆํฌ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์˜คํ”ˆ ์†Œ์Šค ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์‚ฌ๋ž‘ํ•ฉ๋‹ˆ๋‹ค:heart:! Realm์˜ ๋‹ค๋ฅธ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์™€ ๋ธ”๋กœ๊ทธ๋“ค๋„ ๋“ค๋Ÿฌ์ฃผ์‹œ๊ณ , ํŠธ์œ„ํ„ฐ(@realm)๋กœ๋„ ๋ฐ˜๊ฐ‘๊ฒŒ ์ธ์‚ฌ ์ฃผ์„ธ์š”.