cob sync#
.envrc 설정을 기반으로 템플릿 프로젝트를 Mason 브릭으로 동기화합니다. --emit-manifest 모드에서는 반대로 기존 feature 패키지를 스캔해 매니페스트 v1(feature.yaml) 인벤토리를 역생성합니다.
cob sync --type <type> --project-dir template/my_project [options]
옵션#
| 옵션 | 축약 | 설명 | 기본값 |
|---|---|---|---|
--type |
-t |
동기화 타입 (
app
,
monorepo
,
feature
,
all-features
,
all-console-features
).
--emit-manifest
사용 시 생략 가능
|
- |
--name |
-n |
--type feature 또는 --emit-manifest의 feature 이름 (예: home, group, task) |
- |
--project-dir | -d | 템플릿 프로젝트 경로 | 현재 디렉토리 |
--bricks-dir |
-b |
bricks/ 디렉토리 경로 | 프로젝트 경로에서 자동 탐지 |
--sync-icons | 템플릿의 앱 아이콘도 동기화 (기본은 기존 브릭 아이콘 보존) | false | |
--commit | sync 완료 후 bricks 레포에 자동 커밋 | false | |
--push |
자동 커밋 + origin 푸시 (--commit 자동 활성화) |
false | |
--force-shared |
비정본 프로젝트도 공유 brick(app/monorepo) sync 허용 (canonical donor 정책 우회) | false | |
--strict-residual |
sync 후 미변환 raw 프로젝트명이 brick에 남으면 실패 (CI 게이트, monorepo) | false | |
--emit-manifest |
기존 feature의 부품 구성을 매니페스트 v1(feature.yaml)로 역생성 (읽기전용, --name 필수) |
false | |
--output |
-o |
emit-manifest 결과를 저장할 파일 경로 | stdout 출력만 |
동기화 모드#
동기화 타입#
| 타입 | 설명 | 대상 |
|---|---|---|
app |
앱 브릭 동기화 | bricks/{app,console,widgetbook}/__brick__/ |
monorepo | 모노레포 전체 동기화 | bricks/monorepo/__brick__// |
feature |
개별 feature 브릭 동기화 (--name 필수) |
bricks/feature_{name}/ |
all-features | 모든 feature 브릭 일괄 동기화 | feature 브릭 전체 |
all-console-features |
console feature 브릭 일괄 동기화 | console feature 브릭 전체 |
템플릿 변수 변환#
sync는 템플릿 프로젝트의 하드코딩된 값을 .envrc 설정 기반의 Mason 템플릿 변수로 변환합니다. 패턴은 우선순위 순서로 적용됩니다 (GitHub URL → GitHub 조직 → Apple Developer ID → Firebase/도메인 → 프로젝트명 → 조직명). 케이스 변환은 문맥 인식형입니다:
| 문맥 | 변환 예시 |
|---|---|
| GitHub URL | github.com/org/ |
| 패키지명 | _service |
| Firestore 컬렉션 | _users |
Canonical donor 정책#
공유 brick(app, monorepo)은 정본(canonical) 프로젝트만 sync할 수 있습니다. bricks 레포 루트의 .cob-donor.yaml
마커로 정본을 지정하며, 마커가 없으면 정책이 적용되지 않습니다. 비정본 프로젝트가 공유 brick을 sync하려면 --force-shared가 필요합니다.
feature/all-features/all-console-features는 프로젝트별 분리 경로이므로 정책 없이 통과합니다.
--emit-manifest 모드 (읽기전용 인벤토리)#
기존 feature 패키지(feature/{application,console}/<name>)를 스캔해 부품 구성을 매니페스트 v1(feature.yaml) 형태로 역생성합니다.
파일을 변경하지 않는 읽기전용 모드이며, --name <feature>가 필수입니다.
감지 항목#
| 항목 | 감지 위치 | 비고 |
|---|---|---|
| network | lib/src/data/repository/mixins/{feature}_{network}_mixin.dart |
serverpod/openapi/graphql — v1 compose는 serverpod만 지원 (그 외 경고) |
| usecases | lib/src/domain/usecase/*_usecase.dart |
스켈레톤({feature}.dart)은 compose가 항상 생성하므로 제외 |
| blocs | lib/src/presentation/bloc/blocs/*/ |
bloc 파일의 final XUsecase x; 필드로 usecase 의존성 추출, 스켈레톤({feature}/) 제외 |
| widgets | lib/src/presentation/widget/*.dart |
widget.dart barrel 제외 |
| entities | frontend lib/src/domain/entity/ + backend *.spy.yaml |
필드는 백엔드 spy.yaml(계약 소스)에서 읽음, 빈 placeholder spy 제외 |
| backend 토글 | backend/*_server/lib/src/feature/{feature}/ |
endpoint, console_endpoint, service, constant, exception, validation, helper, test, cache, dto, entity, enum, readme — "비어있지 않은 파일 존재" 기준 |
출력#
- 매니페스트 YAML을 stdout에 출력하고,
--output <path>지정 시 파일로도 저장합니다. -
project_name은backend/*_server디렉토리명에서 추정하며, 미발견 시myproject로 출력하고 경고합니다. -
함께 출력되는 이름 규약 리포트는 usecase ↔ repository 인터페이스(
i_{feature}_repository.dart) 메서드의 1:1 매칭 성립률을 측정합니다.
한계#
역분석은 usecase ↔ repository 메서드 이름 규약 1:1 성립을 전제합니다 (성립률은 리포트로 확인). call-site AST 분석과 백엔드 3단 매칭은 의도적으로 제외됩니다 — v1 매니페스트에 wiring 표현이 없으므로 round-trip은 스키마 표현력과 일치해야 성립합니다.
--strict-residual (CI 게이트)#
monorepo sync 완료 후 ResidualTokenScanner가 brick에 남은 미변환 raw 프로젝트명 토큰을 검출합니다. 1건이라도 발견되면 sync를 실패 처리하고 software 에러 코드로 종료하므로, CI에서 변환 누락을 게이트로 차단할 수 있습니다.
🚫 --strict-residual: 미변환 raw 토큰 N건으로 sync를 실패 처리합니다.
예시#
# 모노레포 동기화
cob sync --type monorepo --project-dir template/good_teacher
# 개별 feature 브릭 동기화
cob sync --type feature --name home --project-dir template/good_teacher
# console feature 전체 동기화
cob sync --type all-console-features --project-dir template/kobic
# 동기화 후 자동 커밋 + 푸시
cob sync --type monorepo --project-dir template/good_teacher --push
# emit-manifest: home feature 인벤토리 역생성 (stdout)
cob sync --emit-manifest --name home --project-dir template/good_teacher
# emit-manifest: 파일로 저장
cob sync --emit-manifest --name home --project-dir template/good_teacher \
--output claudedocs/home-feature.yaml
# CI에서 strict-residual 게이트 사용 (GitHub Actions)
- name: Sync monorepo (residual gate)
run: |
dart run bin/cob.dart sync --type monorepo \
--project-dir template/good_teacher \
--strict-residual