# command

## 목적 / 책임

외부 시스템(Git, Jenkins, FTP, Slack, iOS 빌드 등)과의 실제 연동을 구현하는 커맨드 계층과, 커맨드 파라미터 데이터 모델을 담당한다.
파이프라인은 커맨드를 호출만 하며, 실제 I/O·프로세스 실행·외부 API 호출은 이 도메인에 둔다.

## 포함 경로

- `lib/oto/commands/` — 커맨드 구현체 (카테고리별 하위 폴더)
- `lib/oto/data/` — 커맨드 파라미터 데이터 모델 (`*_data.dart`, `*.g.dart`)
- `assets/template/` — 커맨드 실행 중 사용하는 템플릿 파일

## 제외 경로

- `lib/oto/pipeline/` — 실행 흐름 제어 (커맨드 dispatch 이전)
- `lib/oto/core/` — 태그 치환, 데이터 합성 (커맨드 실행 이전)
- `assets/yaml/sample/` — YAML 사용 예시 (`sample` 도메인)

## 주요 구성 요소

- `Command` (`command.dart`) — 커맨드 베이스 클래스, `CommandType` enum
- `CommandSpec` (`command.dart`) — CommandType → category/dataModel/samplePath 메타데이터
- `registerAllCommands()` (`command_registry.dart`) — 카테고리별 register 함수를 호출해 CommandType → Command 매핑 구성
- `CommandRuntime` / `DefaultCommandRuntime` (`command_runtime.dart`) — 커맨드 외부 프로세스 실행 추상화
- `DataParam` (`base_data.dart`) — 모든 커맨드 파라미터의 베이스
- `DataBuild` / `DataScheduler` (`command_data.dart`) — YAML 최상위 build/scheduler 데이터
- `DataCommand` (`command_data.dart`) — 모든 커맨드에 전달되는 통합 컨테이너

커맨드 카테고리와 우선 참조 파일:

| 범주 | 구현 경로 | 데이터 모델 |
|------|-----------|-------------|
| build | `lib/oto/commands/build/` | `lib/oto/data/build_data.dart` |
| file | `lib/oto/commands/file/` | `lib/oto/data/file_data.dart` |
| git / GitHub | `lib/oto/commands/git/` | `lib/oto/data/git_data.dart` |
| ftp / web | `lib/oto/commands/ftp/`, `lib/oto/commands/web/` | `lib/oto/data/network_data.dart` |
| notification | `lib/oto/commands/notification/`, `lib/oto/utils/mattermost/` | `lib/oto/data/notification_data.dart` |
| jira / jenkins | `lib/oto/commands/jira/`, `lib/oto/commands/jenkins/` | `lib/oto/data/integration_data.dart`, `lib/oto/data/jira_data.dart` |
| infra / external tool | `lib/oto/commands/aws/`, `docker/`, `gradle/`, `infra/`, `proto/` | `lib/oto/data/infra_data.dart`, `lib/oto/data/util_data.dart` |
| shell / process / util | `lib/oto/commands/shell/`, `process/`, `util/` | `lib/oto/data/util_data.dart` |

커맨드 asset:

| asset | 사용처 |
|-------|--------|
| `assets/template/index.html` | iOS publish HTML 템플릿 |
| `assets/template/manifest.plist` | iOS publish manifest 템플릿 |

## 유지할 패턴

- 새 커맨드는 반드시 `Command` 상속 후 카테고리별 `register*Command(s)()` 함수와 `registerAllCommands()` 경로에 등록
- `Command.register()`에는 `CommandSpec`을 함께 전달해 category, dataModel, samplePath를 기록
- 파라미터 모델은 `DataParam` 상속 + `@JsonSerializable`
- `*.g.dart`는 `dart run build_runner build`로 생성한다. 생성 파일 직접 수정은 생성 불가한 긴급 상황에서만 한다
- `getWorkspace()`: workspace 필드 → `property['workspace']` → `commonData.workspace` 순으로 resolve
- 커맨드 파라미터는 `getParam(command)`를 통해 태그 치환과 workspace resolve를 거친 뒤 `Data*` 모델로 파싱한다
- 결과 저장은 `<@property.key>` 형태의 쓰기 태그와 `setProperty()` / `complete()`의 `setResult`, `setExitCode` 흐름을 우선 사용한다
- 외부 프로세스 실행은 `Command.runtime`을 통해 `CommandRuntime.start()`, `run()`, `runExecutable()`, `startDetached()` 중 목적에 맞게 사용한다
- 커맨드 추가/파라미터 변경 시 관련 `assets/yaml/sample/**`와 README 커맨드 목록 갱신 필요 여부를 확인한다
- 커맨드가 `assets/template/**`를 읽거나 출력 형식에 의존하면 템플릿 경로와 placeholder 계약을 함께 확인한다
- 데이터 모델 변경 후 `dart run build_runner build`와 `dart analyze`를 실행한다

## 다른 도메인과의 경계

- **pipeline**: `Command.execute(DataCommand)`를 호출하는 시점이 경계. 커맨드는 흐름을 모른다
- **core**: 태그 치환은 core가 완료한 후 DataCommand가 커맨드에 전달됨
- **sample**: YAML 사용 예시는 sample 도메인이 담당한다. 커맨드 파라미터 변경 시 sample 도메인과 동기화한다
- **framework**: `dart_framework`의 `ProcessExecutor`, path/system 유틸은 외부 런타임 의존성으로 사용한다. OTO 비즈니스 로직을 framework 의존성 쪽으로 옮기지 않는다

## 금지 사항

- 커맨드에서 다른 커맨드를 직접 인스턴스화하거나 호출하지 않는다
- 흐름 제어(if/loop) 로직을 커맨드 내부에 넣지 않는다
- 카테고리별 register 함수와 `registerAllCommands()` 경로 외 장소에서 CommandType 매핑을 추가하지 않는다
- 커맨드 구현 중 `Application.instance.dataCommandMap`을 직접 순회하거나 파이프라인 구조를 해석하지 않는다
- 샘플 YAML에 실제 토큰, 비밀번호, API 키를 넣지 않는다
