Tuist 모듈 자동화 CLI 자동화 만들기

by DDD
0*ugtLxtdgV9smjdn_


tuisttool.swift 만든 썰 — Tuist 명령어 치다가 손가락 아파서 만듦


이 글을 쓰게 된 계기


안녕하세요! iOS 운영진 서원지입니다 ㅋㅋㅋ


Tuist 쓰다 보면 이런 거 계속 치잖아요:


tuist generate
tuist fetch
tuist clean
tuist generate


하루에 몇 번을 치는지 모르겠어요… 손가락 아파 죽겠음 �


그래서 그냥 CLI 도구를 만들어버렸습니다!




만들고 싶었던 기능들

tuist generate, fetch, clean 등 한 방에 실행

새 모듈 만들 때 의존성 선택지 자동으로 보여주기

Modules.swift, SPM.swift 파싱해서 뭐 있는지 알아서 찾기

도메인 모듈이면 Interface 폴더도 자동 생성



이거 다 구현했어요! ㅋㅋㅋ




명령어 정리


./tuisttool.swift generate # tuist generate
./tuisttool.swift fetch # tuist fetch
./tuisttool.swift build # clean + fetch + generate (한 방에!)
./tuisttool.swift clean # tuist clean
./tuisttool.swift reset # DerivedData + 캐시 싹 지우고 generate
./tuisttool.swift moduleinit # 새 모듈 만들기 + 의존성 자동 삽입


build 이거 진짜 편해요. 세 개 따로 안 쳐도 됨! �




핵심 구현 포인트


1. 쉘 명령 실행하는 함수


func run(_ command: String, arguments: [String] = []) -> Int32
func runCapture(_ command: String, arguments: [String] = []) throws -> String

run(): 그냥 실행만 하면 될 때

runCapture(): 결과 값 받아야 할 때


이거 두 개만 있으면 웬만한 건 다 됨!




2. 모듈 이름이랑 의존성 입력받기


let moduleInput = prompt("모듈 이름 입력")
let moduleName = prompt("생성할 이름 입력")


의존성은 두 가지 방식으로 선택 가능하게 했어요:

SPM: Extension+TargetDependencySPM.swift 파싱해서 목록 보여줌

내부 모듈: Modules.swift에서 enum case 파싱해서 보여줌


직접 타이핑 안 해도 됨! 선택만 하면 됨! �




3. Tuist scaffold 실행


let result = run("tuist", arguments: [
"scaffold", "Module",
"--layer", layer,
"--name", moduleName,
"--author", author,
"--current-date", currentDate
])


모듈 타입(Presentation, Shared, Core/Domain)에 따라 layer 자동 지정!




4. Project.swift에 의존성 자동 삽입


이게 제일 귀찮았던 부분인데요:


if var content = try? String(contentsOfFile: projectFile),
let range = content.range(of: "dependencies: [") {
...
content.insert(contentsOf: " .SPM.alerter", at: insertIndex)
}


모듈 만들고 나서 Project.swift 열어서 의존성 추가하는 거...


이제 자동으로 넣어줌! ㅋㅋㅋ




5. 도메인 모듈이면 Interface 폴더도 자동 생성


도메인 모듈은 Interface 분리하잖아요?


그것도 자동으로 만들어줍니다:



Projects/Core/Domain/MyModule/Interface/Sources/Base.swift



템플릿까지 같이 생성! 손 안 대도 됨!




생성되는 구조


Projects/
└── Core/
└── Domain/
└── MyFeature/
├── Interface/
│ └── Sources/
│ └── Base.swift
└── Sources/


깔끔하죠? ㅋㅋㅋ




삽질 포인트


파일 파싱할 때 주의


Modules.swift 파싱할 때 정규식 잘못 쓰면 이상한 거 잡혀요.


enum case만 정확히 잡으려고 꽤 고생했음 ㅠㅠ


경로 처리


상대 경로 / 절대 경로 헷갈리면 파일 못 찾음.


FileManager.default.currentDirectoryPath 잘 활용하세요!




마무리


모듈 자주 만드는 분들한테 강추예요!


반복 작업 도구화하면 생산성 확 올라감!


Tuist가 구조화 잘 되어 있어서, 거기에 CLI 도구 얹으면 시너지 대박이에요.


팀원들이랑 같이 쓰면 더 좋고요


저도 계속 기능 추가할 예정입니다!


다음 글 예고: Tuist Plugin 만들기 다뤄볼 예정입니다!




작성자: iOS 운영진 서원지


GitHub: https://github.com/Roy-wonji


작가의 이전글[Android] java.io.stream 고찰