Skip to content

Development

JEONG edited this page Sep 7, 2026 · 1 revision

개발 가이드

Stella 자체를 고칠 때 필요한 것들입니다. 스캔을 돌리는 방법만 필요하다면 설치와 첫 스캔 으로 가세요.

요구 환경

항목
Swift 6.0 이상 (swift-tools-version: 6.0)
macOS 15 이상
의존성 swift-syntax 600+, swift-argument-parser 1.5+, Yams 5.1+

Xcode 로 열어도 되고 swift build 로 끝내도 됩니다. 패키지 이름은 Stella, 산출물은 네 개입니다.

산출물 종류 역할
StellaCore 라이브러리 파싱·매칭·blame·스냅샷 — 로직 전부
StellaTestSupport 라이브러리 테스트 헬퍼 — 샌드박스 git 레포, URL 스텁
apicov 실행 파일 CLI
stella 실행 파일 macOS GUI

CLI 와 GUI 는 둘 다 StellaCore 를 얇게 감쌉니다. 로직을 두 곳에 나눠 쓰지 않는 게 이 구조의 요점입니다.

소스 배치

Sources/
├── StellaCore/
│   ├── OpenAPI/     # 스펙 로드·파싱
│   ├── Scanner/     # 파일 탐색 + SwiftSyntax Router 파싱
│   ├── Matcher/     # 경로 정규화·매칭·overrides
│   ├── Blame/       # git blame 실행
│   ├── Authors/     # authors.yml 매핑
│   ├── Owners/      # owners.yml 매핑
│   ├── Snapshot/    # CoverageSnapshot + 인코딩
│   ├── Pipeline/    # 전체 흐름 조립
│   └── Errors/      # StellaError
├── apicov/
│   ├── Commands/    # scan · report · diff
│   └── Output/      # HTML 리포트, diff 포맷
├── StellaApp/       # SwiftUI
└── StellaTestSupport/

각 단계가 뭘 하는지는 매칭 파이프라인 에 순서대로 정리돼 있습니다.

빌드와 실행

swift build                                  # 전체
swift build -c release --product apicov      # CLI 만
swift run apicov scan --help
swift run stella                             # GUI 를 번들 없이 바로 실행

GUI 를 .app 으로 묶으려면 스크립트를 씁니다.

scripts/build-app.sh            # 빌드 + 번들 → dist/Stella.app
scripts/build-app.sh --no-build # 기존 .build/release/stella 를 재사용

스크립트가 하는 일은 실행 파일과 리소스 번들 복사, 아이콘 squircle 마스킹 후 .icns 생성, Info.plist 작성, ad-hoc 코드사인입니다. 번들 ID 는 com.umc.stella, 최소 시스템 버전은 15.0 입니다. 서명이 ad-hoc 이라 배포용은 아니고 로컬 실행용입니다.

테스트

swift test                                    # 전체
swift test --filter PathNormalizerTests       # 하나만

XCTest 를 씁니다. 테스트는 소스 디렉터리 구조를 그대로 따라갑니다 — Sources/StellaCore/Matcher/PathNormalizer.swift 를 고쳤으면 Tests/StellaCoreTests/Matcher/PathNormalizerTests.swift 를 보면 됩니다.

픽스처

Fixtures/ 하나를 두 테스트 타깃이 .copy("../../Fixtures") 로 공유합니다.

파일 용도
MiniOpenAPI.json 오퍼레이션 4개짜리 최소 스펙
MiniRepo/AppProduct/**/Router/NoticeRouter.swift --app-product 글로브에 걸리는 샘플
MiniRepo/UMCApp/**/Data/Sources/AuthRouter.swift --umc-app 글로브에 걸리는 샘플
authors.yml · owners.yml · overrides.yml 매핑 로더 테스트용

Fixtures/overrides.yml비어 있는 상태가 정상입니다. 여기에 규칙을 넣으면 매칭 테스트의 기대값이 어긋납니다. 운영용 규칙은 레포 루트의 overrides.yml 에 넣으세요. 두 위치의 차이는 매핑 YAML 에 정리돼 있습니다.

