📕 목차
1. 개요
2. 설치
3. options & rules
1. 개요
자동화에 진심인 나는 인적 리소스를 감소시킬 수 있는 부분이 보이면 어떻게든 자동화 프로세스를 구축하는 미치광이 오토메이터에 가깝다.
하지만 IntelliJ에서 제공해주는 기능은 해봐야 컨벤션을 각자 개발자 환경에서 세팅한 다음에 리팩토링 해주는 정도의 자동화밖에 지원하지 않는다는 아쉬움이 있었다. (Java 코드를 컨벤션에 맞게 리팩토링시키는 extension을 만들어보려고 연구 중..)
그러던 중에 Swift는 SwiftFormat 프레임워크로 빌드 과정에 자동으로 컨벤션에 맞게 리팩토링 시킬 수 있다는 것을 알게 되었다.
단순히 경고를 띄우는 SwiftLint와는 달리 SwiftFormat은 공통 설정을 적용해놓으면, 모든 개발자가 동일한 컨벤션에 따라 자동화 규칙이 적용된다는 특징이 있었다.
재밌는 거 발견했으니 이제 적용해보는 일만 남음!
마침 진행 중인 프로젝트에 iOS 팀이 있어서 해당 프로젝트에 자동화를 적용해주기로 했다.
brew 방식으로 설치하기도 하던데, 나는 cocoa pods를 이용해서 환경을 세팅했다.
2. 설치
📌 pod 추가
pod 'SwiftFormat/CLI'
- SwfitFormat/CLI를 Podfile에 추가하고 pod install을 입력해서 설치한다.
📌 Run script 추가
- Build Phases에 Run Script를 추가하고 Compile source 상단으로 옮긴다. (빌드 순서 조정)
- "${PODS_ROOT}/SwfitFormat/CommandLineTool/swiftformat" "$SRCROOT"를 script에 추가한다.
놀랍게도 이러면 세팅이 끝..빌드하면 리팩토링이 적용된다.
🤔 swiftformat failed to read contents of directory
혹시나 위와 같은 에러가 발생하면 Build Settings의 User Script Sandboxing을 No로 바꾸면 된다.
정확히 뭔지는 모르겠지만, 내가 iOS 개발자는 아니므로 깊게 알아보지는 않았다.
3. options & rules
📌 options & rules
- rules: 어떤 컨벤션을 적용할 지 선택한다. --enable, --disable로 on/off한다.
- options: 활성화된 rule의 세부 설정을 제어한다.
📌 swiftformat cli 사용하기
{Pod 경로}/SwiftFormat/CommandLineTool 로 진입하면 swiftformat을 실행할 수 있다.
- swiftformat --options {rule}: 해당 rule에 적용된 option을 확인, 변경할 수 있다.
- swiftformat --rules: 현재 적용되고 있는 옵션과 적용 가능한 옵션을 출력한다.
- swiftformat --ruleinfo {rule}: rule에 대한 설명을 출력한다.
- swiftformat --rules --disable {option}: rule 비활성
- swiftformat --rules --enable {option}: rule 활성
그런데 Pods는 일반적으로 원격 저장소에 올리지 않는다.
cli로 세팅하면 모든 개발자가 swiftformat을 적용하기 위해 직접 cli를 입력해야 하는데, 이는 굉장히 비효율적인 작업이 되므로 사용할 수 없다.
📌 .swfitformat
프로젝트 경로에 .swiftformat 파일을 만들고 옵션을 설정하면, swfitformat이 build 단계에서 해당 파일을 읽어 설정값으로 사용한다.
즉, .swiftformat만 원격 저장소에 올린다면 개발팀 전원이 동일한 convention으로 swift format을 사용할 수 있게 된다.
초기 설정값 일부를 확인해보면 이렇게 되어 있는데, 만약 그대로 사용할 것이라면 따로 설정할 것이 없다.
하지만 만약 disabled로 처리된 acronyms 기능을 사용하고 싶다면 .swiftformat에 다음과 같이 라인을 추가해주면 된다.
--enable acronyms
만약 enable 되어있는 rule의 option을 바꿔주고 싶은 경우엔 다음과 같이 설정하면 된다.
--ranges no-space
이걸 어디서 보느냐? 위에 올려둔 Rules.md 깃헙 경로에 다 나와있다.
📌 최종 적용한 rules
--swiftversion 5.0
# format options
# file options
--exclude Pods
# rules
--enable acronyms, blankLinesBetweenImports, blockComments, docComments, isEmpty, markTypes,
sortImports, wrapConditionalBodies, wrapMultilineConditionalAssignment
--disable applicationMain, assertionFailures, blankLinesBetweenChainedFunctions, conditionalAssignment,
extensionAccessControl, headerFileName, hoistAwait, modifierOrder, opaqueGenericParameters,
preferKeyPath, redundantBackticks, redundantBreak, redundantClosure, redundantExtensionACL,
redundantGet, redundantInit, redundantInternal, redundantLetError, redundantObjc,
redundantOptionalBinding, redundantRawValues, redundantReturn, redundantStaticSelf,
redundantType, sortTypealiases, strongOutlets, strongifiedSelf, trailingCommas, trailingSpace,
wrapArguments, wrapAttributes, wrapSingleLineComments, yodaConditions
- swiftversion을 명시하지 않아도 빌드는 되지만 경고가 뜬다.
- Pods 경로에 있는 파일은 swift format을 적용시키지 않으므로 --exclude로 제외했다.
- 반영하고 싶은데 기본값으로 disabled 처리된 rule은 --enable로 활성화하고, 반대의 경우에는 --disable 처리했다.
여기까지하고 빌드를 해보면 코드가 모두 리팩토링되는 것을 확인할 수 있다.