# 機能設計書 14-omz theme set

## 概要

本ドキュメントは、Oh My Zshの`omz theme set`コマンドの機能設計について記載する。このコマンドは指定されたテーマを`.zshrc`ファイルに永続的に設定し、シェルをリロードする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Oh My Zshのテーマは`.zshrc`ファイル内の`ZSH_THEME`変数で設定される。手動でファイルを編集することなく、コマンドラインからテーマを永続的に変更できる機能が求められる。本機能は、AWKスクリプトを使用して`.zshrc`を安全に編集し、テーマ設定を変更することで、ユーザーの利便性を向上させる。

**機能の利用シーン**：
- お気に入りのテーマを見つけて永続的に設定したい場合
- テーマを変更して次回以降のシェル起動時にも反映させたい場合
- `.zshrc`を手動編集せずにテーマを変更したい場合

**主要な処理内容**：
1. 引数で指定されたテーマ名の存在を確認する
2. AWKスクリプトを使用して`.zshrc`内の`ZSH_THEME=`行を書き換える
3. `.zshrc`が`ZSH_THEME=`行を持たない場合は先頭に追加する
4. 変更前の`.zshrc`をバックアップする
5. 新しい`.zshrc`の構文チェックを行い、エラーがあればロールバックする
6. 成功した場合はシェルをリロードする

**関連システム・外部連携**：特になし。ローカルファイルシステムのみを操作する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | omz theme set | 主画面 | .zshrcにテーマを設定し、シェルをリロード |

## 機能種別

設定変更・ファイル編集

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| theme | 文字列 | Yes | 設定するテーマ名 | テーマファイルの存在確認 |

### 入力データソース

- `$ZSH_CUSTOM/$theme.zsh-theme`: カスタムテーマファイル（優先度1）
- `$ZSH_CUSTOM/themes/$theme.zsh-theme`: カスタムテーマファイル（優先度2）
- `$ZSH/themes/$theme.zsh-theme`: ビルトインテーマファイル
- `${ZDOTDIR:-$HOME}/.zshrc`: 編集対象の設定ファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | 成功/エラーメッセージを標準エラー出力に出力 |

### 出力先

- `${ZDOTDIR:-$HOME}/.zshrc`: テーマ設定が更新されたファイル
- `${ZDOTDIR:-$HOME}/.zshrc.bck`: 変更前のバックアップファイル
- 標準エラー出力: ログメッセージ

### 副作用

- `.zshrc`ファイルが更新される
- `.zshrc.bck`バックアップファイルが作成される
- 成功時はシェルセッションがリロードされる

## 処理フロー

### 処理シーケンス

```
1. 引数の検証
   └─ テーマ名が指定されているか確認

2. テーマファイルの存在確認
   ├─ $ZSH_CUSTOM/$theme.zsh-themeを確認
   ├─ $ZSH_CUSTOM/themes/$theme.zsh-themeを確認
   └─ $ZSH/themes/$theme.zsh-themeを確認

3. AWKスクリプトによる.zshrc編集
   ├─ ZSH_THEME=行を検出して書き換え
   └─ 該当行がない場合はスクリプトが終了コード1を返す

4. ZSH_THEME行が存在しない場合の処理
   └─ ファイル先頭にZSH_THEME行を追加

5. ファイル操作
   ├─ .zshrc.newを生成
   ├─ 既存.zshrcを.zshrc.bckにバックアップ
   └─ .zshrc.newを.zshrcにリネーム

6. 構文チェック
   ├─ zsh -n で新しい.zshrcを検証
   └─ エラー時は.zshrc.bckからロールバック

7. 成功処理
   ├─ 成功メッセージを出力
   └─ インタラクティブセッションの場合はリロード
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{テーマ名が指定されている?}
    B -->|No| C[使用法を表示して終了]
    B -->|Yes| D{テーマファイルが存在する?}
    D -->|No| E[エラー: テーマが見つからない]
    D -->|Yes| F[AWKスクリプトで.zshrcを編集]
    F --> G{ZSH_THEME=行が見つかった?}
    G -->|Yes| H[.zshrc.newを生成]
    G -->|No| I[ファイル先頭にZSH_THEME行を追加]
    I --> H
    H --> J[.zshrcを.zshrc.bckにバックアップ]
    J --> K[.zshrc.newを.zshrcにリネーム]
    K --> L{zsh -n で構文チェック}
    L -->|エラー| M[.zshrc.bckからロールバック]
    M --> N[エラー終了]
    L -->|OK| O[成功メッセージを出力]
    O --> P{インタラクティブセッション?}
    P -->|Yes| Q[_omz::reloadを呼び出し]
    P -->|No| R[終了]
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | テーマ検索優先順位 | `$ZSH_CUSTOM/$theme.zsh-theme` → `$ZSH_CUSTOM/themes/$theme.zsh-theme` → `$ZSH/themes/$theme.zsh-theme`の順で検索 | 常時 |
| BR-02 | バックアップ作成 | 変更前に必ず`.zshrc.bck`を作成 | 常時 |
| BR-03 | 構文チェック必須 | 変更後の`.zshrc`は必ず`zsh -n`で構文チェック | 常時 |
| BR-04 | ロールバック | 構文エラー時は自動的に元の`.zshrc`を復元 | 構文エラー発生時 |
| BR-05 | コメント付加 | 設定行に`# set by \`omz\``コメントを追加 | 常時 |
| BR-06 | 非インタラクティブ時のリロード抑止 | スクリプト実行時など非インタラクティブセッションではリロードしない | 非インタラクティブ時 |

