# 機能設計書 45-invoke関数

## 概要

本ドキュメントは、Cakefile内から他のタスクを呼び出すためのinvoke関数の設計を記載する。

### 本機能の処理概要

invoke関数は、Cakefile内のタスク定義から別のタスクを呼び出すためのグローバル関数である。タスク名を引数として受け取り、そのタスクのaction関数を現在のoptionsオブジェクトを渡して実行する。これにより、タスク間の依存関係を表現し、複数のタスクを組み合わせた複合的なビルド処理が可能になる。

**業務上の目的・背景**：ビルドプロセスでは、あるタスクが別のタスクの完了に依存することがある。例えば、「build」タスクは「clean」タスクの後に実行する必要があるかもしれない。invoke関数を使用することで、タスク間の依存関係を明示的に記述でき、コードの再利用と保守性が向上する。

**機能の利用シーン**：
- 「build」タスクから「clean」「compile」「test」を順次呼び出すとき
- 共通の前処理タスクを複数のタスクから呼び出すとき
- デプロイタスクでビルドとテストを先に実行するとき
- 複数の関連タスクを束ねるメインタスクを作成するとき

**主要な処理内容**：
1. 指定されたタスク名がtasksオブジェクトに存在するか確認
2. 存在しない場合はmissingTaskでエラー終了
3. 存在する場合はtasks[name].action(options)を呼び出し

**関連システム・外部連携**：
- Cakeタスクランナー（cake.coffee）
- task関数（タスク定義）
- option関数（オプション定義）

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | cakeコマンドで指定されたタスクの実行 |

## 機能種別

タスク実行 / 制御フロー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | 呼び出すタスクの名前 | tasksオブジェクトに存在すること |

### 入力データソース

- Cakefile内のタスクaction関数からの呼び出し
- exports.run内での直接呼び出し（コマンドライン引数のタスク名ごと）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | any | タスクのaction関数の戻り値 |

### 出力先

タスクのaction関数の実行結果（通常はコンソール出力など）

## 処理フロー

### 処理シーケンス

```
1. タスクの存在確認
   └─ tasks[name]が存在するかチェック

2. 存在しない場合
   └─ missingTask(name)でエラー表示・プロセス終了

3. 存在する場合
   └─ tasks[name].action(options)を実行
```

### フローチャート

```mermaid
flowchart TD
    A["invoke(name)呼び出し"] --> B{"tasks[name]存在?"}
    B -->|No| C[missingTask: エラー表示]
    C --> D[process.exit 1]
    B -->|Yes| E["tasks[name].action(options)実行"]
    E --> F[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | タスク存在確認 | 指定されたタスクが未定義の場合、エラーメッセージを表示してプロセス終了 | タスクがtasksに登録されていない場合 |
| BR-02 | options共有 | invoke時には現在のoptionsオブジェクトがそのまま渡される | 常時 |
| BR-03 | 同期実行 | invokeはaction関数を同期的に呼び出す。非同期の場合は呼び出し側で待機が必要 | 常時 |
| BR-04 | 再帰呼び出し | 同じタスクを複数回invokeすることも、循環呼び出しも可能（制限なし） | 常時 |

### 計算ロジック

invoke関数の実装（cake.coffee 41-43行目）:
```coffeescript
invoke: (name) ->
  missingTask name unless tasks[name]
  tasks[name].action options
```

使用例:
```coffeescript
task 'clean', 'Remove build artifacts', ->
  # クリーンアップ処理

task 'compile', 'Compile CoffeeScript', ->
  # コンパイル処理

task 'build', 'Build the project', ->
  invoke 'clean'
  invoke 'compile'
