# 機能設計書 75-依存関係解決

## 概要

本ドキュメントは、Zigコンパイラにおける依存関係解決機能の設計を記載する。この機能は、build.zig.zonファイルに定義された依存関係を解析し、パッケージをフェッチ・キャッシュ・管理する。

### 本機能の処理概要

依存関係解決は、Zigのパッケージ管理システムの中核機能である。build.zig.zonファイルで宣言された外部パッケージの依存関係を解析し、リモートからパッケージをフェッチし、ローカルキャッシュに格納し、ハッシュを検証して整合性を確保する。これにより、再現可能なビルドとプロジェクト間のコード共有が可能になる。

**業務上の目的・背景**：現代のソフトウェア開発では外部ライブラリやパッケージの再利用が不可欠である。依存関係解決機能により、開発者はbuild.zig.zonファイルに宣言的に依存関係を記述するだけで、自動的にパッケージがダウンロード・検証・キャッシュされる。これにより、プロジェクトのセットアップが簡素化され、ビルドの再現性が向上する。

**機能の利用シーン**：
- 新しいプロジェクトで外部パッケージを追加する場合
- `zig build`実行時に依存パッケージを自動取得する場合
- `zig fetch`コマンドでパッケージを手動取得する場合
- CI/CDパイプラインで依存関係を事前にキャッシュする場合
- 遅延依存関係（lazy dependency）を必要時に取得する場合

**主要な処理内容**：
1. build.zig.zonファイルの解析（Manifest.parse）
2. 依存関係の抽出（dependencies、paths、name、version等）
3. パッケージロケーション（URL/パス）の解決
4. リモートパッケージのフェッチ（HTTP/Git）
5. パッケージの展開と一時ディレクトリへの配置
6. ハッシュの計算と検証
7. グローバルキャッシュへの移動
8. 再帰的な依存関係の解決

**関連システム・外部連携**：
- HTTPクライアント：リモートパッケージのダウンロード
- Gitクライアント：Gitリポジトリからのパッケージ取得
- ファイルシステム：パッケージキャッシュの管理
- ビルドシステム（build.zig）：解決された依存関係の利用

**権限による制御**：特に権限による制御はなし。ネットワークアクセスが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | プロジェクトビルド画面 | 補助機能 | build.zig.zonベースの依存関係解決処理 |
| 27 | パッケージ取得画面 | 補助機能 | パッケージ依存関係の解決処理 |

## 機能種別

データ取得 / ネットワーク通信 / キャッシュ管理 / パッケージ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| build.zig.zon | ファイル | Yes | パッケージマニフェストファイル | ZON形式で有効であること |
| --fetch | オプション | No | 依存関係のフェッチモード（needed/all） | needed または all |
| --system | オプション | No | システムパッケージディレクトリ | 有効なディレクトリパス |

### 入力データソース

- build.zig.zonファイル
- リモートURL（HTTP/HTTPS）
- Gitリポジトリ
- ローカルパス

### build.zig.zon形式

```zon
.{
    .name = "my-package",
    .version = "1.0.0",
    .fingerprint = 0x12345678,
    .minimum_zig_version = "0.13.0",
    .dependencies = .{
        .some_dep = .{
            .url = "https://example.com/package.tar.gz",
            .hash = "122012345678...",
        },
        .local_dep = .{
            .path = "../local-package",
        },
    },
    .paths = .{
        "src",
        "build.zig",
    },
}
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| パッケージファイル | ディレクトリ | 展開されたパッケージファイル群 |
| パッケージハッシュ | 文字列 | パッケージの一意識別子（SHA-256ベース） |
| dependencies.zig | ファイル | ビルドランナー用の依存関係定義 |

### 出力先

- グローバルキャッシュ: `~/.cache/zig/p/{hash}/`
- ローカルキャッシュ: `.zig-cache/`

## 処理フロー

### 処理シーケンス

```
1. マニフェスト読み込み
   └─ build.zig.zonファイルをパース
   └─ Manifest構造体に変換
2. 依存関係の抽出
   └─ dependenciesフィールドから依存関係リストを取得
