당근마켓) XcodeGen 에서 Tuist 로 전환하기

Kanghoon
당근 테크 블로그
7 min readMay 31, 2021

오늘은 당근마켓 iOS 프로젝트 구성 툴을 XcodeGen 에서 Tuist 로 전환하게 된 이야기를 해보려고 합니다.

Tuist 는 Swift 로 작성된 Xcode 관리 툴입니다. XcodeGen 과 비슷한 점이 많지만 프로젝트 구성을 Swift 파일로 작성할 수 있고 편의 기능이 더 많다는 특징이 있습니다.

기존 프로젝트

먼저 기존의 당근마켓 프로젝트 구성에 대한 이야기를 해보면 좋을 것 같습니다.

당근마켓 iOS 프로젝트에는 XcodeGen 이 적용되어 있고, 메인 프로젝트인 Karrot 프로젝트에 앱 타겟을 포함해 분리된 모듈들을 타겟으로 가지고 있습니다. (대략적인 모습은 아래의 이미지와 비슷합니다.)

당근마켓 프로젝트와 비슷하게 구성한 모습

많은 코드들을 별도의 모듈로 분리하게 되면서, 모듈을 한 프로젝트에서 타겟으로 관리하는 것이 불편하게 느껴졌습니다. 기능 단위는 프로젝트로 나뉘는게 더 명시적으로 느껴지기도 했구요.

먼저 기존에 사용하던 XcodeGen 으로 기존의 타겟 모듈들을 프로젝트로 분리하였습니다.

XcodeGen 에서 멀티 프로젝트를 구성하려면 각 프로젝트 별로 project.yml 을 정의한 다음, 프로젝트를 각각 생성해 projectReferences 를 사용해 각 프로젝트를 연결할 수 있습니다.

이 때 각 프로젝트를 의존성 순서대로 생성해야합니다. 당근마켓은 프로젝트 생성에 Makefile 을 활용하고 있었는데 각 프로젝트 생성 코드를 순서대로 작성해야 하니 관리하기 어려워 보였습니다.

또한 프로젝트 생성 결과물은 연결된 Projects 디렉토리를 만들어주는 형태라 예쁘지 않습니다. (중첩에 중첩.. 대략 아래와 같은 모습입니다.)

XcodeGen 의 projectReferences 를 활용한 모습

당근마켓 프로젝트는 xcworkspace 로 구성되어 있어 모든 프로젝트가 노출되는 상황에서 생성된 결과물이 더 복잡해보였고, 고민 끝에 XcodeGen 대신 최근 사이드 프로젝트에서 사용해본 Tuist 를 사용해보기로 결정했습니다.

Tuist 마이그레이션 테스트

먼저 Tuist 도입에 앞서 원하는 프로젝트 구조에 맞게 디렉토리 구조를 변경하고 필요한 파일들을 추가했습니다. 변경된 프로젝트 구조는 아래와 같습니다.

- Workspace.swift
- Tuist
...
- Projects
- App
- AppName
- Sources
- Tests
- Project.swift
- NotificationExtension
- Sources
- Project.swift
- FrameworkA
- Sources
- Tests
- Project.swift

이 다음 프로젝트 구성에 사용할 수 있는 공용 로직들을 Tuist 템플릿화 하고 해당 코드를 이용해 각 프로젝트 코드를 작성했습니다.

$ tuist init --platform ios // 기본 프로젝트 생성
$ tuist edit // Tuist 프로젝트 수정

tuist init 으로 생성된 기본 파일들을 기존 당근마켓 프로젝트로 이전한 다음 tuist edit 을 이용해 템플릿과 각 프로젝트 구성 코드를 작성합니다.

Tuist 는 XcodeGen 과 다르게 tuist generate 명령어 하나면 프로젝트가 뚝딱 만들어졌습니다. 와우~

작업하면서 알게된 Tuist 팁

Tuist 를 테스트하면서 알게된 소소한 정보들을 공유해보려고 합니다.

1. configuration 다루기

XcodeGen 과 다르게 Tuist 에는 기본 설정값이 꽤 많습니다. xcconfig 를 활용하는 경우 Settings 에 defaultSettings 를 none 으로 줘야 기본 빌드 설정들이 비활성화됩니다.
Tuist 에서 프로젝트 타입에 맞게 추천되는 설정을 사용하는 것이 좋아서 recommend 옵션에 제외해야 하는 값을 excluding 로 제외하는 것을 추천합니다.

let project = Project(
name: "name",
settings: Settings(
configurations: [
...
],
defaultSettings: .recommended(excluding: [
"SWIFT_ACTIVE_COMPILATION_CONDITIONS",
])
)
)

2. tuist template 다루기

팀에서 사용하는 설정들을 잘 파악해서 템플릿을 만들면 실제 프로젝트 파일에 들어가는 코드량이 적어집니다. 당근마켓에서는 공통 설정들을 템플릿 함수로 분리하여 각 프로젝트 세팅에는 적은 코드만 작성하고 있습니다.

각 모듈의 path 등을 enum 으로 작성해 자동완성을 활용하는 것도 좋은 방법입니다.

Tuist 테스트 결과

Tuist 생성 결과물 샘플링

Tuist 로 생성한 프로젝트는 제가 원하는 구조와 좀 더 가까웠습니다. (XcodeGen 처럼 의존성을 중첩으로 구성하지 않고 각각의 프로젝트가 병렬로 생성됨)

기존의 yml 과 swift 로 작성한 프로젝트 파일의 가독성은 팀원 개개인 별로 의견이 달랐지만, Tuist 의 ProjectTemplate 을 이용해 코드를 개선하니 swift 로 작성된 프로젝트 파일의 가독성도 많이 좋아졌습니다. (위 2번 사진 참고)

당근마켓에서는 XcodeGen 과 Tuist 두가지를 테스트 해본 뒤 Tuist 를 사용하는 방향으로 결정하였습니다. 커뮤니티가 활성화되어 프로젝트 생성을 제외한 여러 기능들이 개발되고 있다는점, 프로젝트 생성 결과물이 기대하는 방향과 더 가깝다는 점이 근거가 되었습니다.

두가지 툴을 테스트해보는데 3~4시간 정도의 시간만을 사용했을 정도로 XcodeGen 에서 Tuist 로전환하는데 어려움은 없었습니다. XcodeGen 에 불편함을 느끼시는 분들은 Tuist 를 한 번 사용해보셔도 좋을 것 같습니다.

여담

Tuist 에서 서드파티 캐싱 등의 기능을 제공하고 있는데, 이를 활용해보면 생산성에 도움이 될 것 같습니다.

전반적으로 Tuist 에 대해 궁금하신 분들은 위의 글을 읽어보셔도 좋을 것 같습니다.

당근마켓에서는 이처럼 재밌는 일들을 많이 시도하고 있습니다. 글을 읽고 계시는 iOS 개발자분들 중 당근마켓에 합류하고 싶은 분이 계신다면 이메일(ray@daangnpay.com)로 연락주세요 😆

추가로 궁금하신 점들은 댓글이나 이메일로 남겨주세요

--

--