# 機能設計書 43-task関数

## 概要

本ドキュメントは、Cakefileでタスクを定義するためのtask関数の設計を記載する。

### 本機能の処理概要

task関数は、Cakefileにおいてビルドタスクを定義するためのグローバル関数である。タスク名、オプションの説明、および実行するアクション関数を受け取り、内部のtasksオブジェクトに登録する。登録されたタスクは`cake <タスク名>`コマンドで実行可能になる。

**業務上の目的・背景**：ビルド自動化において、タスク（コンパイル、テスト、デプロイなど）を名前付きで定義し、コマンドラインから呼び出せるようにすることは基本的な要件である。task関数はMakeのターゲットやRakeのタスクに相当する機能を提供し、CoffeeScript開発者が馴染みのある構文でビルドスクリプトを記述できるようにする。

**機能の利用シーン**：
- Cakefileでコンパイルタスクを定義するとき
- テスト実行タスクを定義するとき
- ドキュメント生成やリリース作業のタスクを定義するとき
- 複数のサブタスクを束ねるメインタスクを定義するとき

**主要な処理内容**：
1. 引数の順序を正規化（descriptionとactionの入れ替えに対応）
2. タスク情報（name, description, action）をオブジェクトとして構成
3. tasksオブジェクトにタスク名をキーとして登録

**関連システム・外部連携**：
- Cakeタスクランナー（cake.coffee）
- invoke関数（他タスクからの呼び出し）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Annotated Source - Cake | 補助機能 | タスク定義関数の解説を含む |
| 38 | Annotated Source - Cake | 補助機能 | タスク定義関数の解説を含む（v2） |

## 機能種別

設定定義 / タスク登録

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | タスクの名前。`cake <name>`で実行される | 文字列であること |
| description | string | No | タスクの説明。引数なしで`cake`を実行した際に表示される | 文字列またはFunction |
| action | Function | Yes | タスク実行時に呼び出される関数。optionsオブジェクトが引数として渡される | 関数であること |

**注**: descriptionとactionの引数順序は入れ替え可能。関数が2つ目の引数の場合、descriptionは省略されたとみなされる。

### 入力データソース

Cakefile内でのtask関数呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tasks[name] | object | 登録されたタスクオブジェクト |
| tasks[name].name | string | タスク名 |
| tasks[name].description | string | タスクの説明 |
| tasks[name].action | Function | 実行関数 |

### 出力先

内部のtasksオブジェクト（モジュールスコープ）

## 処理フロー

### 処理シーケンス

```
1. 引数のチェック
   └─ actionが未定義かどうかを確認

2. 引数の正規化
   └─ actionが未定義の場合、descriptionをactionとし、descriptionを未定義に

3. タスクオブジェクトの構成
   └─ {name, description, action}オブジェクトを作成

4. tasksへの登録
   └─ tasks[name]にタスクオブジェクトを代入
```

### フローチャート

```mermaid
flowchart TD
    A[task関数呼び出し] --> B{action引数あり?}
    B -->|No| C[description を action に代入]
    C --> D[description を undefined に]
    B -->|Yes| E[引数そのまま使用]
    D --> F[タスクオブジェクト作成]
    E --> F
    F --> G["tasks[name] に登録"]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 引数順序の柔軟性 | descriptionを省略した場合、2番目の引数がactionとして扱われる | descriptionが関数の場合 |
| BR-02 | タスク上書き | 同名のタスクが定義された場合、後の定義で上書きされる | 同じnameで複数回task呼び出し |
| BR-03 | options受け渡し | action関数はパース済みのoptionsオブジェクトを引数として受け取る | タスク実行時 |

### 計算ロジック

引数正規化ロジック（cake.coffee 31行目）:
```coffeescript
[action, description] = [description, action] unless action
```

この行は、actionがundefined（falsy）の場合に、descriptionとactionを入れ替える。これにより以下の両方の呼び出し方法が可能になる：

```coffeescript
# 説明付き
task 'build', 'Build the project', -> compile()

# 説明なし
task 'build', -> compile()
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | なし | task関数自体はエラーを発生させない | - |

task関数は引数チェックを行わず、登録のみを行う。不正な引数が渡された場合のエラーは、タスク実行時（invoke呼び出し時）に発生する。

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- タスク登録は即時完了（O(1)の計算量）
- Cakefile読み込み時に全タスクが一度に登録される

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

- action関数の内容はユーザーが定義するため、任意のコードが実行可能
- Cakefileは信頼できるソースからのみ取得すること

## 備考

- task関数はhelpers.extendによってglobalオブジェクトに追加されるため、Cakefile内ではrequireなしで使用可能
- タスク名には任意の文字列が使用可能だが、シェルでの扱いやすさを考慮して英数字とハイフン・アンダースコアを推奨

---

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

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

### 推奨読解順序

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

task関数が使用するtasksオブジェクトの構造を理解する。

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

**読解のコツ**: `tasks = {}` は空オブジェクトの初期化。各タスクは `tasks[name] = {name, description, action}` の形式で格納される。

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

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

**主要処理フロー**:
- **30行目**: `task: (name, description, action) ->` - 関数定義
- **31行目**: `[action, description] = [description, action] unless action` - 引数正規化
- **32行目**: `tasks[name] = {name, description, action}` - タスク登録

**読解のコツ**:
- CoffeeScriptの分割代入 `[a, b] = [b, a]` は変数の入れ替えを行う
- `unless action` は `if not action` と同義
- `{name, description, action}` はES6のショートハンドプロパティと同様

#### Step 3: グローバル登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cake.coffee | `src/cake.coffee` | helpers.extend globalの呼び出し（26行目） |
| 3-2 | helpers.coffee | `src/helpers.coffee` | extend関数の定義（42-45行目） |

**主要処理フロー**:
- **26行目**: `helpers.extend global, { task: ..., option: ..., invoke: ... }` でglobalにプロパティを追加
- helpers.coffeeのextend関数がオブジェクトのプロパティをコピー

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

```
Cakefile
    │
    └─ task 'taskname', 'description', -> action()
           │
           └─ global.task (cake.coffee:30)
                  │
                  ├─ [action, description] = [description, action] unless action
                  │
                  └─ tasks[name] = {name, description, action}
```

### データフロー図

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

Cakefile ─▶ task(name, description, action)
                      │
                      ├─▶ 引数正規化
                      │       │
                      │       ▼
                      │   action = description (if action is undefined)
                      │
                      └─▶ tasks[name] = {...}
                                │
                                ▼
                          tasks オブジェクト ──▶ invoke/printTasksで参照
```

### 関連ファイル一覧

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