### 計算ロジック

特になし。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数なしエラー | テーマ名が指定されていない | 使用法を表示して終了（リターンコード1） |
| - | テーマ未検出エラー | 指定されたテーマファイルが見つからない | エラーメッセージを出力して終了 |
| - | ファイル操作エラー | .zshrcの編集に失敗 | エラーメッセージを出力して終了 |
| - | 構文エラー | 編集後の.zshrcに構文エラーがある | バックアップからロールバックして終了 |

### リトライ仕様

リトライは行わない。構文エラー時は自動的にロールバックされる。

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

擬似的なトランザクション処理を実装：
1. 新しいファイル（`.zshrc.new`）を作成
2. 元のファイルをバックアップ
3. 新しいファイルを正式なファイル名にリネーム
4. 構文チェックで問題があればバックアップから復元

## パフォーマンス要件

- 通常の`.zshrc`ファイル（数百行程度）では1秒以内に処理完了すること
- AWKによる行単位処理のため、ファイルサイズに比例した処理時間

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

- `.zshrc`ファイルの書き込み権限が必要
- バックアップファイルにも同様の権限が必要
- テーマ名はAWKスクリプト内でエスケープされずに使用されるため、信頼できる入力のみを受け付けること

## 備考

- `$ZDOTDIR`が設定されている場合は、そのディレクトリ内の`.zshrc`が対象となる
- 実際のパスは`:A`修飾子によりシンボリックリンクが解決される
- `ZSH_THEME=`行が複数ある場合は最初の行のみが置換される

---

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

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

### 推奨読解順序

#### Step 1: 関数の全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli.zsh | `lib/cli.zsh` | `_omz::theme::set`関数の定義位置（796-860行目）を確認 |

**読解のコツ**: AWKスクリプトがzsh文字列内に埋め込まれている。`$1`はAWK内の第1フィールドを指す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cli.zsh | `lib/cli.zsh` | omz関数（3-21行目）からのコマンドディスパッチを確認 |
| 2-2 | cli.zsh | `lib/cli.zsh` | _omz::theme関数（745-764行目）からのサブコマンドディスパッチを確認 |

**主要処理フロー**:
1. **3-21行目**: `omz`関数がコマンドライン引数を解析し、`_omz::$command`を呼び出す
2. **745-764行目**: `_omz::theme`関数が`set`サブコマンドを受け取り、`_omz::theme::set`を呼び出す

#### Step 3: テーマ設定処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cli.zsh | `lib/cli.zsh` | `_omz::theme::set`関数（796-860行目）の実装詳細 |

**主要処理フロー**:
- **797-800行目**: 引数チェックと使用法表示
- **802-808行目**: テーマファイルの存在確認
- **810-825行目**: AWKスクリプトによる`ZSH_THEME=`行の置換
- **827-828行目**: zshrcパスの設定
- **829-839行目**: AWK実行とファイル操作
- **841-846行目**: ファイル操作エラー処理
- **848-853行目**: 構文チェックとロールバック
- **855-859行目**: 成功処理とリロード

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

```
omz (3-21行目)
    │
    └─ _omz::theme (745-764行目)
           │
           └─ _omz::theme::set (796-860行目)
                  │
                  ├─ テーマファイル存在確認
                  │
                  ├─ AWKによる.zshrc編集
                  │
                  ├─ 構文チェック (zsh -n)
                  │
                  └─ _omz::reload (成功時)
```

### データフロー図

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

テーマ名            ───▶ テーマファイル検索
(コマンドライン)           │
                          ▼
.zshrc              ───▶ AWKスクリプト実行          ───▶ .zshrc.new
                          │
                          ▼
                     ファイル操作
                          │
                     .zshrc → .zshrc.bck
                     .zshrc.new → .zshrc
                          │
                          ▼
                     構文チェック (zsh -n)
                          │
                          ├─ OK → リロード
                          └─ NG → ロールバック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cli.zsh | `lib/cli.zsh` | ソース | omzコマンドのCLI実装。_omz::theme::set関数を含む |
| .zshrc | `${ZDOTDIR:-$HOME}/.zshrc` | 設定 | 編集対象のzsh設定ファイル |
| .zshrc.bck | `${ZDOTDIR:-$HOME}/.zshrc.bck` | バックアップ | 変更前の.zshrcのバックアップ |
