# 機能設計書 5-補完キャッシュ管理

## 概要

本ドキュメントは、Oh My Zsh（以下OMZ）の補完キャッシュ管理機能に関する機能設計書である。zcompdumpファイルの作成、検証、再コンパイルを管理する処理について記述する。

### 本機能の処理概要

本機能は、ZSHの補完システム（compinit）が生成するダンプファイル（zcompdump）を管理し、OMZのリビジョン変更やfpathの変更を検出して適切にキャッシュを更新する。

**業務上の目的・背景**：ZSHの補完システムは多数の補完関数を読み込むため、初期化に時間がかかる。zcompdumpファイルにより補完定義をキャッシュすることで、シェル起動時間を大幅に短縮できる。OMZはこのキャッシュの整合性を管理し、必要に応じて自動再生成を行う。

**機能の利用シーン**：シェル起動時に自動実行される。OMZのアップデート後やプラグインの追加・削除後には、キャッシュの再生成が自動的に行われる。また、`omz reload`コマンドで明示的にキャッシュを削除して再生成することも可能。

**主要な処理内容**：
1. ZSH_COMPDUMPパスの決定
2. zcompdumpファイルのメタデータ検証（OMZリビジョン、fpath）
3. compinit実行による補完システム初期化
4. zcompdumpファイルのコンパイル（.zwc生成）
5. 補完セキュリティチェック

**関連システム・外部連携**：Git（OMZリビジョン取得）

**権限による制御**：ZSH_COMPDUMPファイルへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | omz reload | 補助機能 | zcompdumpファイルを削除して補完キャッシュをクリア |

## 機能種別

初期化処理 / キャッシュ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ZSH_COMPDUMP | 環境変数(文字列) | No | 補完ダンプファイルパス | 未定義時は自動生成 |
| ZSH_DISABLE_COMPFIX | 環境変数(boolean) | No | 補完セキュリティチェックの無効化 | true/false |
| ZSH | 環境変数(文字列) | Yes | OMZインストールディレクトリ | 必須 |
| SHORT_HOST | 変数 | Yes | 短縮ホスト名 | 自動設定 |
| ZSH_VERSION | 環境変数 | Yes | ZSHバージョン | シェル提供 |
| fpath | 配列 | Yes | 関数検索パス | 初期化済み |

### 入力データソース

- $ZSH/.gitリポジトリ（リビジョン取得）
- fpath配列
- 既存のzcompdumpファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ZSH_COMPDUMP | 環境変数 | 補完ダンプファイルパス |
| zcompdumpファイル | ファイル | 補完定義キャッシュ |
| .zwcファイル | ファイル | コンパイル済み補完キャッシュ |

### 出力先

- ${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}
- 上記ファイルの.zwc版

## 処理フロー

### 処理シーケンス

```
1. ZSH_COMPDUMPパス決定
   └─ ZSH_COMPDUMP環境変数が設定されていればそれを使用
   └─ 未設定の場合は自動生成: ${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}

2. メタデータ生成
   └─ OMZリビジョン取得（git rev-parse HEAD）
   └─ 現在のfpath取得

3. メタデータ検証
   └─ 既存zcompdumpにOMZリビジョンが含まれるか確認
   └─ 既存zcompdumpにfpathが含まれるか確認
   └─ 不一致の場合はzcompdump削除

4. compinit実行
   └─ ZSH_DISABLE_COMPFIX=trueの場合: compinit -u（全ディレクトリから読み込み）
   └─ それ以外: compinit -i（安全なディレクトリのみ）

5. メタデータ追記
   └─ zcompdumpにOMZリビジョンとfpathを追記

6. コンパイル
   └─ zrecompileでzcompdumpを.zwcにコンパイル
   └─ ロックファイルで排他制御

7. セキュリティチェック
   └─ ZSH_DISABLE_COMPFIX=true以外の場合
   └─ handle_completion_insecuritiesをバックグラウンド実行
```