3. 各依存関係の処理（JobQueueで並列実行）
   3-1. ロケーション判定
       └─ URL → リモートフェッチ
       └─ パス → ローカル参照
   3-2. キャッシュ確認
       └─ ハッシュが存在すればキャッシュヒット
       └─ 存在しなければフェッチ実行
   3-3. リモートフェッチ（必要な場合）
       └─ HTTPでダウンロード
       └─ tar.gz/zip等を展開
       └─ 一時ディレクトリに配置
   3-4. ハッシュ計算・検証
       └─ パッケージ内容からハッシュを計算
       └─ 宣言されたハッシュと照合
   3-5. キャッシュへの移動
       └─ 一時ディレクトリからグローバルキャッシュへリネーム
   3-6. 再帰的依存関係の解決
       └─ 子パッケージのbuild.zig.zonを処理
4. dependencies.zig生成
   └─ ビルドランナー用の依存関係ソースを生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[build.zig.zon読み込み]
    B --> C[Manifest.parse]
    C --> D{パース成功?}
    D -->|No| E[エラー報告]
    D -->|Yes| F[依存関係リスト取得]
    F --> G[JobQueue作成]
    G --> H[各依存関係を並列処理]
    H --> I{ロケーション種別}
    I -->|URL| J[リモートフェッチ]
    I -->|パス| K[ローカル参照]
    J --> L{キャッシュ存在?}
    L -->|Yes| M[キャッシュ使用]
    L -->|No| N[HTTPダウンロード]
    N --> O[展開・配置]
    O --> P[ハッシュ計算]
    P --> Q{ハッシュ一致?}
    Q -->|No| R[エラー報告]
    Q -->|Yes| S[キャッシュへ移動]
    K --> T[パス検証]
    M --> U[再帰的依存解決]
    S --> U
    T --> U
    U --> V{全依存完了?}
    V -->|No| H
    V -->|Yes| W[dependencies.zig生成]
    W --> X[終了]
    E --> X
    R --> X
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-01 | ハッシュ必須 | リモート依存関係はハッシュフィールドが必須 | URL指定時 |
| BR-75-02 | パスハッシュ禁止 | パス指定の依存関係はハッシュを持てない | path指定時 |
| BR-75-03 | 遅延依存関係 | lazy=trueの依存関係は必要時のみフェッチ | lazy=true時 |
| BR-75-04 | キャッシュ優先 | ハッシュが一致すればローカルキャッシュを使用 | キャッシュ存在時 |
| BR-75-05 | 相対パス制約 | URL取得パッケージは外部への相対パス参照禁止 | パッケージキャッシュ内 |

### 計算ロジック

**パッケージハッシュの計算**:
- SHA-256をベースとしたマルチハッシュ形式
- パッケージ名、バージョン、ID、サイズ、およびファイル内容のダイジェストから算出
- 形式: `{name}-{version}-{base64エンコードされた33バイト}`

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

本機能ではデータベース操作は行わない。ファイルシステム上でキャッシュを管理する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FetchFailed | フェッチエラー | パッケージのダウンロード失敗 | URLとネットワーク接続を確認 |
| HashMismatch | ハッシュエラー | 計算されたハッシュと宣言ハッシュが不一致 | 正しいハッシュを確認・更新 |
| ParseFailure | パースエラー | build.zig.zonの構文エラー | ファイルの構文を修正 |
| FileNotFound | ファイル不在 | キャッシュまたはソースファイルが見つからない | パスとファイルの存在を確認 |
| DependencyOutsideProject | パスエラー | 相対パスがプロジェクト外を参照 | 相対パスを修正 |

### リトライ仕様

ネットワークエラー時のリトライは現時点では実装されていない。

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

該当なし。ただし、一時ディレクトリを使用してアトミックなキャッシュ更新を実現している。

## パフォーマンス要件

- 依存関係の解決は並列実行される（JobQueue使用）
- キャッシュヒット時は即座に完了すること
- 大規模な依存関係ツリーでも合理的な時間で完了すること

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

- ハッシュ検証によりパッケージの改ざんを検出
- HTTPS推奨（HTTPからHTTPSへ自動アップグレード）
- 信頼できないソースからのパッケージ取得に注意
- パッケージキャッシュのディレクトリ権限に注意

## 備考

- build.zig.zon形式はZON（Zig Object Notation）を使用
- 遅延依存関係は`lazy = true`で指定し、必要時のみダウンロード
- `--system`オプションでオフラインビルドが可能（事前にパッケージを配置）
- ハッシュ形式は0.14.0で新形式に移行予定（レガシー形式もサポート）

---

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

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

### 推奨読解順序

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