```

## データベース操作仕様

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| No such task: {name} | タスクエラー | 指定されたタスク名がtasksに存在しない | タスク名を確認、または`cake`でタスク一覧を表示 |

### リトライ仕様

エラー発生時はprocess.exit(1)でプロセスが終了するため、リトライは行われない。ユーザーが再度cakeコマンドを実行する必要がある。

## トランザクション仕様

該当なし

## パフォーマンス要件

- タスク呼び出しのオーバーヘッドは最小（オブジェクト参照と関数呼び出しのみ）
- 実行時間は呼び出されるタスクのaction関数の内容に依存

## セキュリティ考慮事項

- invokeはCakefile内で定義されたタスクのみを実行可能
- 外部からの入力でタスク名を指定する場合は、ホワイトリストによる検証を推奨

## 備考

- Node.jsの非同期性により、複数のinvokeが含まれるタスクは予想と異なる順序で実行される可能性がある
- 非同期タスク間の順序制御が必要な場合は、async/awaitやPromiseを使用すること
- invoke関数はhelpers.extendによってglobalオブジェクトに追加される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

invoke関数が参照するtasksオブジェクトとoptionsオブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cake.coffee | `src/cake.coffee` | tasks変数の定義（20行目） |
| 1-2 | cake.coffee | `src/cake.coffee` | options変数の定義（21行目） |

**読解のコツ**: tasksはタスク名をキーとするオブジェクト、optionsはOptionParserでパースされたコマンドラインオプションを格納するオブジェクト。

#### Step 2: invoke関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cake.coffee | `src/cake.coffee` | invoke関数の定義（41-43行目） |

**主要処理フロー**:
- **41行目**: `invoke: (name) ->` - 関数定義
- **42行目**: `missingTask name unless tasks[name]` - タスク存在確認
- **43行目**: `tasks[name].action options` - タスクアクション実行

**読解のコツ**:
- `unless` は `if not` と同義
- `tasks[name].action options` は `tasks[name].action(options)` と等価

#### Step 3: missingTask関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cake.coffee | `src/cake.coffee` | missingTask関数（80行目） |
| 3-2 | cake.coffee | `src/cake.coffee` | fatalError関数（75-78行目） |

**主要処理フロー**:
- **80行目**: `missingTask = (task) -> fatalError "No such task: #{task}"` - エラーメッセージ生成
- **76行目**: `console.error message + '\n'` - エラー出力
- **78行目**: `process.exit 1` - プロセス終了

#### Step 4: exports.runでの使用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | cake.coffee | `src/cake.coffee` | exports.run内でのinvoke呼び出し（60行目） |

**主要処理フロー**:
- **60行目**: `invoke arg for arg in options.arguments` - コマンドライン引数のタスク名ごとにinvoke

### プログラム呼び出し階層図

```
cake <taskname1> <taskname2>
    │
    └─ exports.run (cake.coffee:49)
           │
           ├─ oparse.parse(args) (57行目)
           │       │
           │       └─ options.arguments = [taskname1, taskname2]
           │
           └─ invoke arg for arg in options.arguments (60行目)
                  │
                  ├─ invoke 'taskname1' (cake.coffee:41)
                  │       │
                  │       ├─ missingTask unless tasks[name] (42行目)
                  │       │
                  │       └─ tasks[taskname1].action(options) (43行目)
                  │               │
                  │               └─ タスク内でinvoke 'subtask' (可能)
                  │
                  └─ invoke 'taskname2'
                          └─ ...
```

### データフロー図

```
[入力]               [処理]                    [出力]

タスク名 ───────────▶ invoke(name)
                         │
                         ├─▶ tasks[name] 存在確認
                         │       │
                         │       ├── No ──▶ missingTask ──▶ process.exit(1)
                         │       │
                         │       └── Yes
                         │             │
                         │             ▼
options ─────────────────┴──▶ tasks[name].action(options)
                                     │
                                     ▼
                               タスク実行結果 ──▶ stdout/stderr
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cake.coffee | `src/cake.coffee` | ソース | invoke関数の実装、tasks/optionsの管理 |
| helpers.coffee | `src/helpers.coffee` | ソース | extend関数（globalへの登録に使用） |
| Cakefile | プロジェクトルート | 設定 | ユーザーがinvoke関数を呼び出すファイル |