### フローチャート

```mermaid
flowchart TD
    A[初期化開始] --> B{ZSH_COMPDUMP設定あり?}
    B -->|Yes| C[ZSH_COMPDUMPを使用]
    B -->|No| D[パス自動生成]
    C --> E[メタデータ生成]
    D --> E
    E --> F{既存zcompdumpのメタデータ一致?}
    F -->|Yes| G[compinit実行]
    F -->|No| H[zcompdump削除]
    H --> G
    G --> I{ZSH_DISABLE_COMPFIX?}
    I -->|true| J[compinit -u]
    I -->|false| K[compinit -i + セキュリティチェック]
    J --> L[メタデータ追記]
    K --> L
    L --> M{ロック取得成功?}
    M -->|Yes| N[zrecompile実行]
    M -->|No| O[スキップ]
    N --> P[ロック解放]
    O --> Q[完了]
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | メタデータ検証 | OMZリビジョンまたはfpathが変更された場合はzcompdumpを再生成 | 常時 |
| BR-02 | セキュリティモード | ZSH_DISABLE_COMPFIX=true以外はセキュアモードでcompinit実行 | 常時 |
| BR-03 | 排他制御 | zrecompile実行時はロックディレクトリで排他制御 | コンパイル時 |
| BR-04 | バックグラウンドセキュリティチェック | セキュリティチェックはバックグラウンドで実行 | ZSH_DISABLE_COMPFIX=false時 |
| BR-05 | ホスト・バージョン依存パス | zcompdumpパスにホスト名とZSHバージョンを含める | デフォルトパス使用時 |

### 計算ロジック

**ZSH_COMPDUMPパス生成**:
```zsh
ZSH_COMPDUMP="${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
```

**メタデータ形式**:
```
#omz revision: <git-commit-hash>
#omz fpath: <fpath-array>
```

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Git取得エラー | OMZディレクトリがGitリポジトリでない | リビジョン検証をスキップ |
| - | 書き込みエラー | zcompdumpへの書き込み権限がない | teeでエラーを無視 |
| - | ロック取得失敗 | 他プロセスがコンパイル中 | コンパイルをスキップ |

### リトライ仕様

リトライは行わない。ロック取得失敗時は処理をスキップ。

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

本機能はトランザクションを使用しないが、ロックディレクトリによる排他制御を行う。

## パフォーマンス要件

- zcompdumpのコンパイル（.zwc生成）により補完の高速化を実現
- メタデータ検証により不要な再生成を防止
- セキュリティチェックはバックグラウンド実行でシェル起動をブロックしない

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

- **compinit -i**: 安全なディレクトリ（所有者がrootまたは現在のユーザーで、グループ/他者書き込み不可）からのみ補完を読み込む
- **compaudit**: 補完ディレクトリのセキュリティ監査を実行
- **handle_completion_insecurities**: 不適切なパーミッションのディレクトリを検出して警告

## 備考

- zcompdumpファイルは異なるZSHバージョン間で互換性がないため、バージョンごとに別ファイルを使用
- macOSのDHCPによるホスト名変更に対応するため、LocalHostNameを優先使用
- `omz reload`で明示的にキャッシュをクリア可能

---

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

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

### 推奨読解順序

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

補完キャッシュで扱う変数とファイル構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | ZSH_COMPDUMP、zcompdump_revision、zcompdump_fpathの関係 |

**読解のコツ**:
- zcompdumpはZSHの補完キャッシュファイル
- メタデータ（リビジョン、fpath）でキャッシュの有効性を判断

#### Step 2: SHORT_HOST算出を理解する

ホスト名の取得ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | 100-106行目のSHORT_HOST算出 |

**主要処理フロー**:
- **101-103行目**: macOSの場合はscutil --get LocalHostNameを使用
- **105行目**: その他の場合は${HOST/.*/}（最初の.までを取得）

#### Step 3: ZSH_COMPDUMPパス生成を理解する

補完ダンプファイルのパス決定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | 108-111行目のZSH_COMPDUMPパス生成 |

**主要処理フロー**:
- **109-111行目**: ZSH_COMPDUMPが未設定の場合、`${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}`を設定

#### Step 4: メタデータ管理を理解する

zcompdumpのメタデータ検証・更新ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | 113-146行目のメタデータ管理 |

**主要処理フロー**:
- **114行目**: OMZリビジョン取得（git rev-parse HEAD）
- **115行目**: 現在のfpath取得
- **118-122行目**: メタデータ不一致時のzcompdump削除
- **136-145行目**: メタデータの追記

#### Step 5: compinit実行を理解する

補完システム初期化処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | 124-133行目のcompinit実行 |

**主要処理フロー**:
- **124行目**: ZSH_DISABLE_COMPFIXの確認
- **125-129行目**: セキュアモード（compinit -i）+ セキュリティチェック
- **131-132行目**: 非セキュアモード（compinit -u）

#### Step 6: zrecompileを理解する

補完キャッシュのコンパイル処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | oh-my-zsh.sh | `oh-my-zsh.sh` | 148-152行目のzrecompile処理 |

**主要処理フロー**:
- **149行目**: ロックディレクトリ作成で排他制御
- **150行目**: zrecompile -q -p でコンパイル
- **151行目**: 古い.zwcとロックの削除

#### Step 7: セキュリティチェックを理解する

補完ディレクトリのセキュリティ監査を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | compfix.zsh | `lib/compfix.zsh` | handle_completion_insecurities関数 |

**主要処理フロー**:
- **18行目**: compauditで不安全なディレクトリを検出
- **21行目**: 不安全なディレクトリがない場合は早期リターン
- **24-43行目**: 警告メッセージの出力

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

```
oh-my-zsh.sh (初期化時)
    │
    ├─ SHORT_HOST算出
    │      └─ scutil --get LocalHostName (macOS)
    │      └─ ${HOST/.*/} (その他)
    │
    ├─ ZSH_COMPDUMPパス決定
    │
    ├─ メタデータ生成
    │      ├─ git rev-parse HEAD
    │      └─ fpath取得
    │
    ├─ メタデータ検証
    │      └─ grep -q -Fx
    │
    ├─ compinit実行
    │      ├─ compinit -i (セキュアモード)
    │      └─ compinit -u (非セキュアモード)
    │
    ├─ lib/compfix.zsh
    │      └─ handle_completion_insecurities() &|
    │             └─ compaudit
    │
    ├─ メタデータ追記
    │      └─ tee -a
    │
    └─ zrecompile
           └─ mkdir (ロック取得)
           └─ zrecompile -q -p
           └─ rm -rf (ロック解放)
```

### データフロー図

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

$ZSH/.git              ───▶ git rev-parse HEAD ──────────▶ zcompdump_revision
fpath配列              ───▶ 文字列化 ────────────────────▶ zcompdump_fpath

既存zcompdump          ───▶ grep検証
                              │
                              ├─▶ 不一致: rm zcompdump
                              │
                              └─▶ compinit ───────────────▶ 新zcompdump
                                      │
                                      └─▶ メタデータ追記 ──▶ 更新されたzcompdump
                                              │
                                              └─▶ zrecompile ▶ zcompdump.zwc
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| oh-my-zsh.sh | `oh-my-zsh.sh` | ソース | 補完キャッシュ管理のメイン処理 |
| compfix.zsh | `lib/compfix.zsh` | ソース | 補完セキュリティチェック |
| cli.zsh | `lib/cli.zsh` | ソース | omz reload（キャッシュクリア） |
| .zcompdump-* | `~/.zcompdump-*` | キャッシュ | 補完定義キャッシュファイル |
| .zcompdump-*.zwc | `~/.zcompdump-*.zwc` | キャッシュ | コンパイル済み補完キャッシュ |
