프로그래밍에서 lint
또는 linter
는 코드의 잠재적인 문제를 자동으로 찾아주는 도구나 과정을 의미한다. 이 용어는 1978년에 C 프로그래밍 언어에서 코드의 결함을 찾아주는 프로그램을 개발한 스티븐 존슨(Stephen C. Johnson)에 의해 처음 사용되었다. 이 프로그램 이름이 Lint
였고, 이후 다양한 프로그래밍 언어와 환경에서 비슷한 도구를 lint
라고 부르게 되었다고 한다.
Swift에도 SwiftLint
라는 패키지가 있다. 오늘은 이에 대해 알아볼 것.
SwiftLint를 사용하여 코딩 컨벤션을 Rule로 정하면 다음과 같은 이점이 있다.
SwiftLint의 효능
- 코드 품질 향상: 일관된 코딩 스타일을 유지할 수 있고, 잘못된 코드나 잠재적인 버그를 사전에 발견할 수 있다.
- 자동화된 코드 검토: 코드 리뷰 과정에서 스타일 문제나 기본적인 오류를 자동으로 체크해줘서 리뷰어가 중요한 로직에 집중할 수 있다.
- 생산성 향상: 반복적인 스타일 체크 작업을 줄여주며 IDE에서 실시간으로 경고를 확인할 수 있다.
유지보수성 증가: 팀원 간의 코딩 스타일 차이를 줄여주며 코드가 일관되게 유지되어 추후 유지보수나 확장이 쉬워진다. 새로운 팀원이 프로젝트에 합류할 때 코드 스타일을 빠르게 익힐 수 있다.
SPM으로 프로젝트 파일에 추가했다가 뭐가 잘 안돼서 (찾아보니 잘 안된다는 사람들이 많음... swift.packages인가? 그걸 못찾겠다)
spm으로 설치한 패키지 다 지우고 그냥 homebrew로 설치했다.
homebrew가 이미 설치되어 있다고 가정하고,
터미널에
brew install swiftlint
❗️ 설치 오류 해결
참고로 나는 Rosetta로 열기 설정이 되어있어서 처음에 오류가 났는데, finder에서 찾아서 해제해주면 설치가 잘 된다.
- 터미널 아키텍처 확인:
arch
출력이 arm64이면 ARM 모드, i386이면 Rosetta 2 모드이다.
i386이라고 뜬다면 터미널 닫기 -> finder에서 터미널 찾기 -> 정보 가져오기 -> Rosetta를 사용하여 열기 체크 해제 -> 터미널 종료후 다시 열어 install 실행
하면 설치가 잘 될 것이다.
Targets -> Build Phases 가서 + 버튼 클릭 -> New Run Script phases -> 다음 코드 입력
export PATH="$PATH:/opt/homebrew/bin"
if which swiftlint > /dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
빌드 단계에서 SwiftLint가 실행되게 해 주는 단계이다.
이 단계까지 마치면 코드에서 주의 표시를 볼 수 있다(고 하는데 난 오류가 계속 나서 해결하느라 이 단계 직후를 못봤다)
프로젝트 파일 단계(최상단) 에서 New File 클릭
맨 밑에 있는 Other -> Empty 생성해주고 이름은 .swiftlint.yml
로 지정
이런 경고창이 뜨는데 오른쪽의 '. 사용' 눌러주면 된다.
공식 문서에 있는걸 갖다붙였더니 실행이 안돼서...
여기 블로그에 있는 조건들을 가져왔다. 룰에 대한 설명이 잘 되어있어서 추후 조건 작성할 때 참고하려고 북마크...
--- # 문서의 시작
# 기본 적용되는 룰에서 사용하지 않는 룰
disabled_rules:
- trailing_whitespace # 후행 공백 (선행 공백과 더불어 필요없다고 미적용이 불필요하다고 생각됨) - 선택 필요
- nesting # 중첩
- vertical_whitespace # 세로 공백
- redundant_optional_initialization # 옵셔널 타입을 nil로 초기화 중복
- unused_closure_parameter # 미사용 클로저 파라미터 _ 대체
- syntactic_sugar # 간결한 표현 (Array 대신 [Int] 등의 표현)
- cyclomatic_complexity # 순환 복잡성
- type_body_length # 타입 본문의 행 길이 제한
- file_length # 파일 줄 길이 제한
- unused_optional_binding # 사용되지 않는 옵셔널 바인딩 제한
- function_parameter_count # 파라미터 갯수 제한
- function_body_length # 함수 본문의 행 길이 제한
- large_tuple # 튜플 인자 수 제한
- unused_control_flow_label # 미사용 제어 플로우 제거
- trailing_comma # 배열 및 딕셔너리에서 후행 쉼표 조건 (적용 혹은 미적용)
- opening_brace # 중괄호 선언 조건 (중괄호 앞 단일 공백 및 선언과 같은 행)
- closure_parameter_position # 클로저 매개변수 위치 (중괄호와 같은 행)
- for_where # for where 절 선호 (for 문 내 if 사용 대체)
- inclusive_language # 포괄적 언어 사용 (인종, 성별, 사회경제적 지위를 나타내는 언어 사용금지)
- statement_position # 구문 위치 제한 (else, catch 등이 선언 바로 뒤 한칸 공백 후 위치함) - 선택 필요
- todo # TODO, FIXME 주석 제한
# 옵트 인 룰
opt_in_rules:
- indentation_width # 인덴트 룰 적용
- closure_end_indentation # 클로저의 끝 괄호를 시작한 행과의 들여쓰기 맞춤
- empty_count # count보다 isEmpty 선호
- empty_string # == ""보다 isEmpty 선호
- sorted_imports # import 시 알파벳 순 정렬
- used_import # 사용되지 않는 모듈 import 알림
# 인덴트 커스텀 정의
indentation_width:
indentation_width: 2
include_comments: false
# 타입 네이밍 커스텀 정의
type_name:
min_length:
warning: 1
max_length:
warning: 120
allowed_symbols:
- _
# 식별자 네이밍 커스텀 정의
identifier_name:
min_length:
warning: 0
error: 0
max_length:
warning: 120
error: 120
allowed_symbols:
- $
- _
# 콜론 커스텀 정의
colon:
apply_to_dictionaries: false # 딕셔너리에서 콜론이 키 옆에 있어야 하는 룰 미적용
# 행 길이 커스텀 정의
line_length:
ignores_urls: true # URL에 대해 행 길이 제한 미적용
ignores_comments: true # 코멘트에 대해 행 길이 제한 미적용
ignores_interpolated_strings: true # 보간된 문자열 행 길이 제한 미적용
# 룰 적용 제외할 파일
excluded:
- Pods
- LintTest/AppDelegate.swift
- LintTest/SceneDelegate.swift
... # 문서의 끝
설정이 잘 되었다면 다음과 같이 주의창이 마구마구 뜬다.
주의창을 보고 이렇게 행복했던 적은 처음...
SPM설치 -> 실패
공식문서 조건으로 썼더니 -> 실패 (이게 이유인줄 모르고 계속 다른거 건드림..)
등등 해서 시간을 많이 버렸더니 실행됐을때 기분이 아주 좋았다.
Sandbox: swiftlint(64002) deny(1) file-read-data
이런 오류가 떴다. 뭔가 파일에 접근을 못하고 있는 것 같은 오류...
Xcode 버전이 업그레이드 되면서 User Script Sandbox가 기본 Yes로 설정되었다고 하는 것 같은데, 이걸 No로 바꿔주면 실행이 잘 된다.
참고: 샌드박싱(Sandboxing) 이란?
샌드박싱은 애플리케이션이 보안상의 이유로 특정 시스템 자원에 접근하는 것을 제한하는 메커니즘이다. Xcode에서는 빌드 과정 중에 실행되는 사용자 스크립트에도 이러한 샌드박싱 정책을 적용할 수 있고, 이 경우 스크립트는 제한된 파일 시스템 접근 권한만 갖게 된다.즉 샌드박싱이 활성화된 상태에서는 스크립트가 파일 시스템 접근 권한을 얻지 못해, 특정 파일을 읽으려고 할 때 접근이 거부될 수 있다는 것이다. 특히, SwiftLint 설정 파일인 .swiftlint.yml을 읽지 못해서 발생하는 문제가 있을 수 있다고 한다.
이렇게 설정해주면 (아마) 잘 보일것이다!!