외부에 의존하는 테스트

StellaTestSupport 에 두 개가 있습니다.

  • SandboxGitRepo — 임시 디렉터리에 진짜 git 레포를 만들고 커밋을 찍습니다. user.email/user.namecommit.gpgsign false 를 직접 설정하므로 로컬 git 설정에 영향받지 않고 deinit 에서 디렉터리를 지웁니다. blame 테스트가 씁니다
  • StubURLProtocolURLSessionConfiguration 에 끼워 넣어 스펙 다운로드 응답을 가로챕니다. OpenAPILoader 테스트가 네트워크 없이 돌아가는 이유입니다

자주 하는 변경

새 Router 글로브 추가

Sources/StellaCore/Pipeline/ScanConfig.swiftProjectInput 팩토리가 있습니다.

public static func appProduct(rootPath: URL) -> ProjectInput {
    ProjectInput(key: "appProduct", displayName: "AppProduct",
                 rootPath: rootPath, routerGlobs: ["**/Router/*Router.swift"])
}

key 는 스냅샷의 connections·summary 키로 그대로 나가므로 한 번 정하면 바꾸기 어렵습니다. 글로브는 ** (하위 디렉터리 전체) 와 * (경로 컴포넌트 하나) 만 지원합니다 — RouterFileFinder 가 정규식으로 바꿔 씁니다.

CLI 플래그도 같이 늘려야 합니다. Sources/apicov/Commands/ScanCommand.swift 를 보세요.

스냅샷 필드 추가

Sources/StellaCore/Snapshot/CoverageSnapshot.swift 의 구조체에 필드를 더합니다. 옵셔널로 넣으면 기존 스냅샷을 그대로 디코딩할 수 있어 schemaVersion 을 올리지 않아도 됩니다. 필수 필드를 추가하거나 의미를 바꾸면 currentSchemaVersion 을 올리고 읽는 쪽 셋 (HTML 리포트·diff·Stella 앱) 을 같이 손봐야 합니다. 자세한 건 스냅샷 스키마 에.

Router 파싱 규칙 변경

Sources/StellaCore/Scanner/RouterEnumParser.swift 가 SwiftSyntax 로 enum 을 훑습니다. 파싱 실패는 예외가 아니라 "인식 안 된 case" 로 흘러가 스냅샷의 unmatchedRouterCasesmissing path or method arm 으로 남습니다. 규칙을 고쳤으면 Fixtures/MiniRepo 에 케이스를 하나 추가해 회귀를 잡아두세요.

코드 규칙

  • 에러는 StellaError 로 모읍니다Sources/StellaCore/Errors/StellaError.swift. 새 실패 지점이 생기면 여기에 케이스를 추가합니다. 지금은 LocalizedError 를 채택하지 않아서 GUI 쪽 메시지가 불친절합니다 (StellaCore.StellaError error 3.). 손볼 여지가 있는 부분입니다
  • StellaCore 는 UI 를 모릅니다 — AppKit·SwiftUI import 가 들어가면 CLI 가 못 씁니다
  • Swift 6 동시성 — 스냅샷을 오가는 타입은 Sendable, GUI 모델은 @MainActor 입니다
  • 파일 헤더 — Swift 소스에는 붙이지 않습니다. 스크립트와 워크플로 YAML 에만 Created by euijjang97 헤더가 있습니다
  • 커밋 메시지이모지 [타입] 한 줄 요약 형식입니다. git log --oneline 으로 최근 것들을 보고 맞추세요

커밋하지 않는 것

.gitignore 가 걸러줍니다 — .build/, .swiftpm/, dist/, .claude/, _workspace/.

레포 루트의 authors.yml · owners.yml · overrides.yml 은 운영 데이터라 커밋합니다. 새로 시작할 때는 옆에 있는 *.yml.example 을 복사해 쓰세요.


관련: 매칭 파이프라인 · 스냅샷 스키마 · 트러블슈팅

Clone this wiki locally