パッケージとマニフェストの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Package.zig | `src/Package.zig` | Hash、Fingerprint、Module等の定義 |
| 1-2 | Manifest.zig | `src/Package/Manifest.zig` | Dependency、ParseOptions等の定義 |

**読解のコツ**:
- **Package.zig 48-140行目**: Hash構造体。パッケージの一意識別子。
- **Package.zig 13-34行目**: Fingerprint構造体。パッケージIDとチェックサム。
- **Manifest.zig 15-30行目**: Dependency構造体。依存関係の定義。

#### Step 2: マニフェスト解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Manifest.zig | `src/Package/Manifest.zig` | parse関数、parseRoot関数 |

**主要処理フロー**:
- **60-107行目**: parse関数。build.zig.zonのパース。
- **160-244行目**: parseRoot関数。トップレベルフィールドの処理。
- **246-261行目**: parseDependencies関数。依存関係の解析。
- **263-341行目**: parseDependency関数。各依存関係の詳細解析。

#### Step 3: フェッチ処理を理解する

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

**主要処理フロー**:
- **29-92行目**: Fetch構造体の定義。
- **103-161行目**: JobQueue構造体。並列処理の管理。
- **328-477行目**: run関数。フェッチ処理の本体。
- **342-385行目**: relative_pathの処理（ローカル依存関係）。
- **414-476行目**: リモート依存関係の処理。
- **485-599行目**: runResource関数。リソースの展開とハッシュ計算。

#### Step 4: ジョブキューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Fetch.zig | `src/Package/Fetch.zig` | JobQueue.createDependenciesSource |

**主要処理フロー**:
- **178-288行目**: createDependenciesSource関数。dependencies.zig生成。

#### Step 5: コマンドラインインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | main.zig | `src/main.zig` | cmdFetch、cmdBuild |

**読解のコツ**: main.zigからFetch.JobQueueがどのように呼び出されるかを追跡する。

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

```
main.zig (cmdBuild / cmdFetch)
    │
    └─ Package.Fetch.JobQueue
           │
           ├─ Fetch.run() [各依存関係を並列処理]
           │      │
           │      ├─ [relative_path]
           │      │      └─ loadManifest()
           │      │      └─ queueJobsForDeps()
           │      │
           │      ├─ [remote]
           │      │      ├─ キャッシュ確認
           │      │      ├─ initResource() [HTTPクライアント]
           │      │      └─ runResource()
           │      │             ├─ unpackResource() [tar/zip展開]
           │      │             ├─ loadManifest()
           │      │             ├─ computeHash()
           │      │             └─ renameTmpIntoCache()
           │      │
           │      └─ queueJobsForDeps() [再帰]
           │
           ├─ consolidateErrors()
           │
           └─ createDependenciesSource()
                  └─ dependencies.zig生成
```

### データフロー図

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

build.zig.zon ───────▶ Manifest.parse()
                            │
                            ▼
                      依存関係リスト
                            │
                            ▼
URL/パス情報 ───────▶ JobQueue.run()
                            │
           ┌────────────────┼────────────────┐
           │                │                │
           ▼                ▼                ▼
       [URL処理]      [パス処理]     [キャッシュ確認]
           │                │                │
           ▼                ▼                │
      HTTPダウンロード  ローカル参照         │
           │                │                │
           ▼                │                │
      展開・ハッシュ計算   │                │
           │                │                │
           └────────────────┴────────────────┘
                            │
                            ▼
                      キャッシュ格納 ───────▶ ~/.cache/zig/p/{hash}/
                            │
                            ▼
                      dependencies.zig ─────▶ ビルドランナーへ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Package.zig | `src/Package.zig` | ソース | パッケージ関連の型定義 |
| Fetch.zig | `src/Package/Fetch.zig` | ソース | フェッチ処理の実装 |
| Manifest.zig | `src/Package/Manifest.zig` | ソース | マニフェスト解析 |
| Module.zig | `src/Package/Module.zig` | ソース | モジュール定義 |
| main.zig | `src/main.zig` | ソース | コマンドラインインターフェース |
| git.zig | `src/Package/Fetch/git.zig` | ソース | Git操作 |
| build_runner.zig | `lib/compiler/build_runner.zig` | ソース | ビルドランナー |
| Cache.zig | `lib/std/Build/Cache.zig` | ソース | キャッシュ管理 |
