프로젝트에 새로운 모듈을 추가하거나 tuist generate, tuist clean, tuist build 등을 반복적으로 타이핑하다 보면 꽤 귀찮아져서....
그래서 자주 사용하는 명령어들을 묶고, 모듈 템플릿 기반으로 자동 생성할 수 있도록 간단한 CLI 도구를 만들어봤습니다.
이번 글에서는 tuisttool.swift 라는 이름의 커맨드라인 도구를 어떻게 만들었는지, 어떤 기능들을 넣었는지 정리해본다.
나만의 모듈 자동 생성기이자 Tuist의 부족한 CLI 도우미 역할을 톡톡히 해줄 수 있습니다.
tuist generate, fetch, clean, reset 등을 빠르게 실행할 수 있는 CLIModules.swift, SPM.swift를 파싱해 자동으로 의존성 선택./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 + Tuist 캐시 제거 후 generate
./tuisttool.swift moduleinit # 새로운 모듈 scaffold + 의존성 자동 삽입
run()과 runCapture()로 쉘 명령 실행func run(_ command: String, arguments: [String] = []) -> Int32
func runCapture(_ command: String, arguments: [String] = []) throws -> String
단순 실행만 필요한 경우 run()을, 결과 값을 받아야 할 경우 runCapture()를 사용합니다.
let moduleInput = prompt("모듈 이름 입력")
let moduleName = prompt("생성할 이름 입력")
그리고 의존성은 아래처럼 내부 모듈 또는 SPM 중 선택할 수 있도록 구현했습니다.
Extension+TargetDependencySPM.swift를 파싱Modules.swift에서 enum을 파싱하여 enum case 리스트를 출력let result = run("tuist", arguments: [
"scaffold", "Module",
"--layer", layer,
"--name", moduleName,
"--author", author,
"--current-date", currentDate
])
모듈 타입(Presentation, Shared, Core/Domain 등)에 따라 자동으로 layer를 지정해줍니다.
if var content = try? String(contentsOfFile: projectFile),
let range = content.range(of: "dependencies: [") {
...
content.insert(contentsOf: " .SPM.alerter", at: insertIndex)
}
Projects/Core/Domain/MyModule/Interface/Sources/Base.swiftProjects/
└── Core/
└── Domain/
└── MyFeature/
├── Interface/
│ └── Sources/
│ └── Base.swift
└── Sources/
모듈 스캐폴딩이 잦아지다 보면 반복되는 작업을 도구화하는 게 필수가 된다고 생각이 듭니다.
Tuist의 장점은 이미 구조화가 잘 되어 있다는 것이고, 그걸 기반으로 나만의 CLI 도구를 곁들이면 생산성을 훨씬 높일 수 있습니다.
앞으로도 이 도구는 지속적으로 고도화해볼 예정이고, 같은 구조를 쓰는 팀원들이라면 함께 써도 좋을 것 같습니다 .