SwiftLint는 스위프트 스타일 및 컨벤션을 강제하기 위한 도구로, GitHub 스위프트 스타일 가이드에 대략적인 기반을 두고 있습니다.
SwiftLint는 좀 더 정확한 결과를 위해 Clang과 SourceKit에 연결하여 소스 파일의 AST 표현을 사용합니다.
본 프로젝트는 Contributor Covenant Code of Conduct를 충실히 따릅니다. 본 프로젝트에 참여함으로써 이러한 수칙을 준수해야 합니다. 받아들일 수 없는 항목이 있다면 info@realm.io로 알려주세요.
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
를 다운로드해서 설치하고 실행할 수 있습니다.
본 프로젝트를 클론해서 빌드할 수도 있습니다. git submodule update --init --recursive; make install
명령을 사용합니다. (Xcode 8.0 이후 버전)
프로젝트에 SwiftLint를 통합하기 위한 권장 사용 방식의 전반적인 개요를 알고 싶다면, 아래 프레젠테이션 영상을 보거나 스크립트를 읽어보면 좋습니다.
SwiftLint를 Xcode 스킴에 통합하여 IDE 상에 경고나 에러를 표시할 수 있습니다. "Run Script Phase"를 새로 만들고 아래 스크립트를 추가하기만 하면 됩니다.
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
CocoaPods를 사용해서 설치한 경우는 아래 스크립트를 대신 사용합니다.
"${PODS_ROOT}/SwiftLint/swiftlint"
Xcode에서 저장시 swiftlint autocorrect
를 실행하려면 Alcatraz에서 SwiftLintXcode 플러그인을 설치합니다.
⚠ ️이 플러그인은 Xcode 8에서 SIP를 비활성화하지 않으면 동작하지 않으며, 이는 권장하지 않습니다.
AppCode에서 SwiftLint를 사용하려면 이 플러그인을 설치하고 플러그인 환경설정에서 SwiftLint가 설치된 경로를 지정해줍니다. autocorrect
액션은 ⌥⏎
단축키로 사용할 수 있습니다.
Atom에서 SwiftLint를 사용하려면 APM에서 linter-swiftlint
패키지를 설치합니다.
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}
이는 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에는 75개가 넘는 룰들이 있고, 스위프트 커뮤니티(바로 여러분들!)는 이를 지속적으로 발전시켜 가고 있습니다. 풀 리퀘스트는 언제나 환영입니다.
현재 구현된 룰 전체를 확인하려면 Source/SwiftLintFramework/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
: 기본 룰이 아닌 룰들을 활성화합니다.whitelist_rules
: 지정한 룰들만 활성화되도록 화이트리스트로 지정합니다.disabled_rules
및opt_in_rules
과는 같이 사용할 수 없습니다.
disabled_rules: # 실행에서 제외할 룰 식별자들
- colon
- comma
- control_statement
opt_in_rules: # 일부 룰은 옵트 인 형태로 제공
- empty_count
- missing_docs
# 사용 가능한 모든 룰은 swiftlint rules 명령으로 확인 가능
included: # 린트 과정에 포함할 파일 경로. 이 항목이 존재하면 `--path`는 무시됨
- Source
excluded: # 린트 과정에서 무시할 파일 경로. `included`보다 우선순위 높음
- Carthage
- Pods
- Source/ExcludedFolder
- Source/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, checkstyle, junit, html, emoji, markdown)
아래 문법을 사용하여 설정 파일에 새로운 정규 표현식 기반의 룰을 정의할 수 있습니다.
custom_rules:
pirates_beat_ninjas: # 룰 식별자
included: ".*.swift" # 린트 실행시 포함할 경로를 정의하는 정규표현식. 선택 가능.
name: "Pirates Beat Ninjas" # 룰 이름. 선택 가능.
regex: "([n,N]inja)" # 패턴 매칭
match_kinds: # 매칭할 SyntaxKinds. 선택 가능.
- comment
- identifier
message: "Pirates are better than ninjas." # 위반 메시지. 선택 가능.
severity: error # 위반 수준. 선택 가능.
no_hiding_in_strings:
regex: "([n,N]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
를 실행하기 전에 파일들을 백업해주세요. 그렇지 않으면 중요한 데이터가 유실될 수도 있습니다.
표준 린트 검사는 자동 수정 중에는 비활성화됩니다. 위반 사항들은 파일이 자동 수정된 후에 더이상 유효하지 않을 가능성이 크기 때문입니다.
SwiftLint는 Realm Inc.에 의해 만들어져서 관리되고 있습니다. Realm의 이름과 로고는 Realm Inc.의 트레이드 마크입니다.
우리는 오픈 소스 소프트웨어를 사랑합니다:heart:! Realm의 다른 오픈소스 프로젝트와 블로그들도 들러주시고, 트위터(@realm)로도 반갑게 인사 주세요.