# 機能設計書 9-fetch

## 概要

本ドキュメントは、Zigコンパイラの`fetch`コマンドの機能設計について記述する。このコマンドはパッケージをグローバルキャッシュにコピーしハッシュを出力する、依存関係管理機能である。

### 本機能の処理概要

`zig fetch`コマンドは、指定されたURL（またはローカルパス）からパッケージをダウンロードし、グローバルキャッシュに保存する。パッケージの内容をハッシュ化し、そのハッシュ値を出力する。これにより、build.zig.zonで依存関係を指定する際に必要なハッシュ値を取得できる。

**業務上の目的・背景**：Zigのパッケージ管理では、依存関係の完全性と再現性を保証するためにハッシュベースの検証を採用している。`zig fetch`は、外部パッケージを取得してそのハッシュを計算し、build.zig.zonに記述するための情報を提供する。これにより、ビルドの再現性と安全性が確保される。

**機能の利用シーン**：
- 新しい依存関係を追加する際のハッシュ取得
- 依存関係のバージョン更新
- パッケージの事前ダウンロードとキャッシュ
- build.zig.zonへの依存関係追加

**主要な処理内容**：
1. コマンドライン引数の解析
2. URLまたはパスの解析
3. パッケージのダウンロード（または取得）
4. ハッシュの計算
5. グローバルキャッシュへの保存
6. ハッシュ値の出力

**関連システム・外部連携**：
- HTTPクライアント：パッケージのダウンロード
- Gitクライアント：Gitリポジトリからの取得

**権限による制御**：特になし。ネットワークアクセスとファイルシステムへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | パッケージ取得画面 | 主機能 | パッケージをグローバルキャッシュにコピーしハッシュを出力する処理 |

## 機能種別

依存関係管理 / パッケージ取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| url_or_path | []const u8 | Yes | パッケージのURLまたはローカルパス | 有効なURL/パス |
| --global-cache-dir | []const u8 | No | グローバルキャッシュディレクトリ | 有効なディレクトリパス |
| --debug-hash | bool | No | ハッシュ計算のデバッグ情報出力 | - |
| --save | []const u8 | No | 取得後にbuild.zig.zonに依存関係を追加 | - |
| --save-exact | []const u8 | No | URLをそのまま保存（コミット解決なし） | - |

### 入力データソース

- コマンドライン引数
- ネットワーク（HTTPまたはGit）
- ローカルファイルシステム

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| パッケージハッシュ | テキスト | パッケージ内容のハッシュ値 |
| キャッシュファイル | バイナリ | グローバルキャッシュに保存されたパッケージ |

### 出力先

- 標準出力（ハッシュ値）
- グローバルキャッシュディレクトリ
- build.zig.zon（--save指定時）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ cmdFetch関数で処理
2. URLまたはパス解析
   └─ HTTPまたはGitまたはローカルパス
3. パッケージ取得
   └─ HTTPダウンロードまたはGitクローン
4. ハッシュ計算
   └─ パッケージ内容からハッシュを生成
5. キャッシュ保存
   └─ グローバルキャッシュディレクトリに保存
6. 結果出力
   └─ ハッシュ値を標準出力
7. (オプション) build.zig.zonに追加
   └─ --save指定時
```

### フローチャート

```mermaid
flowchart TD
    A[zig fetch 開始] --> B[コマンドライン引数解析]
    B --> C{URLまたはパス?}
    C -->|URL| D[HTTPクライアント初期化]
    C -->|パス| E[ローカルパス処理]
    D --> F[パッケージダウンロード]
    E --> G[パッケージ読み込み]
    F --> H[ハッシュ計算]
    G --> H
    H --> I[グローバルキャッシュに保存]
    I --> J{--save指定?}
    J -->|Yes| K[build.zig.zonを更新]
    J -->|No| L[ハッシュを標準出力]
    K --> L
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ハッシュベース検証 | パッケージ内容をハッシュ化して完全性を検証 | 常時 |
| BR-02 | Gitコミット解決 | Gitリポジトリの参照をコミットSHAに解決 | --save指定時かつGit URL |
| BR-03 | キャッシュ利用 | 既にキャッシュにある場合は再ダウンロードしない | ハッシュが一致する場合 |

### 計算ロジック

**パッケージハッシュ計算**：
- パッケージ内の全ファイルの内容と構造をハッシュ化
- ファイルの順序に依存しない一意なハッシュを生成

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

データベースは使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NetworkError | ネットワーク接続失敗 | ネットワーク接続を確認 |
| - | InvalidUrl | 無効なURL形式 | URLを確認 |
| - | NotFound | パッケージが見つからない | URLまたはパスを確認 |
| - | HashMismatch | ハッシュ不一致 | パッケージの完全性を確認 |

### リトライ仕様

- ネットワークエラー時は自動リトライを試みる場合あり

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

該当なし

## パフォーマンス要件

- HTTPダウンロードは並列処理をサポート
- キャッシュヒット時は即座に結果を返却

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

- パッケージはハッシュで検証
- HTTPSを推奨

## 備考

- 出力されるハッシュはbuild.zig.zonの.hash フィールドに使用
- --saveオプションでbuild.zig.zonへの自動追加が可能

---

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

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

### 推奨読解順序

#### Step 1: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | main.zig | `src/main.zig` | fetchコマンドの分岐処理 |

**主要処理フロー**:
1. **326-327行目**: `mem.eql(u8, cmd, "fetch")`で判定
2. **cmdFetch関数**が呼び出される

#### Step 2: cmdFetch関数の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.zig | `src/main.zig` | cmdFetch関数の実装 |

**主要処理フロー**:
- **6931行目**: `fn cmdFetch`の開始
- **6940-6950行目**: オプション変数の初期化
- **6952-6983行目**: コマンドライン引数の解析
- **6987-6990行目**: HTTPクライアントの初期化
- **7006-7046行目**: Package.Fetchの設定
- **7048-7057行目**: フェッチ実行とエラー処理
- **7059-7070行目**: ハッシュの出力

#### Step 3: パッケージフェッチ処理の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Package.zig | `src/Package.zig` | Fetch構造体とrun関数 |

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

```
main (src/main.zig)
    │
    └─ cmdFetch
            │
            ├─ HTTPクライアント初期化
            │      └─ std.http.Client
            │
            ├─ グローバルキャッシュディレクトリ解決
            │
            ├─ Package.Fetch.JobQueue作成
            │
            ├─ Package.Fetch作成と実行
            │      ├─ パッケージダウンロード
            │      ├─ ハッシュ計算
            │      └─ キャッシュ保存
            │
            └─ 結果出力
                   ├─ ハッシュを標準出力
                   └─ (--save時) build.zig.zon更新
```

### データフロー図

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

URL/パス ─────────────▶ ダウンロード ──▶ 展開 ──┐
                                               │
                                               ├──▶ ハッシュ計算 ──▶ 標準出力
                                               │
グローバルキャッシュ ◀───────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.zig | `src/main.zig` | ソース | cmdFetch関数 |
| Package.zig | `src/Package.zig` | ソース | Fetch処理 |
